datatable-sort-debug.js revision 186b3579b2d4dfe441df1f5b7a4a7ddc98d6e524
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke SmithAdds support for sorting the table data by API methods `table.sort(...)` or
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith`table.toggleSort(...)` or by clicking on column headers in the rendered UI.
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke SmithSorting by the API is enabled automatically when this module is `use()`d. To
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smithenable UI triggered sorting, set the DataTable's `sortable` attribute to
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smithvar table = new Y.DataTable({
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith columns: [ 'id', 'username', 'name', 'birthdate' ],
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith data: [ ... ],
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith sortable: true
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smithtable.render('#table');
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith</code></pre>
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke SmithSetting `sortable` to `true` will enable UI sorting for all columns. To enable
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke SmithUI sorting for certain columns only, set `sortable` to an array of column keys,
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smithor just add `sortable: true` to the respective column configuration objects.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke SmithThis uses the default setting of `sortable: auto` for the DataTable instance.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smithvar table = new Y.DataTable({
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith { key: 'username', sortable: true },
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith { key: 'name', sortable: true },
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith { key: 'birthdate', sortable: true }
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith data: [ ... ]
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith // sortable: 'auto' is the default
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smithvar table = new Y.DataTable({
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith columns: [ 'id', 'username', 'name', 'birthdate' ],
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith data: [ ... ],
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith sortable: [ 'username', 'name', 'birthdate' ]
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith</code></pre>
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke SmithTo disable UI sorting for all columns, set `sortable` to `false`. This still
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smithpermits sorting via the API methods.
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke SmithAs new records are inserted into the table's `data` ModelList, they will be inserted at the correct index to preserve the sort order.
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke SmithThe current sort order is stored in the `sortBy` attribute. Assigning this value at instantiation will automatically sort your data.
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke SmithSorting is done by a simple value comparison using < and > on the field
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smithvalue. If you need custom sorting, add a sort function in the column's
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith`sortFn` property. Columns whose content is generated by formatters, but don't
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smithrelate to a single `key`, require a `sortFn` to be sortable.
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smithfunction nameSort(a, b) {
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith var aa = a.get('lastName'),
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith bb = a.get('lastName');
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith if (aa === bb) {
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith aa = a.get('firstName');
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith bb = b.get('firstName');
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith return (aa > bb) ? 1 : (aa < bb) ? -1 : 0;
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smithvar table = new Y.DataTable({
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith columns: [ 'id', 'username', { key: name, sortFn: nameSort }, 'birthdate' ],
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith data: [ ... ],
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith sortable: [ 'username', 'name', 'birthdate' ]
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith</code></pre>
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke SmithSee the user guide for more details.
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith@module datatable-sort
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith@class DataTable.Sortable
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith@for DataTable
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith // Which columns in the UI should suggest and respond to sorting interaction
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith // pass an empty array if no UI columns should show sortable, but you want the
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith // table.sort(...) API
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith Controls which column headers can trigger sorting by user clicks.
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith Acceptable values are:
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith * "auto" - (default) looks for `sortable: true` in the column configurations
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith * `true` - all columns are enabled
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith * `false - no UI sortable is enabled
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith * {String[]} - array of key names to give sortable headers
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith @attribute sortable
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @type {String|String[]|Boolean}
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @default "auto"
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith The current sort configuration to maintain in the data.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Accepts column `key` strings or objects with a single property, the column
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith `key`, with a value of 1, -1, "asc", or "desc". E.g. `{ username: 'asc'
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith }`. String values are assumed to be ascending.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Example values would be:
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith * `"username"` - sort by the data's `username` field or the `key`
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith associated to a column with that `name`.
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith * `{ username: "desc" }` - sort by `username` in descending order.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Alternately, use values "asc", 1 (same as "asc"), or -1 (same as "desc").
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith * `["lastName", "firstName"]` - ascending sort by `lastName`, but for
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith records with the same `lastName`, ascending subsort by `firstName`.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Array can have as many items as you want.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith * `[{ lastName: -1 }, "firstName"]` - descending sort by `lastName`,
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith ascending subsort by `firstName`. Mixed types are ok.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @attribute sortBy
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @type {String|String[]|Object|Object[]}
186b3579b2d4dfe441df1f5b7a4a7ddc98d6e524Luke Smith Strings containing language for sorting tooltips.
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith @attribute strings
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @type {Object}
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @default (strings for current lang configured in the YUI instance config)
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith valueFn: function () {
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Sort the data in the `data` ModelList and refresh the table with the new
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Acceptable values for `fields` are `key` strings or objects with a single
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith property, the column `key`, with a value of 1, -1, "asc", or "desc". E.g.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith `{ username: 'asc' }`. String values are assumed to be ascending.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Example values would be:
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith * `"username"` - sort by the data's `username` field or the `key`
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith associated to a column with that `name`.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith * `{ username: "desc" }` - sort by `username` in descending order.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Alternately, use values "asc", 1 (same as "asc"), or -1 (same as "desc").
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith * `["lastName", "firstName"]` - ascending sort by `lastName`, but for
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith records with the same `lastName`, ascending subsort by `firstName`.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Array can have as many items as you want.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith * `[{ lastName: -1 }, "firstName"]` - descending sort by `lastName`,
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith ascending subsort by `firstName`. Mixed types are ok.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @method sort
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @param {String|String[]|Object|Object[]} fields The field(s) to sort by
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @param {Object} [payload] Extra `sort` event payload you want to send along
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @return {DataTable}
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith return this.fire('sort', Y.merge((payload || {}), {
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Reverse the current sort direction of one or more fields currently being
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Pass the `key` of the column or columns you want the sort order reversed
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @method toggleSort
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @param {String|String[]} fields The field(s) to reverse sort order for
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @param {Object} [payload] Extra `sort` event payload you want to send along
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @return {DataTable}
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith // To avoid updating column configs or sortBy directly
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith for (i = 0, len = current.length; i < len; ++i) {
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith for (i = 0, len = columns.length; i < len; ++i) {
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith return this.fire('sort', Y.merge((payload || {}), {
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith //--------------------------------------------------------------------------
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith // Protected properties and methods
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith //--------------------------------------------------------------------------
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Applies the sorting logic to the new ModelList if the `newVal` is a new
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @method _afterDataChange
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @param {EventFacade} e the `dataChange` event
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith _afterDataChange: function (e) {
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith // object values always trigger a change event, but we only want to
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith // call _initSortFn if the value passed to the `data` attribute was a
83abb4e792c64ccc94916233f9dedbd9fa638d50Luke Smith // new ModelList, not a set of new data as an array, or even the same
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith // ModelList.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith if (e.prevVal !== e.newVal || e.newVal.hasOwnProperty('_compare')) {
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Sorts the `data` ModelList based on the new `sortBy` configuration.
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @method _afterSortByChange
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith @param {EventFacade} e The `sortByChange` event
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith _afterSortByChange: function (e) {
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith // Can't use a setter because it's a chicken and egg problem. The
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith // columns need to be set up to translate, but columns are initialized
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith // from Core's initializer. So construction-time assignment would
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith // Don't sort unless sortBy has been set
db7877b089ad41f8aebc49c0810c81adc5c44cacLuke Smith Subscribes to state changes that warrant updating the UI, and adds the
_bindSortUI: function () {
this._uiSetSortable);
if (this._theadNode) {
_defSortFn: function (e) {
destructor: function () {
if (this._sortHandle) {
// TODO: table.get('sortBy.asObject')? table.get('sortBy.json')?
state = [];
return val;
initializer: function () {
this._parseSortable();
this._setSortBy();
this._initSortFn();
this.after({
_initSortFn: function () {
var self = this;
return cmp;
_onUITriggerSort: function (e) {
config = {},
e.preventDefault();
if (id) {
if (column) {
originEvent: e,
_parseSortable: function () {
columns = [],
if (col) {
} else if (sortable) {
_renderSortable: function () {
this._uiSetSortable();
this._bindSortUI();
_setSortBy: function () {
this._sortBy = [];
if (name) {
if (column) {
return item;
_uiSetSortable: function () {
if (liner) {
if (node) {
return val === null ||