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');
}
});