Authors:Evan Huang
Project owner:Evan Huang


This feature enhances the single sorting feature of base DataGrid. Nested sorting allows users to sort on one or more columns concurrently and also control the sort direction and order. Finally, columns can be removed from the sort without disturbing the rest of the sort.


    /*set up data store*/
    var data = {
      identifier: 'id',
      items: []
    var data_list = [
      { col1: "normal", col2: false, col3: 'But are not followed by two hexadecimal', col4: 29.91},
      { col1: "important", col2: false, col3: 'Because a % sign always indicates', col4: 9.33},
      { col1: "important", col2: false, col3: 'Signs can be selectively', col4: 19.34}
    var rows = 60;
    for(var i=0, l=data_list.length; i<rows; i++){
      data.items.push(dojo.mixin({ id: i+1 }, data_list[i%l]));
    var store = new{data: data});

    /*set up layout*/
    var layout = [[
      {name: 'Column 1', field: 'id'},
      {name: 'Column 2', field: 'col2'},
      {name: 'Column 3', field: 'col3', width: "230px"},
      {name: 'Column 4', field: 'col4'}

    /* create a new grid: */
    var grid = new dojox.grid.EnhancedGrid({
        id: 'grid',
        store: store,
        structure: layout,
        rowSelector: '20px',
        plugins : {nestedSorting: true}},

    /* append the new grid to the div */

    /* Call startup() to render the grid */
<div id="gridDiv"></div>
@import "{{baseUrl}}dojo/resources/dojo.css";
@import "{{baseUrl}}dijit/themes/claro/claro.css";
@import "{{baseUrl}}dojox/grid/enhanced/resources/claro/EnhancedGrid.css";
@import "{{baseUrl}}dojox/grid/enhanced/resources/EnhancedGrid_rtl.css";

/*Grid need a explicit width/height by default*/
#grid {
    width: 43em;
    height: 20em;


Using the nested sorting feature is pretty simple as shown below:

  • Declare nested sorting feature plugin
  • Use nested sorting feature

with HTML markup

<div id="grid" store="store1" data-dojo-type="dojox.grid.EnhancedGrid" data-dojo-props="plugins:{nestedSorting: true}" >

with JavaScript way

var grid = new dojox.grid.EnhancedGrid({id: "grid", store: "store1", plugins: {nestedSorting: true}, ...}, dojo.byId("gridDiv"));
  • Set default sorting order with sortFields
var grid = new dojox.grid.EnhancedGrid({
    id: "grid",
    // default sorting order
    sortFields: [{attribute: 'col4', descending: false},{attribute: 'col7', descending: true}],
    plugins: {nestedSorting: true}
}, div);
  • Set new sorting order dynamically
var newSortFields = [{attribute: 'col3', descending: true},{attribute: 'col1', descending: false}];
  • Prevent column(s) from being sorted by canSort()
var grid = new dojox.grid.EnhancedGrid({
    id: "grid",
    // prevent some columns from being sorted
    // column index 0 and column with field 'col6' are disabled for being sorted
    canSort: function(colIndex, field){
        return colIndex != 0 && field != 'col6';
    plugins: {nestedSorting: true}
}, div);

When nested sorting is enabled, you can also use comparatorMap for custom sorting; see for more details.


The following are typical scenarios using nested sorts:

  • When there is no sorting established, a unary (single) sort caret is shown when the mouse hovers over a column. The upward direction of the caret reflects that this will result in an ascending sort.
  • Once the sort choice is selected for the ‘Genre’ column, the grid rows will be sorted ascending based on by the values in Genre. Note that the keyboard focus moves to the sort choice in response to the mouse click. The graphical label of the sort choice is a downward caret since the function would be a descending sort.
  • Then the nested sort tip is shown when the mouse hovers over a other column headers.
  • Clicking region “A” in the figure below will execute a nested sort, and the rows will be sorted by Artist in this example within Genre.
  • Clicking region “B” will reset the sort, and the rows will be sorted by Artist alone.
  • Once a column is sorted ascending, the sort choice changes to a sort descending choice.
  • Once a column is sorted descending, the sort choice changes to a ‘remove sort’ function (see the figure below). When a column is removed from the sort, other columns in the sort will be adjusted to reflect the new sort order. For example, Year would become the second column in the sort if it had previously been the third.

To summarize, the sort choice cycles among sort-ascending, sort-descending, and remove sort functions.

There is no limit to the number of columns that may be in the sort.


Keyboard Support

Key Action
LEFT/RIGHT arrow keys Moves the keyboard focus among column headers and regions within a column header
SPACE key Chooses the sorting choice with the keyboard focus
  • The above keys are only effective when keyboard focus is within the column headers.

Screen Readers

ARIA attributes “aria-label” and “aria-sort” are used for screen readers.

Region ARIA Attribute ARIA Attribute Value
Select region aria-label Column name
Unary sort choice aria-sort Sorting state, e.g. “descending”
  • Normal sate - “Column 2 Genre single sort”
  • Hovered - “Column 2 Genre - Press space to choose descending nested sort”
Nested sort choice aria-sort Sorting state, e.g. “descending”
  • Normal sate - “Column 2 Genre nested sort sort position 1”
  • Hovered - “Column 2 Genre - Press space to choose descending nested sort”

Note: In Firefox v.3.5, JAWS10 doesn’t announce all the above ARIA attributes appropriately. This will be addressed when newer JAWS and Firefox versions are released.

See Also

Error in the documentation? Can’t find what you are looking for? Let us know!