PDA

View Full Version : grid dataIndex and sorting



ericwaldheim
6 Oct 2006, 9:56 AM
When I click to sort a column in which the dataIndex exceeds the number of columns in the grid (less one), I get the following error:

Error: this.config[col] has no properties
Source File: http://localhost:8080/tmg/yui-ext/basic-grid-lib.js Line: 112

I'm using the yui-ext.32.2 release.

(Amazing work. thanks.)

jack.slocum
6 Oct 2006, 8:38 PM
Can you explain a little more, maybe a code sample? It's sounds like you are saying that when you sort on a column that has a dataIndex greater than the number of available indexes in the data model you get an error? (which is what you should get).

ericwaldheim
7 Oct 2006, 7:41 AM
The Grid has one column, the DataModel has 2 columns.
With dataIndex (which is an excellent feature) I can display
just the second column. But sorting it fails.



var g = YAHOO.ext.grid;
var s = g.DefaultColumnModel.sortTypes;
var cols = [
{header:"Name", width:150, dataIndex:1,
sortable:true, sortType:s.asStr},
];
grid = new g.Grid('lbox',
new g.DefaultDataModel([[3,3],[1,1],[2,2]]),
new g.DefaultColumnModel(cols)
)
grid.render();

[img]

jack.slocum
7 Oct 2006, 8:35 AM
Try it without the extra comma. ;)



var cols = [
{header:"Name", width:150, dataIndex:1,
sortable:true, sortType:s.asStr}, <--- extra comma
];

ericwaldheim
7 Oct 2006, 9:46 AM
Nope, same issue. Here's what I think is happening.

Line 758 of GridView.js calls sort with a dataIndex


dm.sort(cm, cm.getDataIndex(header.columnIndex), direction);


But the data model is expecting a columnIndex:



YAHOO.ext.grid.DefaultDataModel.prototype.sort = function(columnModel, columnIndex, direction, suppressEvent){


So in my example the dataIndex is 1 but the largest columnIndex is 0.

jack.slocum
7 Oct 2006, 10:26 AM
That code is right. The data model is expecting a column index matching it's structure (which is what a dataIndex is). But it led me to this:

sort() is calling out to the ColumnModel, which is where the sortTypes are defined. It is passing it's column index (the dataIndex), which doesn't match the column models column index.

That is indeed a bug.

Nice find, I will fix it now.

jack.slocum
7 Oct 2006, 10:33 AM
Can you paste this somewhere in your code and tell me if it fixes it?


YAHOO.ext.grid.DefaultColumnModel.prototype.getSortType = function(col){
col = this.getDataIndex(col);
if(!this.config[col].sortType){
return YAHOO.ext.grid.DefaultColumnModel.sortTypes.none;
}
return this.config[col].sortType;
};

The sortTypes being on the column model is going to be eliminated soon. They should be defined on the data model for this very reason. The only reason it hasn't been done is to not break peoples code.

ericwaldheim
7 Oct 2006, 11:06 PM
Nope, that doesn't seem to be it.

I traced starting in YAHOO.ext.grid.HeaderController.headerClick.
Within this func we have:

header.columnIndex is 0
cm.getDataIndex(header.columnIndex) is 1

headerClick then makes this call:


dm.sort(cm, cm.getDataIndex(header.columnIndex), direction);

so we end up here with columnIndex = 1:


YAHOO.ext.grid.DefaultDataModel.prototype.sort = function(columnModel, columnIndex, direction, suppressEvent){
...
var sortType = columnModel.getSortType(columnIndex);

getSortType then calls getDataIndex with col=1:


YAHOO.ext.grid.DefaultColumnModel.prototype.getDataIndex = function(col){
if(typeof this.config[col].dataIndex != 'number'){
return col;
}
return this.config[col].dataIndex;
};


with col=1. Since there is no col w/ index 1 in our ColumnModel we get the exception:


Error: this.config[col] has no properties
Source File: DefaultColumnModel.js Line: 175


So I'm still of the opinion that we go wrong when we pass a dataIndex of 1 and to a function that wants a columnIndex (max should be 0). But it's late, perhaps I've missed something. Thanks.[/b]

jack.slocum
8 Oct 2006, 1:38 AM
So I'm still of the opinion that we go wrong when we pass a dataIndex of 1 and to a function that wants a columnIndex (max should be 0). But it's late, perhaps I've missed something.

The data model doesn't care about the column model's column index, it only cares about it's column indexes.

Had I thought it out a little further, I would have realize getDataIndex would fail in the same way. This will fix the problem, although I am not happy with the solution. Maybe it's time to break everyone code (and mine) and take the sortType off the ColumnModel. It is not compatible with the dataIndex feature and I predict it will cause even more problems in the future.

The data index lookup is lazy initialized so it is only built if the user actually does a sort.


YAHOO.ext.grid.DefaultColumnModel.prototype.getSortType = function(col){
if(!this.dataMap){
// build a lookup so we don't search every time
var map = [];
for(var i = 0, len = this.config.length; i < len; i++){
map[this.getDataIndex(i)] = i;
}
this.dataMap = map;
}
col = this.dataMap[col];
if(!this.config[col].sortType){
return YAHOO.ext.grid.DefaultColumnModel.sortTypes.none;
}
return this.config[col].sortType;
};

Animal
8 Oct 2006, 11:17 AM
Make the change before there's too much code to break. The sort type is definitely part of the data model. It's not a huge amount of refactoring for Grid users. I'll accomodate it no problem.

ericwaldheim
9 Oct 2006, 7:57 AM
Yep. Thanks.

And the Grid code is so clean, you'll never hear a complaint from me regarding breaking it to keep it that way.

I also figured out where I got confused: there is no concept of dataIndex in the DataModel, it uses the term columnIndex. So passing a dataIndex from the ColumnModel to a columnIndex in the DataModel makes perfect sense.

Thank you.