0

I have a grid that contains some complex data (basically, the cells are "3D"). I use a renderer to populate each cell because the actual data is buried down in a hasMany relationship. By knowing the row and column, I can access that row's relationship's store, and grab my data based on the column index. Because there is this relationship in my grid's data, it makes sorting very difficult, and using sortType isn't something that I can employ, or at least, I haven't figured out how to use it yet.

I have come up with a solution, but it seems to not work/throw an error in Internet Explorer. My solution listens for the sortchange event on the grid, checks to see if the clicked column is one of my unique columns, creates the sort function based on the direction, and then uses setSorters to actually do the sorting.

There is no error thrown in IE until I try to output the sort function's passed in records. The error that I get is Ext.data.Model#persistenceProperty" is deprecated... in Chrome and Firefox, the console.log outputs the appropriate record, so I'm confused why IE would do this... it's not like I'm doing anything crazy.

I have reported this issue on the Sencha forums, but it was changed from a bug to a normal question, which leads me to believe that I might be going about this the wrong way. I do know about this thread, but doSort is no longer a method in ExtJS 5.

Does anyone have any guidance on how to accomplish this in all browsers? And is what I'm doing legal/is this really a bug? Here is my example and code:

Ext.application({
  name: 'Fiddle',

  launch: function() {
    Ext.define('DayModel', {
      extend: 'Ext.data.Model',
      fields: [{
        name: 'day',
        type: 'string'
      }, {
        name: 'value',
        type: 'number'
      }]
    });
    Ext.define('WeekModel', {
      extend: 'Ext.data.Model',
      fields: [{
        name: 'week',
        type: 'string'
      }],
      hasMany: [{
        associationKey: 'days',
        name: 'getDaysStore',
        model: 'DayModel'
      }]
    });
    Ext.define('MyStore', {
      extend: 'Ext.data.Store',
      model: 'WeekModel',
      proxy: {
        type: 'ajax',
        url: 'data1.json'
      }
    });
    Ext.define('MyGrid', {
      extend: 'Ext.grid.Panel',
      renderTo: Ext.getBody(),
      initComponent: function() {
        this.callParent();
        this.on('sortchange', this.onSortChange, this);
        var store = Ext.create('MyStore');
        if (store) {
          store.on('load', this.onStoreLoad, this);
          this.setStore(store);
          store.load();
        }
      },
      dayColumnRenderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
        if (record) {
          var daysStore = record.getDaysStore();
          if (daysStore) {
            // subtract 1 because we have the Week column as the first column, so index is shifted by 1
            var dayRecord = daysStore.getAt(colIndex - 1);
            if (dayRecord) {
              value = dayRecord.get('value');
            }
          }
        }
        return value;
      },
      sortColumnByIndex: function(columnIndex, direction) {
        var store = this.getStore();
        if (store) {
          var sorterFn = function(rec1, rec2) {
            var sortValue = false;
            console.log(rec1, rec2);
            if (rec1 && rec2) {
              var day1;
              var daysStore1 = rec1.getDaysStore();
              if (daysStore1) {
                day1 = daysStore1.getAt(columnIndex);
              }
              var day2;
              var daysStore2 = rec2.getDaysStore();
              if (daysStore2) {
                day2 = daysStore2.getAt(columnIndex);
              }
              if (day1 && day2) {
                sortValue = day1.get('value') > day2.get('value');
              }
            }
            return sortValue;
          };
          if (direction !== 'ASC') {
            sorterFn = function(rec1, rec2) {
              var sortValue = false;
              if (rec1 && rec2) {
                var day1;
                var daysStore1 = rec1.getDaysStore();
                if (daysStore1) {
                  day1 = daysStore1.getAt(columnIndex);
                }
                var day2;
                var daysStore2 = rec2.getDaysStore();
                if (daysStore2) {
                  day2 = daysStore2.getAt(columnIndex);
                }
                if (day1 && day2) {
                  sortValue = day1.get('value') < day2.get('value');
                }
              }
              return sortValue;
            };
          }
          store.setSorters([{
            sorterFn: sorterFn
          }]);
        }
      },
      onStoreLoad: function(store, records, successful, eOpts) {
        // set columns
        var columns = [{
          text: 'Week',
          dataIndex: 'week'
        }];
        if (records) {
          var firstRecord = records[0];
          if (firstRecord) {
            var daysStore = firstRecord.getDaysStore();
            if (daysStore) {
              daysStore.each(function(dayRecord, dayColumnIndex) {
                columns.push({
                  text: dayRecord.get('day'),
                  dataIndex: 'day' + dayColumnIndex,
                  dayColumnIndex: dayColumnIndex,
                  renderer: this.dayColumnRenderer
                });
              }, this);
            }
          }
        }
        this.reconfigure(null, columns);
      },
      onSortChange: function(container, column, direction, eOpts) {
        // check for weekColumnIndex
        if (column && column.dayColumnIndex !== undefined) {
          this.sortColumnByIndex(column.dayColumnIndex, direction);
        }
      }
    });
    Ext.create('MyGrid');
  }
});

