LIDOR SYSTEMS

Advanced User Interface Controls and Components

Custom Sorting in Angular Grid

Created: 16 August 2017

IntegralUI Grid component for Angular comes with built-in support for sorting operations. You can either use the built-in sort functionality or create your own custom sorting. This example shows how to create custom operation to sort rows by Date, when column is clicked.

Grid component is part of IntegralUI Web
a suite of UI Components for development of web apps

If you have any questions, don't hesitate to contact us at support@lidorsystems.com

When you click on column headers, all rows are sorted in ascending or descending order. The sort order is represented by an arrow, which appears on right side of column header. In this demo, only the Date column has custom sorting applied; all other columns use a built-in sort operation.

Built-in Sorting

By default, sorting is disabled. To sort rows in Angular Grid component, you need to simply call the sort method and specify the column by which rows will be sorted and the sort order (ascending or descending).

Whenever a sort order is specified for a specific column, an arrow will appear on right side of column header representing whether rows are sorted in ascending or descending order.

When grid cells have simple data (text or numeric values), built-in sorting should be enough. You only need to specify the text or value field for grid cells, and the sorting will be applied based on those values.

Note The value field has higher priority than the text field, and it is first checked during sort operation.

Custom Sort Operation

In other cases, like when you need to show Date values or some other kind of custom objects in grid cells, you may need to create a custom sort operation. For this purpose, the sort method also accepts a comparer function as third argument. This function is used instead of built-in sort operation.

To sort Date/Time values, at first you need to create a comparer function. This function has two arguments, two values of the same type used during comparing process. In this case, because we are sorting rows, both arguments are row objects.

To get a value of the grid cell, you can set the sortColumn variable that will hold a reference to column by which rows are sorted. Then use this variable to get the cell value from rows that are shown in sorting column. To find which cell belongs to which column, the best is to use the cell cid field and column id field, like it is shown below:

// Grid  settings
@ViewChild('grid') grid: IntegralUIGrid;

public columns: Array;
public rows: Array;

private sorting: IntegralUISortOrder = IntegralUISortOrder.None;
private sortColumn: any = null;
private prevColumn: any = null;


getCellValue(row: any){
    let cellValue: any = null;

    if (this.sortColumn && row.cells){
        for (let j = 0; j < row.cells.length; j++){
            if (row.cells[j].cid == this.sortColumn.id){
                cellValue = row.cells[j].value;
                break;
            }
        }
    }

    return cellValue;
}
                            

At first Date values are converted to a numeric value, and then compared against each other to determine their position. For conversion, the standard valueOf method is used, which is already part of the Date object.

comparer = (firstRow: any, secondRow: any) => {
    let x: any = this.getCellValue(firstRow);
    let y: any = this.getCellValue(secondRow);

    x = x ? x.valueOf() : null;
    y = y ? y.valueOf() : null;

    switch (this.sorting){
        case IntegralUISortOrder.Ascending:
            if (x < y)
                return -1;
            else if (x > y)
                return 1;
            break;

        case IntegralUISortOrder.Descending:
            if (x > y)
                return -1;
            else if (x < y)
                return 1;
            break;

        default:
            return 0;
    }
}
                            

Depending on sort order applied to the column, different conditions are checked. If there is no Date value specified for a grid cell, it is presumed as 0. Meaning it will appear as first or last in the order.

At last, you need to add a code to an event handler for columnClick event that will execute whenever a column header is clicked. Depending on column type, the sort method is called using built-in sorting or the comparer function we have created above.

onColumnClick(e: any){
    if (e.column){
        if (e.column != this.prevColumn){
            if (this.sorting == IntegralUISortOrder.None)
                this.sorting = IntegralUISortOrder.Ascending;
        }
        else {
            if (this.sorting == IntegralUISortOrder.Ascending)
                this.sorting = IntegralUISortOrder.Descending;
            else
                this.sorting = IntegralUISortOrder.Ascending;
        }

        this.sortColumn = e.column;
        this.prevColumn = e.column;

        if (e.column.id == 4)
            this.grid.sort(e.column, this.sorting, this.comparer);
        else
            this.grid.sort(e.column, this.sorting);
    }
}  
                          
<iui-grid [columns]="columns" [rows]="rows" [showFooter]="false" (columnClick)="onColumnClick($event)" #grid>
    <ng-template let-column [iuiTemplate]="{ type: 'header' }">
        {{column.headerText}}
    </ng-template>
    <ng-template let-cell [iuiTemplate]="{ type: 'cell' }">
        {{cell.text}}
    </ng-template>
</iui-grid>
                          

Conclusion

Sorting in Grid component for Angular is straightforward. In most cases, when grid cells have text or numeric values, you can use already built-in sort operations. Whenever rows are sorted, an arrow will appear in column header showing the current sort order.

Custom sorting is also supported, by allowing creation of comparer function where you can add any custom conditions to sort complex objects.

The Grid component is part of IntegralUI Web.

Newsletter


Sign-up to our newsletter and you will receive news on upcoming events, latest articles, samples and special offers.
Name: Email: *
*By checking this box, I agree to receive a newsletter from Lidor Systems in accordance with the Privacy Policy. I understand that I can unsubscribe from these communications at any time by clicking on the unsubscribe link in all emails.