DHTMLX Documentation

In-grid sorting


Basics of sorting


The grid allows to sort data rows on the client side.
By default sorting is triggered by a single click on any header row (if a grid has multiple rows - a click on any of them will trigger sorting).

The sorting can be forced by js code like this:
    grid.sortRows(index)
Where "index" is the index of the column, by which the grid needs to be sorted.

The command can be executed with additional parameters to specify more details:
    grid.sortRows(0,"str","asc");    // sorting by the first column, as a string in the ascendant order
    grid.sortRows(1,"int","des");    // sorting by the first column, as a string in the descendant order

Sorting types


The way of sorting depends on column sorting types. There are 4 predefined sorting types:
    str - the data will be sorted as strings (case sensitive);
    int - the data will be sorted as numbers (numbers must be in js recognizable format, or you can use number formating feature of the grid);
    date - the data will be sorted as a date (dates must be in js recognizable format, or you can use use date formating feature of the grid);
    na - sorting is not available for a column (a column will not react on a header click and sortRows calls).

The sorting types are assigned to columns using:
    grid.setColSorting(list_of_values);
    grid.setColSorting("int,str,na,str"); // define sorting state for columns 0-3

Custom sorting

The 4 existing sorting types are too small to cover all use-cases, so the grid allows to create custom sorting types.
Basically you need to define a function which will receive two values and the required order of sorting.
The return value will be as follows:
    valueA > valueB => return 1
    valueA < valueB => return -1

The snippets below show some common use-cases.

Case insensitive sorting

function str_custom=function(a,b,order){    //the name of the function must be > than 5 chars
    if (order=="asc")
        return (a.toLoweCase()>b.toLoweCase()?1:-1);
    else
        return (a.toLoweCase()<b.toLoweCase()?-1:1);
}
grid.setColSorting("int,str_custom,na,str"); // define sorting state for columns 0-3

The code above is pretty simple, but can be written in a simpler (or more difficult, it depends on your definition of simplicity) way like this:

function str_custom=function(a,b,order){  
        return (a.toLoweCase()>b.toLoweCase()?1:-1)*(order=="asc"?1:-1);
}

Custom time sorting

For data such as    14:56

function time_custom=function(a,b,order){  
        a=a.split(":")
        b=a.split(":")
        if (a[0]==b[0])
             return (a[1]>b[1]?1:-1)*(order=="asc"?1:-1);
        else
             return (a[0]>b[0]?1:-1)*(order=="asc"?1:-1);
}
grid.setColSorting("int,time_custom,na,str");

Custom date sorting

For data such as    dd/mm/yyyy
(you don't need it, if you are using setDateFormat functionality)

function date_custom=function(a,b,order){  
        a=a.split("/")
        b=a.split("/")
        if (a[2]==b[2]){
            if (a[1]==b[1])
                return (a[0]>b[0]?1:-1)*(order=="asc"?1:-1);
            else
                return (a[1]>b[1]?1:-1)*(order=="asc"?1:-1);
        } else
             return (a[2]>b[2]?1:-1)*(order=="asc"?1:-1);
}
grid.setColSorting("int,date_custom,na,str");

Stable sorting

The default sorting routine used by the grid is a quicksort algorithm, which is unstable (it means that rows with the same value may change their position after sorting).
The Grid has a way to switch to the stable sorting algorithm, it can be done with the help of:
    mygrid.enableStableSorting(true);
Basically stable sorting is a little slower than the default one, so enable this mode only if it is really necessary.

Sorting by multiple columns

The default sorting routine is designed to sort the grid by values of a single column, but in some use-cases it is necessary to sort the grid by values of multiple columns.
While native API doesn't have legal ways to achieve such feature - there are 3 possible workarounds:
        In case of stable sorting, the rows with the same values will not change their position, it can be exploited to organize sorting by multiple columns:
        mygrid.enableStableSorting(true);
        mygrid.sortRows(1,"str","asc");    //sort by the sibling column
        mygrid.sortRows(0,"str","des");    //sort by the main column
        As a result the grid will be sorted by a column of lesser importance and after that by a column of higher importance. In combination with stable sorting it will give the same result as sorting by two columns.

        You can use complex soring function similar to the following one:
function sort_by_two(a,b,order,aid,bid){
      if (a==b){
         var a2=mygrid.cells(aid,1).getValue();
         var b2=mygrid.cells(bid,1).getValue();
         if(order=="asc")
            return a2>b2?1:-1;
         else
            return a2<b2?1:-1;
      }

      if(order=="asc")
         return a>b?1:-1;
      else
         return a<b?1:-1;
   }
        Two values marked in bold - index of the second column, which will be used in sorting as an addition to the main column.


Predefined sorting order

In some scenarios it is pretty complex to get sortable values on the client side. In such case it is possible to create a separate column with plain values which can be used for sorting. Such column can be set to invisible mode by
    grid.setColumnHidden(...
And later, any search action is redirected to it in the following way:
    grid.attachEvent("onBeforeSorting",function(ind,type,direction){
        if (ind == some1){        // if sorting for problematic column
            this.sortRows(some2,type,direction);         //sort grid by the column with prepared values
            this.setSortImgState(true,ind,direction);    //set a correct sorting image
            return false; //block default sorting
        }
        return true;    
    });

Server side sorting

If none of the above mentioned methods works for your needs, you can implement server side sorting:
    grid.attachEvent("onBeforeSorting",function(ind,type,direction){
        this.clearAll();    // clear grid
        this.loadXML("some.url?dir="+dir+"&ind="+ind); //load a new dataset from the server, with necessary order
        this.setSortImgState(true,ind,direction);    //set a correct sorting image
        return false;    
    });



Some special cases

Sorting by combo label

The sorting uses the cell value for sorting. It works fine in most cases, but if you are using combo cells you may need to sort by cell labels (which may differ from cell values).
Such use-case can be implemented with the usage of custom sorting:
   function custom_1(a,b,ord,a_id,b_id){
      a=mygrid2.cells(a_id,5).getText();
      b=mygrid2.cells(b_id,5).getText();
      return ord=="asc"?(a>b?1:-1):(a>b?-1:1);
   }
    Where 5  - the index of the column for which sorting will be applied.

Partial sorting


Another rare situation that may still occur is the following: the grid contains a few rows which must have fixed position, while other rows must be sorted.
And again the grid does not provide any native solution. But using custom sorting use-case can be implemented in this case:

   function custom (a,b,ord,aid,bid) {
      var aid=aid.split("_")
      var bid=bid.split("_")
      if (aid[0]=="top") return 1;
      if (bid[0]=="top") return -1;

      return ((a>b)?1:-1)*(ord=="asc"?1:-1);
   }
The snippet above adds logic to custom sorting, which will move rows with ID="top_*" to the top of the grid, while sorting other datasets in the required order.