| 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:

- Use 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:

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

- Use complex custom sorting function.

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.

- Use predefined sorting - see the paragraph below.

### 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.
© DHTMLX, 2008