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:
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”).
The way of sorting depends on column sorting types. There are 4 predefined sorting types:
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
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:
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.
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); }
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");
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");
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.
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:
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.
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.
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:
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+"&ind="+ind); // load a new dataset from the server, with necessary order this.setSortImgState(true,ind,direction); //set a correct sorting image return false; });
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.
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.