Now I need a custom sorting routine for the columns of this Grid, but I do
not know where to begin:
Is sorting implemented on the Grid or on the Store? (Or maybe the Data
inside the Store?)
Is there a delcarative hook somewhere for a compare function?
Are there helper functions in dojo for sorting of various types
(float,string,integer,dates) or is it better to use javascript default
operators?
Default sorting in the grid is using the "field" attribute to specify the
data to be sorted. -> Is there a way to specify a complex data field.
(Non-Flat Array as base of the DataGrid)
Thanks!
--
View this message in context: http://dojo-toolkit.33424.n3.nabble.com/How-to-implement-custom-sorting-on-a-declarative-dojox-grid-DataGrid-tp2935028p2935028.html
Sent from the Dojo Toolkit mailing list archive at Nabble.com.
________________________________________________________
Dojotoolkit: http://dojotoolkit.org
Reference Guide: http://dojotoolkit.org/reference-guide
API Documentation: http://dojotoolkit.org/api
Tutorials: http://dojotoolkit.org/documentation
Dojo-i...@mail.dojotoolkit.org
http://mail.dojotoolkit.org/mailman/listinfo/dojo-interest
field="person.name"
In Dojo 1.0 there was a dojox.grid.data.Table which could be used like this:
var model = new dojox.grid.data.Table(null,data);
...
model.fields.get(4).compare = function(a, b){
return (b > a ? 1 : (a == b ? 0 : -1));
}
Both would be adequate sollutions for my Problem, but I am stuck with Dojo
1.6 here and I do not know how to apply the above sollutions to my
environment.
The only option I know off at the moment would be to flatten the response
array that I get from the Database. Since the amount of rows ranges in the
thousands this could be a real performance killer each time the data is
refreshed.
--
View this message in context: http://dojo-toolkit.33424.n3.nabble.com/How-to-implement-custom-sorting-on-a-declarative-dojox-grid-DataGrid-tp2935028p2979996.html
dojo.store.Memory uses a dojo.store.util.SimpleQueryEngine which does only
sort a flat array:
if(options && options.sort){
results.sort(function(a, b){
for(var sort, i=0; sort = options.sort[i]; i++){
var aValue = a[sort.attribute];
var bValue = b[sort.attribute];
if (aValue != bValue) {
return !!sort.descending == aValue > bValue ? -1 : 1;
}
}
return 0;
});
}
Extending this function to accept a nested value from the field Attribute
should be possible.
function _extractValue(obj,key){
if(key.indexOf(".") != -1){
var keys=key.split(".");
for(i=0;i<keys.length;i++){
obj=obj[keys[i]];
}
return obj;
}
else{
return obj[key];
}
}
...
if(options && options.sort){
results.sort(function(a, b){
for(var sort, i=0; sort = options.sort[i]; i++){
var aValue = _extractValue(a,sort.attribute);
var bValue = _extractValue(b,sort.attribute);
if (aValue != bValue) {
return !!sort.descending == aValue > bValue ? -1 : 1;
}
}
return 0;
});
}
However this is only the first part of the problem, since the Grid cannot
cope with the nested notation and will render "..." entries into the Cells.
The format function resting in dojox.grid.cells._base seems to be
responsible for extracting the value from the row data (here: inItem).
format: function(inRowIndex, inItem){
var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) :
(this.value || this.defaultValue);
d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g,
'&').replace(/</g, '&lt;') : d;
if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex
&& i.cell==this))){
return this.formatEditing(d, inRowIndex);
}else{
return this._defaultFormat(d, [d, inRowIndex, this]);
}
}
</raw>
Im still trying to figure out how and where to modify the grid/cells to
accommodate the nested notation (field="foo.bar")
However there are two options:
The first one - like above - would be to support nested keys internally -
which makes it necessary to tweak both the store and the grid (and cells
respectively).
The second one would be to allow for custom "compare" functions defined on
the grid to be used in the store. At the Moment the sort info consists of
the clicked headers field name only.
Support for custom formatters allready exists, so the cells display scheme
wouldn't have to be modified.
--
View this message in context: http://dojo-toolkit.33424.n3.nabble.com/How-to-implement-custom-sorting-on-a-declarative-dojox-grid-DataGrid-tp2935028p2984756.html
This get-Function looks like it could be the sollution for all my problems,
since it allows access to nested array data for the sorting algorithm. (at
least I think so).
Two parameters should be passed to this get function: column index and data
record/item.
My problem is that the second parameter is passed as "null".
Looking at the DataGrid the items variable is null and the subsequently
called private function _by_idx() always returns null too.
Could this be a result of "not" using an ItemFileReadStore, or is there
something I am missing here?
--
View this message in context: http://dojo-toolkit.33424.n3.nabble.com/How-to-implement-custom-sorting-on-a-declarative-dojox-grid-DataGrid-tp2935028p2987998.html
The first problem : specifying nested data for the DataGrid fields was
solved allready using the get-function to dive into the arrays substructure.
(that is explained above)
Sorting however is still dependent on the field attribute.
If the field attribute contains the name of an array this column will not
sort correctly.
I had to modify a few dojo classes to accomodate for that. I will later put
this in a more modular form, but here is the raw result for now:
First I needed to allow the definition of an addtional comparator callback
in the Grid Definition.
For that I have added some code to the dojox.grid.cells._base
dgc._Base.markupFactory = function(node, cellDef){
var d = dojo;
...
var comparator = d.trim(d.attr(node,"comparator")||"");
if(comparator){
cellDef.comparator = dojo.getObject(comparator);
}
...
}
Next the DataGrid needs to give this new parameter to the query to do the
sorting.
This is done in the dojox.grid.DataGrid. "c" is the Cell I modified above.
getSortProps:function(){
...
return[{attribute:c.field,descending:desc,comparator:c.comparator}];
}
Finally I need to change the sorting itself which is defined in
dojo.store.util.SimpleQueryEngine.
SimpleQueryEngine is the default Engine for the MemoryStore
(dojo.store.Memory).
function execute(array){
// execute the whole query, first we filter
var results = dojo.filter(array, query);
// next we sort
if(options && options.sort){
results.sort(function(a, b){
for(var sort, i=0; sort = options.sort[i]; i++){
var aValue = a[sort.attribute];
var bValue = b[sort.attribute];
if (aValue != bValue) {
// changed Part start
if(options.sort[i].comparator){
return !!sort.descending == options.sort[i].comparator(aValue,bValue)
? -1 : 1;
}
else{
return !!sort.descending == aValue > bValue ? -1 : 1;
}
// changed Part end
}
}
return 0;
});
}
...
return results;
}
Now I can add comparators to each column and define them where I want to:
Declarative DataGrid Setup:
...
<td field="myArray" get="getsNameFromArray"
comparator="comparesNames">Name</td>
...
Javascript definition of the comparator function (a and b are "myArray"
objects):
compareNames = function(a,b){
return a.name > b.name;
}
Javascript definition of the getter function (record is the whole row and
contains the "myArray" object):
getNamesFromArray= function(idx,record){
return record.myArray.name;
}
--
View this message in context: http://dojo-toolkit.33424.n3.nabble.com/How-to-implement-custom-sorting-on-a-declarative-dojox-grid-DataGrid-tp2935028p2989124.html