data1.json

[
  {
    "week": "8\/27\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 821.13
      },
      {
        "day": "Tuesday",
        "value": 244.45
      },
      {
        "day": "Wednesday",
        "value": 664.59
      },
      {
        "day": "Thursday",
        "value": 572.49
      },
      {
        "day": "Friday",
        "value": 100.96
      }
    ]
  },
  {
    "week": "5\/3\/2015",
    "days": [
      {
        "day": "Monday",
        "value": 885.49
      },
      {
        "day": "Tuesday",
        "value": 417.41
      },
      {
        "day": "Wednesday",
        "value": 419.62
      },
      {
        "day": "Thursday",
        "value": 512.05
      },
      {
        "day": "Friday",
        "value": 441.35
      }
    ]
  },
  {
    "week": "9\/2\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 385.65
      },
      {
        "day": "Tuesday",
        "value": 446.5
      },
      {
        "day": "Wednesday",
        "value": 475.39
      },
      {
        "day": "Thursday",
        "value": 821.32
      },
      {
        "day": "Friday",
        "value": 700.17
      }
    ]
  },
  {
    "week": "11\/6\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 55.76
      },
      {
        "day": "Tuesday",
        "value": 275.73
      },
      {
        "day": "Wednesday",
        "value": 321.79
      },
      {
        "day": "Thursday",
        "value": 589.53
      },
      {
        "day": "Friday",
        "value": 986.44
      }
    ]
  },
  {
    "week": "5\/16\/2015",
    "days": [
      {
        "day": "Monday",
        "value": 212.09
      },
      {
        "day": "Tuesday",
        "value": 587.13
      },
      {
        "day": "Wednesday",
        "value": 530.96
      },
      {
        "day": "Thursday",
        "value": 511.06
      },
      {
        "day": "Friday",
        "value": 154.04
      }
    ]
  },
  {
    "week": "4\/25\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 905.84
      },
      {
        "day": "Tuesday",
        "value": 792.99
      },
      {
        "day": "Wednesday",
        "value": 283.89
      },
      {
        "day": "Thursday",
        "value": 10.06
      },
      {
        "day": "Friday",
        "value": 855.79
      }
    ]
  },
  {
    "week": "10\/3\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 554.08
      },
      {
        "day": "Tuesday",
        "value": 32.82
      },
      {
        "day": "Wednesday",
        "value": 767.86
      },
      {
        "day": "Thursday",
        "value": 455.03
      },
      {
        "day": "Friday",
        "value": 91.45
      }
    ]
  },
  {
    "week": "4\/20\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 986.91
      },
      {
        "day": "Tuesday",
        "value": 461.16
      },
      {
        "day": "Wednesday",
        "value": 111.98
      },
      {
        "day": "Thursday",
        "value": 402.46
      },
      {
        "day": "Friday",
        "value": 901.53
      }
    ]
  },
  {
    "week": "5\/11\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 333.73
      },
      {
        "day": "Tuesday",
        "value": 199.59
      },
      {
        "day": "Wednesday",
        "value": 262.88
      },
      {
        "day": "Thursday",
        "value": 572.45
      },
      {
        "day": "Friday",
        "value": 107.91
      }
    ]
  },
  {
    "week": "6\/21\/2015",
    "days": [
      {
        "day": "Monday",
        "value": 918.2
      },
      {
        "day": "Tuesday",
        "value": 560.97
      },
      {
        "day": "Wednesday",
        "value": 366.1
      },
      {
        "day": "Thursday",
        "value": 984.78
      },
      {
        "day": "Friday",
        "value": 992.21
      }
    ]
  },
  {
    "week": "6\/27\/2015",
    "days": [
      {
        "day": "Monday",
        "value": 386.41
      },
      {
        "day": "Tuesday",
        "value": 640.2
      },
      {
        "day": "Wednesday",
        "value": 48.1
      },
      {
        "day": "Thursday",
        "value": 306.6
      },
      {
        "day": "Friday",
        "value": 855.79
      }
    ]
  },
  {
    "week": "3\/6\/2015",
    "days": [
      {
        "day": "Monday",
        "value": 856.98
      },
      {
        "day": "Tuesday",
        "value": 747.94
      },
      {
        "day": "Wednesday",
        "value": 638.24
      },
      {
        "day": "Thursday",
        "value": 341.54
      },
      {
        "day": "Friday",
        "value": 792.7
      }
    ]
  },
  {
    "week": "10\/16\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 999.63
      },
      {
        "day": "Tuesday",
        "value": 586.11
      },
      {
        "day": "Wednesday",
        "value": 626.51
      },
      {
        "day": "Thursday",
        "value": 39.03
      },
      {
        "day": "Friday",
        "value": 524.8
      }
    ]
  },
  {
    "week": "2\/4\/2015",
    "days": [
      {
        "day": "Monday",
        "value": 662.25
      },
      {
        "day": "Tuesday",
        "value": 943.43
      },
      {
        "day": "Wednesday",
        "value": 926.43
      },
      {
        "day": "Thursday",
        "value": 89.6
      },
      {
        "day": "Friday",
        "value": 442.88
      }
    ]
  },
  {
    "week": "11\/18\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 118.1
      },
      {
        "day": "Tuesday",
        "value": 218.62
      },
      {
        "day": "Wednesday",
        "value": 639.59
      },
      {
        "day": "Thursday",
        "value": 426.43
      },
      {
        "day": "Friday",
        "value": 645.38
      }
    ]
  },
  {
    "week": "12\/24\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 798.07
      },
      {
        "day": "Tuesday",
        "value": 373.61
      },
      {
        "day": "Wednesday",
        "value": 479.74
      },
      {
        "day": "Thursday",
        "value": 732.26
      },
      {
        "day": "Friday",
        "value": 85.73
      }
    ]
  },
  {
    "week": "4\/11\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 365.01
      },
      {
        "day": "Tuesday",
        "value": 35.47
      },
      {
        "day": "Wednesday",
        "value": 894.57
      },
      {
        "day": "Thursday",
        "value": 521.17
      },
      {
        "day": "Friday",
        "value": 477.67
      }
    ]
  },
  {
    "week": "12\/21\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 113.72
      },
      {
        "day": "Tuesday",
        "value": 218.71
      },
      {
        "day": "Wednesday",
        "value": 672.37
      },
      {
        "day": "Thursday",
        "value": 3.09
      },
      {
        "day": "Friday",
        "value": 179.24
      }
    ]
  },
  {
    "week": "7\/30\/2014",
    "days": [
      {
        "day": "Monday",
        "value": 40.6
      },
      {
        "day": "Tuesday",
        "value": 644.09
      },
      {
        "day": "Wednesday",
        "value": 211.88
      },
      {
        "day": "Thursday",
        "value": 109.62
      },
      {
        "day": "Friday",
        "value": 199.69
      }
    ]
  },
  {
    "week": "3\/11\/2015",
    "days": [
      {
        "day": "Monday",
        "value": 617.25
      },
      {
        "day": "Tuesday",
        "value": 720.71
      },
      {
        "day": "Wednesday",
        "value": 117.68
      },
      {
        "day": "Thursday",
        "value": 625.6
      },
      {
        "day": "Friday",
        "value": 733.51
      }
    ]
  }
]

