Thank you for this code. It works very good, but i needed to support remotesorting aswell. So i slightly changed your code like this to make it work:
Code:
Ext.override(Ext.data.Store, {
sortState: [],
//compatibility to old sort function
sort: function(fieldName, dir){
this.sortByFields([{
field:fieldName,
direction: dir
}]);
},
sortByFields: function(newFields, add) {
var fields = this.sortState;
//Todo: see if ext has an exisiting lookup implementation
var lookupfn = function (arr, field) {
var index = Ext.each(arr, function (item) {
if(item.field == field) {
return false;
}
});
if(index === undefined) {
return -1;
}
return index;
};
/*
if(!add)
fields = []
*/
Ext.each(newFields, function(item,i){
var doFlip = false;
if (typeof item == 'string') {
item = {
field: item,
direction: 'ASC'
};
doFlip = true;
}
var oldIndex = lookupfn(this.sortState, item.field);
if(oldIndex >= 0) {
if(add) {
//unselect the field if ctrl is pressed again on an already sorted column
fields.splice(oldIndex, 1);
}
else {
fields[oldIndex].direction = (doFlip ? (this.sortState[oldIndex].direction == 'ASC' ? 'DESC':'ASC') : item.direction);
}
}
else {
//only create completely new selection if an unsorted column is clicked withou CTRL pressed
if(!add && i===0) {
fields = [];
}
fields.push(item);
}
}, this);
var si = (this.sortInfo) ? this.sortInfo : null;
this.sortInfo = fields;
this.sortState = fields;
if(!this.remoteSort){
var st = [];
for (var i = 0; i < fields.length; i++) {
st.push(this.fields.get(fields[i].field).sortType);
}
var fn = function(r1, r2) {
var result;
for (var i = 0; !result && i < fields.length; i++) {
var v1 = st[i](r1.data[fields[i].field]);
var v2 = st[i](r2.data[fields[i].field]);
result = (v1 > v2) ? 1 : ((v1 < v2) ? -1 : 0);
if (fields[i].direction == 'DESC') {result = -result; }
}
return result;
};
this.data.sort('ASC', fn);
if(this.snapshot && this.snapshot != this.data){
this.snapshot.sort('ASC', fn);
}
this.fireEvent("datachanged", this);
}else{
if (!this.load(this.lastOptions)) {
if (si) {
this.sortInfo = si;
}
}
}
},
load : function(options){
options = options || {};
if(this.fireEvent("beforeload", this, options) !== false){
this.storeOptions(options);
var p = Ext.apply(options.params || {}, this.baseParams);
if(this.sortInfo && this.remoteSort){
var pn = this.paramNames;
p[pn.sort] = this.sortInfo.field ? this.sortInfo.field :Ext.encode(this.sortInfo);
p[pn.dir] = this.sortInfo.direction ? this.sortInfo.direction : null;
}
this.proxy.load(p, this.reader, this.loadRecords, this, options);
return true;
} else {
return false;
}
}
});
This way the posted var "sort" contains a json of all fields and directions instead of the name only. the modified load-function is backward compatible in case you are using another store with the old functionality.
E.g.
old style:
PHP Code:
sort=street_descr
dir=ASC
new style
PHP Code:
sort=[{"field":"street_descr","direction":"ASC"},{"field":"postal_zip_cd","direction":"ASC"}]
dir=null //is not used anymore here