Sort on underlying data in ng-grid
Asked Answered
R

2

6

I wish to display a formatted value in a ng-grid cell, but sort on a related numeric value not displayed.

var myData1 = [{
 name: "Moroni",
  age: 50,
  ageWord: "Fifty"
}

From the above example I would display the ageWord column, but wish to sort on the age column.

The docs for sorting an ng-grid directive indicate I can provide a custom function to sort underlying data:

sortFn

Sets the sort function for the column. Useful when you have data that is formatted in an unusual way or if you want to sort on an underlying data type. Check the MDN sort docs for examples

the custom sort function receives the display values when the column sort is clicked, but I wish to sort on the age. If I had the row available in the sort function I could sort on the sibling cell, something like this:

sortFn: function(a, b) {
    var ageA = a.getProperty('age');
    var ageB = b.getProperty('age');
    return ageA-ageB;
  }

Any suggestions how I can sort by 'age' when the 'ageWord' column is sorted? Example available on plnkr.

Resumption answered 20/12, 2013 at 15:16 Comment(1)
you could use field:'age', cellFilter: 'toWord' and write a filter toWord(num)? Similar to this one: #14767451Barris
A
13

You need to define your column as an object and define your cellTemplate. Then use the age property in your sortFn (http://plnkr.co/edit/qmBsneZ3HmFRKSkjbBWU?p=preview):

// main.js
var app = angular.module('myApp', ['ngGrid']);

app.controller('MyCtrl', function($scope) {
    //Notice age is now an object to be used with the cellTemplate
    var myData1 = [{name: "Moroni", age: {age: 50, ageWord: "Fifty"}},
                     {name: "Tiancum", age: {age: 43, ageWord: "Forty-Three"}},
                     {name: "Mildred", age: {age: 70, ageWord: "Seventy"}},
                     {name: "Jacob", age: {age: 27, ageWord: "Twenty-Seven"}}];


    $scope.gridOptions = { 
      data: 'gridData',
       columnDefs: [
        {field: 'name', displayName: 'Name'}, 
        {field:'age', 
         displayName:'Age',
         cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{COL_FIELD.ageWord}}</span></div>',
         sortFn: function (a, b) {
           //compare age property of the object
           if (a.age < b.age) {
             return -1;
           }
           else if (a.age > b.age) {
             return 1;
           }
           else {
             return 0;
           }
         }
       }]
    };

    $scope.gridData = myData1;

});

According to the docs, cellTemplate defaults to:

<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{COL_FIELD CUSTOM_FILTERS}}</span></div>

So all you need to do is use {{COL_FIELD.age}} and any custom filters you may (or may not) have.

Anadiplosis answered 20/12, 2013 at 16:18 Comment(1)
Worked brilliantly and a game changer for how I was previously preparing/displaying my data. Thanks!Resumption
P
6

You could use sortInfo in your gridOptions, like this:

 $scope.gridOptions = { 
  data: 'gridData',
    columnDefs: [
      {field: 'name', displayName: 'Name'}, 
      {field:'ageWord', displayName: 'Age'}
    ],
    sortInfo: {
      fields: ['age'],
      directions: ['asc']
    }
};
Proconsul answered 20/12, 2013 at 21:6 Comment(1)
sortInfo provides the "initial" sort upon first view. "Define a sortInfo object to specify a default sorting state. " It does not affect the column sort click event.Resumption

© 2022 - 2024 — McMap. All rights reserved.