EDIT

I can accomplish this with model mapping, but the idea is that my data will have a dynamic number of columns (I know this example doesn't show it, but go with it), so that makes this a little more difficult. However, using mapping does drastically reduce the amount of code bloat. Example and code:

Ext.application({
  name: 'Fiddle',

  launch: function() {
    Ext.define('DayModel', {
      extend: 'Ext.data.Model',
      fields: [{
        name: 'day',
        type: 'string'
      }, {
        name: 'value',
        type: 'number'
      }]
    });
    Ext.define('WeekModel', {
      extend: 'Ext.data.Model',
      fields: [{
        name: 'week',
        type: 'string'
      }, {
          name: 'day0',
          type: 'number',
          mapping: 'days[0].value'
      }, {
          name: 'day1',
          type: 'number',
          mapping: 'days[1].value'
      }, {
          name: 'day2',
          type: 'number',
          mapping: 'days[2].value'
      }, {
          name: 'day3',
          type: 'number',
          mapping: 'days[3].value'
      }, {
          name: 'day4',
          type: 'number',
          mapping: 'days[4].value'
      }],
      hasMany: [{
        associationKey: 'days',
        name: 'getDaysStore',
        model: 'DayModel'
      }]
    });
    Ext.define('MyStore', {
      extend: 'Ext.data.Store',
      model: 'WeekModel',
      proxy: {
        type: 'ajax',
        url: 'data1.json'
      }
    });
    Ext.define('MyGrid', {
      extend: 'Ext.grid.Panel',
      renderTo: Ext.getBody(),
      initComponent: function() {
        this.callParent();
        var store = Ext.create('MyStore');
        if (store) {
          store.on('load', this.onStoreLoad, this);
          this.setStore(store);
          store.load();
        }
      },
      onStoreLoad: function(store, records, successful, eOpts) {
        // set columns
        var columns = [{
          text: 'Week',
          dataIndex: 'week'
        }];
        if (records) {
          var firstRecord = records[0];
          if (firstRecord) {
            var daysStore = firstRecord.getDaysStore();
            if (daysStore) {
              daysStore.each(function(dayRecord, dayColumnIndex) {
                columns.push({
                  text: dayRecord.get('day'),
                  dataIndex: 'day' + dayColumnIndex,
                  dayColumnIndex: dayColumnIndex
                });
              }, this);
            }
          }
        }
        this.reconfigure(null, columns);
      }
    });
    Ext.create('MyGrid');
  }
});

1 Answer 1

0

With the help of Joel Watson over on the Sencha Forums, he was able to figure out my issue... I was returning the wrong values from the sorterFn. According to the docs:

A specific sorter function to execute. Can be passed instead of property. This function should compare the two passed arguments, returning -1, 0 or 1 depending on if item 1 should be sorted before, at the same level, or after item 2.

So my updated code goes to:

var sorterFn = function(rec1, rec2) {
  var sortValue = false;
  if (rec1 && rec2) {
    var day1;
    var daysStore1 = rec1.getDaysStore();
    if (daysStore1) {
      day1 = daysStore1.getAt(columnIndex);
    }
    var day2;
    var daysStore2 = rec2.getDaysStore();
    if (daysStore2) {
      day2 = daysStore2.getAt(columnIndex);
    }
    if (day1 && day2) {
        var val1 = day1.get('value');
        var val2 = day2.get('value');
        // this is the key to it all
        sortValue = val1 > val2 ? 1 : val1 === val2 ? 0 : -1;
    }
  }
  return sortValue;
};
if (direction !== 'ASC') {
  sorterFn = function(rec1, rec2) {
    var sortValue = false;
    if (rec1 && rec2) {
      var day1;
      var daysStore1 = rec1.getDaysStore();
      if (daysStore1) {
        day1 = daysStore1.getAt(columnIndex);
      }
      var day2;
      var daysStore2 = rec2.getDaysStore();
      if (daysStore2) {
        day2 = daysStore2.getAt(columnIndex);
      }
      if (day1 && day2) {
        var val1 = day1.get('value');
        var val2 = day2.get('value');
        // this is the key to it all
        sortValue = val1 < val2 ? 1 : val1 === val2 ? 0 : -1;
      }
    }
    return sortValue;
  };
}
store.setSorters([{
  sorterFn: sorterFn
}]);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.