Search code examples
javascriptsortingknockout.jstypescriptkogrid

How to implement custom sort for koGrid?


Data:

16.00 hours 19.99 hours 210.46 hours 262.54 hours 303.19 hours 55.95 hours 60.07 hours 64.07 hours 7.95 hours

What I want:

I need to allow sorting for this king of data in koGrid (default feature by clicking grid header, asc or desc sort).

Problem:

The data is string so you might guess how it sorts out - by char codes. What are my options? I found that a column can have sortFn assigned, something like this I guess?

enter image description here

Code:

this.gridOptions = {
            canSelectRows: false,
            showColumnMenu: false,
            showFilter: false,
            columnDefs: [

                { field: 'localizedName', displayName: 'Name' },
                {
                    field: 'localizedDuration', displayName: 'Duration',
                    sortFn: function (itemA: string, itemB: string) {
                        var numA = parseFloat(itemA);
                        var numB = parseFloat(itemB);

                        if (!numA && !numB)
                            return 0;
                        else if (!itemA && (itemA === undefined || itemA === null))
                            return 1;
                        else if (!itemB && (itemB === undefined || itemB === null))
                            return -1;

                        if (numA > numB)
                            return -1;
                        else if (numA < numB)
                            return 1;

                        return 0;
                    }
                },
            ],
            data: this.dataRows
        };

Fiddle: JSFiddle


Solution

  • Just try to modify your code like this

    View :

    <div data-bind="koGrid: gridOptions"></div>
    

    viewModel:

    vm = function () {
        var self = this;
        self.myData = ko.observable([{
            hours: '113.02 hours'
        }, {
            hours: '13.01 hours'
        }, {
            hours: '303.01 hours'
        }, {
            hours: '33.01 hours'
        }]);
    
        self.gridOptions = {
            data: self.myData,
            columnDefs: [{
                field: 'hours',
                displayName: 'hours',
                sortFn(a, b) {
                    if (!(a && b)) {
                        return -1;
                    }
                    var a1 = parseFloat(a.split(' ')[0]);
                    var b1 = parseFloat(b.split(' ')[0]);
                    if (a1 > b1) return 1;
                    if (a1 < b1) return -1;
                    if (a1 = b1) return 0;
                }
            }]
        };
    };
    ko.applyBindings(new vm);
    

    Working fiddle here

    Reference documentation available here