DHTMLX Docs & Samples Explorer

Index
dhtmlxgrid

## In-Grid Sorting

### Forcing 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 the grid has multiple rows, a click on any of them will trigger sorting. Sorting can be forced by JS code like this:

            grid.sortRows(col, type, order);

The parameters here are:

- col - index of the column by which the grid should be sorted;
- type - sorting type (str,int,date), optional, by default sorting type is taken from column setting;
- order - sorting order (asc,des), optional, by default sorting order is based on the previous sorting operation.

### Getting Sorting State

The following method is responsible for getting sorting state:

            grid.getSortingState();

The method returns the array the first element of which is the index of the sorter column, and the second one is direction of sorting (“asc” or “des”).

### Sorting Types

The way of sorting depends on column sorting types. There are 4 predefined sorting types:

- str - data will be sorted as strings (case sensitive);
- int - data will be sorted as numbers (numbers must be in JS recognizable format, or the user can apply number formating feature of the grid);
- date - data will be sorted as a date (dates must be in JS recognizable format, or the user can apply 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).

Sorting types are assigned to columns in the following way:

            //grid.setColSorting(list_of_values);
            grid.setColSorting("int,str,na,str"); // define sorting state for columns 0-3

### Custom Sorting

It should be noted that 4 existing sorting types are not enough to cover all use-cases, so the grid allows to create custom sorting types. Basically the user should define a function that 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 following method should be used to setting custom sorting:

              grid.setCustomSorting(func, col);

The parameters are as follows:

- func - function to use for comparison;
- col - index of the column to apply custom sorting to.

Also, if unknown type was used as parameter of setColSorting - grid will try to locate the function with the same name and use it as sorting function. The snippets below show some common use-cases.

### Case Insensitive Sorting

        function str_custom(a,b,order){    // the name of the function must be > than 5 chars
            if (order=="asc")
                return (a.toLowerCase()>b.toLowerCase()?1:-1);
            else
                return (a.toLowerCase()>b.toLowerCase()?-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 way (it depends on user's definition of simplicity) like this:

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

### Custom Time Sorting

This type of custom sorting can be applied for such data as 14:56:

            function time_custom(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

One more type of custom sorting can be for such data as dd/mm/yyyy (the user doesn't need it, if he is using setDateFormat() functionality):

            function date_custom(a,b,order){
                a=a.split("/")
                b=b.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

Default sorting routine used by the grid is a quick sort algorithm that is unstable (it means that rows with the same value may change their position after sorting). There is a way to switch to the stable sorting algorithm in the grid. This can be done with the help of:

            grid.enableStableSorting(true);

Basically, stable sorting is a little slower than the default one, so the user should bear in mind that this mode should be enabled 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:

- Using stable sorting - 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:

            grid.enableStableSorting(true);
            grid.sortRows(1,"str","asc");    // sort by the sibling column
            grid.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.

- Using complex function - complex soring function similar to the following one can be used:

            function sort_by_two(a,b,order,aid,bid){
              if (a==b){
                 var a2=grid.cells(aid,1).getValue();
                 var b2=grid.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.

- Using predefined sorting .

### Predefined Sorting

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 that can be used for sorting. Such column can be set to invisible mode by the following method:

            grid.setColumnHidden(some2);

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 a 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;
            });

Method setSortImgState() should be used to set position and visibility of a sort arrow, this method takes the following parameters:

- state(true|false) - show|hide an image;
- ind - index of the field;
- order(asc|desc) - type of image;
- row - one based index of header row (used in multi-row headers, top row by default).

### Server Side Sorting

Starting with 2.1 - this task can be automated with help of dhtmlxconnector

If none of the above mentioned methods works for user needs, the user can implement server side sorting:

            grid.attachEvent("onBeforeSorting",function(ind,type,direction){
                    this.clearAll();                                            // clear grid
                    this.loadXML("some.url?dir="+dir+"&amp;ind="+ind); // load a new dataset from the server, with necessary order
                    this.setSortImgState(true,ind,direction);        //set a correct sorting image
                    return false;
                });

### 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.