PDA

View Full Version : sort by name for column of gridPanel?



everrich
26 Sep 2008, 12:08 AM
i have 2 columns: Type and Name
Items of column Name: A, a, B, b, 1, 2, _flower.
So i want sorting is:


_flower
1
2
a
A
b
B

But when i choice Sort Ascending:


1
2
A
B
_flower
a
b

and Sort Descending:


b
a
_flower
B
A
2
1

Animal
26 Sep 2008, 12:16 AM
So you want to define your own ordering, and not rely on natural ASCII sort order?

I've thought for a while, that we need to be able to specify a Comparator function to Store.

So

use



Ext.override(Ext.data.Store, {
sortData : function(f, direction){
direction = direction || 'ASC';
var st = this.fields.get(f).sortType;
var fn = this.comparator || function(r1, r2){
var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
};
this.data.sort(direction, fn);
if(this.snapshot && this.snapshot != this.data){
this.snapshot.sort(direction, fn);
}
}
});


Then configure your Store with



{
...
comparator: function(v1, v2) {
// return -1 if v1 is less than v2
// return 0 if v1 is equal to v2
// return 1 if v1 is greater than v2
},
...
}

everrich
26 Sep 2008, 1:13 AM
{
...
comparator: function(v1, v2) {
// return -1 if v1 is less than v2
// return 0 if v1 is equal to v2
// return 1 if v1 is greater than v2
},
...
}

But i don't understand (v1, v2)
when i debug by firebug, my code: var fn = this.comparator || function(r1, r2){...} don't work
can you help me wite code for comparator: function(v1, v2) is more clear

Animal
26 Sep 2008, 1:35 AM
Read the ciode:



var fn = this.comparator || function(r1, r2){
var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
};


Its a function which compares two values, returns -1, 0, or 1 depending on whether v1 is <, =, or > v2

Simple, you write a function which decides the order. This is basic stuff, we've all done this kind of thing in C and Java haven't we?

everrich
26 Sep 2008, 1:56 AM
comparator: function(v1, v2) {
var string1 = v1.data['Name'], string2 = v2.data['Name'];
return(st1.localeCompare(st2));
},

v1.data['Name'] is astring
my code is very good but when i click any column, column Name is sorting
i want when i click column Name, only column Name is soritng
and click column Type, only column Type is sorting

Animal
26 Sep 2008, 2:00 AM
comparator: function(v1, v2) {
var st1 = v1.data[f], st2 = v2.data[f];
return(st1.localeCompare(st2));
},

Animal
26 Sep 2008, 2:05 AM
Hmm, no, obviously, that's not in scope when you define the comparator.

Stand by, it will need a fix in MixedCollection too...

Animal
26 Sep 2008, 2:12 AM
Ext.override(Ext.data.Store, {
sortData : function(f, direction){
direction = direction || 'ASC';
var st = this.fields.get(f).sortType;
var fn = this.comparator || function(r1, r2){
var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
};
this.data.sort(direction, fn, this);
if(this.snapshot && this.snapshot != this.data){
this.snapshot.sort(direction, fn, this);
}
}
});


and



Ext.override(Ext.util.MixedCollection, {
// private
_sort : function(property, dir, fn, scope){
var dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1;
fn = fn || function(a, b){
return a-b;
};
var c = [], k = this.keys, items = this.items;
for(var i = 0, len = items.length; i < len; i++){
c[c.length] = {key: k[i], value: items[i], index: i};
}
c.sort(function(a, b){
var v = fn.call(scope || window, a[property], b[property]) * dsc;
if(v == 0){
v = (a.index < b.index ? -1 : 1);
}
return v;
});
for(var i = 0, len = c.length; i < len; i++){
items[i] = c[i].value;
k[i] = c[i].key;
}
this.fireEvent("sort", this);
},

/**
* Sorts this collection with the passed comparison function
* @param {String} direction (optional) "ASC" or "DESC"
* @param {Function} fn (optional) comparison function
* @param {Object} scope (optional) The scope inwhich to call the comparison function
*/
sort : function(dir, fn, scope){
this._sort("value", dir, fn, scope);
}
});


So then



comparator: function(v1, v2) {
var st1 = v1.data[this.sortInfo.field], st2 = v2.data[this.sortInfo.field];
return(st1.localeCompare(st2));
},

Animal
26 Sep 2008, 2:17 AM
See associated Feature Request thread: http://extjs.com/forum/showthread.php?t=48334

everrich
26 Sep 2008, 2:56 AM
http://i189.photobucket.com/albums/z64/everrich/bug.jpg
your code is problem ?

Animal
26 Sep 2008, 3:00 AM
It's worth every penny.

Debug it.

everrich
26 Sep 2008, 3:27 AM
comparator: function(v1, v2) {
var st1 = v1.data[this.sortInfo.field], st2 = v2.data[this.sortInfo.field];
return(st1.localeCompare(st2));
},

i used your code but a problem is appear:
http://i189.photobucket.com/albums/z64/everrich/bug.jpg

how can i do it?

Animal
26 Sep 2008, 4:51 AM
What you are just sitting there waiting for me to fix the problem? After I gave you some free consultancy?

Scope.

If you could get your finger out and perform debugging instaed of just looking at error messages, you would see that the scope is not set.

Use the code from post 8. It works. I've been to the trouble of testing it in examples/grid/array-grid.js

That'll be

everrich
26 Sep 2008, 6:33 AM
thanks very much and i have some questions
i have 3 columns: Type, Name, Size
when i click columns Size, i want all items sorting by 2 requirement:
1. priority type = 1 : items are sorting to topmost
2. descending by size

How can i do it?

Animal
26 Sep 2008, 6:49 AM
You must examine the fields in your comparator. You are totally in control of the sort order now, and you have all the fields available to you.

everrich
26 Sep 2008, 6:59 AM
I can't write this code
Can you share for me some codem please.

mjlecomte
26 Sep 2008, 7:04 AM
If Animal doesn't do all of your project for you, you might refer here:
http://extjs.com/learn/Ext_FAQ_Grid#Sorting_issues

There's some custom sort nuggets there also.

everrich
26 Sep 2008, 7:28 AM
I had readed http://extjs.com/learn/Ext_FAQ_Grid#Sorting_issues but it isn't useful for me
Can you write some code for me, please.