Custom Sorting in Angulargrid - sort case insensitve
Asked Answered
I

3

6

I am using ag-grid for generating some tables. So far it has been great. But I am experiencing some difficulty in sorting because my table has some data which are in lowercase and I want my sorting function to ignore the case and sort them just has case sensitive.

The two features that can do this job are cellRenderer and sort function.

cellRenderer function:

cellRenderer: function(params) {
    if (params.value=='Police') {
        return 'POLICE';
    } else {
        return params.value.toUpperCase();
    }
}

sorting function:

$scope.sortByAthleteAsc = function() {
    var sort = [
        {field: 'athlete', sort: 'asc'}
    ];
    $scope.gridOptions.api.setSortModel(sort);
};

These are the two examples provided. How can I connect these two functions to produce my table case insensitive sorting?

Infantry answered 23/8, 2015 at 16:57 Comment(0)
E
9

put a comparator onto the colDef. like the following:

colDef.comparator = function(valueA, valueB, nodeA, nodeB) {
    // here valueA and valueB are the items to be compared
    return valueA.toLowerCase().localeCompare(valueB.toLowerCase());
}

you also are provided the row nodes, where you can access the full row data, not just the value specific to the col.

Earthbound answered 2/9, 2015 at 20:42 Comment(2)
If you want the sort enabled by default add sort: 'desc' or sort: 'asc' in addition to the comparator propertyOrest
@Niall Crosby : can you please provide a punker to demonstrate your answer it will help a lot.Impressionism
I
4

This issue can be solved by

   GridOptions.accentedSort = true;
Intelligible answered 13/2, 2019 at 15:28 Comment(0)
S
3

cellRenderer doesn't actually have anything to do with sorting; as Niall points out, what you need is to modify the column definition to use a custom sorting function. From the example code, let's say you're working with the first example, so your columnDef for athlete looks like this:

var columnDefs = [
    {headerName: "Athlete", field: "athlete", width: 150, sort: 'desc'},
    ...
];

You need to add a comparator to that columnDef:

    {headerName: "Athlete", field: "athlete", width: 150, sort: 'desc', 
        comparator: function(valueA, valueB, nodeA, nodeB, isInverted)
        {return caseInsensitiveSort(valueA, valueB, nodeA, nodeB, isInverted);}
    }

and then add your function for sorting below.

function caseInsensitiveSort(valueA, valueB, nodeA, nodeB, isInverted) {
    return valueA.toLowerCase().localeCompare(valueB.toLowerCase());
}

Note that you pass nodes and isInverted, even though you don't have to use them, because that's the signature that ag-grid expects.

A case where you would use the isInverted flag is if you need to handle certain values like blanks or nulls separately. Here's a more detailed function that sorts those values to the bottom, regardless of direction:

function caseInsensitiveSort(valueA, valueB, nodeA, nodeB, isInverted) {
    if( valueA === "" || valueA === null ) {
        if( valueB === "" || valueB === null ) {
            return 0;   // a and b are both blank; 0 means identical
        } else {
            return (isInverted ? -1 : 1);  // a is null, b is not; return 1 for normal sort or -1 for inverted
        }
    }
    if( valueB === "" || valueB === null ) {
        return (isInverted ? 1 : -1);   // b is null, a is not; return -1 for normal or 1 for inverted to get the opposite result as above
    }
    return valueA.toLowerCase().localeCompare(valueB.toLowerCase());
};

You could also set that comparator as part of a column type and then apply the column type to the columnDef; this way, you can easily use the same sort function across multiple columns.

var columnDefs = [
    {headerName: "Athlete", field: "athlete", width: 150, sort: 'desc', type: 'text'},
    ...
];

var gridOptions = {
    columnDefs: columnDefs,
    ... // whatever else you set
    columnTypes: {
        "text": {comparator: function(valueA, valueB, nodeA, nodeB, isInverted) 
            {return caseInsensitiveSort(valueA, valueB, nodeA, nodeB, isInverted);}
    }
};

I have a significantly more complicated example that I've just used on my current project at work; as time permits, I'll narrow it down a bit for a plunkr so you can see how the whole thing works. The ag-grid documentation is pretty useful once you know what you're doing, but the information it has is frequently spread out among several pages, and there aren't many examples that show you exactly what you need to know.

Sillabub answered 28/8, 2017 at 16:55 Comment(3)
I was struggling with implementing such custom sorting and your caseInsensitiveSort is exactly what I needed! Thank you so much! You've saved me many more hours of frustration. Thank you!Abbottson
@Dave DuPlantis How would you make all the nulls last then first depending on the direction of sort? Putting them always lasts seems misleading if you never transverse to the last page in a pagination case.Susiesuslik
I went with this so that blanks aka nulls get directionally sorted:function caseInsensitiveSort(a, b) { if (a === b) { return 0; } else if (a === 'null' || a === null || a === '' || a === undefined) { return -1; } else if (b === 'null' || b === null || b === '' || b === undefined) { return 1; } else { return a.localeCompare(b); } }Susiesuslik

© 2022 - 2024 — McMap. All rights reserved.