PDA

View Full Version : [2.3] Multisort grid and store



MeDavid
29 Aug 2009, 7:34 AM
It's a hack to support multi column sort in the grid using the ctrl button while clicking a header. It Uses a modified version of the multiSort function from 'Animal' which can be found at http://www.extjs.com/forum/showthread.php?p=232118#post232118

It's not the best code (overriding extjs private methods), but I needed a quick hack

mbstroz
8 Oct 2009, 6:41 AM
I am going to test this. I need this functionality to move forward on my project.

wm003
26 Oct 2009, 6:11 AM
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:



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:

sort=street_descr
dir=ASC
new style

sort=[{"field":"street_descr","direction":"ASC"},{"field":"postal_zip_cd","direction":"ASC"}]
dir=null //is not used anymore here

wm003
19 Nov 2009, 1:38 AM
I change the code a bit (changed code in post above)

- unselect a column when it is clicked whith CTRL pressed and was already selected before
- support both menu entries in the column menu for sorting the columns
- only select one single column and unselect all others if a column is clicked which has _not_ been selected before

ekojs
11 Sep 2013, 8:03 PM
@Animal -- I have been looking at your multisortgrid function and I'm wondering how to use this in my Extjs or in my PHP.... sorry I'm newbie, can you give me step by step how to use that ?

Thank's before....