PDA

View Full Version : Correct behaviour of event "selectionchange"?



Wolfgang
16 Aug 2007, 12:49 PM
How should "selectionchange" be used to detect a change in the selection of a row in the grid?

"selectionchange" Events generated when clicking twice on the same row:


//1.click
["selectionchange", Object singleSelect=true selections=[0] last=false]
["selectionchange", Object singleSelect=true selections=[1] last=8 lastActive=8]
//2.click
["selectionchange", Object singleSelect=true selections=[0] last=false]
["selectionchange", Object singleSelect=true selections=[1] last=8 lastActive=8]

Now, a click on a different row:


["selectionchange", Object singleSelect=true selections=[0] last=false]
["selectionchange", Object singleSelect=true selections=[1] last=9 lastActive=9]


I could for example store last somewhere as var last_prev = last; and then compare last == last_prev in the eventhandler.
However, i thing that "selectionchange" would/should provide the info _that a selection has changed_, itself.

Any comment on this is welcome.

Wolfgang

Wolfgang
17 Aug 2007, 9:32 AM
Can anyone confirm wether this is a bug or wether i am using this event in a wrong way?
Why does it fire two times?
So far it looks similar to "rowclick" (when trying to detect a selection change)

Animal
17 Aug 2007, 9:55 AM
I think there's something strange.

It shouyld fire twice if you click on a different row. Unselecting the old selected row, and selecting the new row.

But IMHO, clicking on an already selected row should not fire a selection change event.

I had to code round this. My Grid wrapper object fires a selection event only when a row is first selected.

Wolfgang
17 Aug 2007, 10:55 AM
Animal i totally agree with you, but i really get two events for each click, regardless wether i use the same, or another row.

Here a snippet from my code includig a workaround (store old value / buffered listener):
- "lastSelectedFahrzeug" is a var in my closure to store the value of the prev. selected id (i do not use the record id but the value of 'id' in my store)
- i use a buffered listner to avoid getting 2 events. However the code could handle this, because i check "lastActive" upfront.



// Grid create - Requires DS
grid = new Ext.grid.EditorGrid(gridId, {
ds: ds,
cm: cm,
selModel: new Ext.grid.RowSelectionModel({singleSelect:true}),
autoExpandColumn: 'id_mitarbeiter',
enableColLock: false,
loadMask: true
});



// Snyc 2nd Grid
function getFahrzeug(sm) {
// event can fires twice if buffer is not used. first time without a record
if (typeof sm.lastActive == 'boolean') {
return true;
}
// valid event, lets see wether there is a change
var rowRecord = sm.getSelected();
var fahrzeugId = rowRecord.get('id');
if (fahrzeugId == lastSelectedFahrzeug) {
return true;
}

lastSelectedFahrzeug = fahrzeugId;
var fahrzeug = rowRecord.get('klasse') + '' + rowRecord.get('typ') + ' : ' + rowRecord.get('kennzeichen');
GUI.td_buchung.loadBuchung(fahrzeugId, fahrzeug);
return true;
}
// use a buffered listener to avoid getting two events
grid.getSelectionModel().on('selectionchange', getFahrzeug, this, {buffer: 250});

Wolfgang
17 Aug 2007, 11:01 AM
Find attached a complete event trace:


//1st click on the row in the grid
["beforerowselect", Object singleSelect=true selections=[1] last=2 lastActive=2, 2, false]
["remove", Object id=24 data=Object json=Object store=Object, "24"]
["rowdeselect", Object singleSelect=true selections=[0] last=false, 2]
["selectionchange", Object singleSelect=true selections=[0] last=false]
["clear"]
["add", 0, Object id=24 data=Object json=Object store=Object, "24"]
["rowselect", Object singleSelect=true selections=[1] last=2 lastActive=2, 2, Object id=24 data=Object json=Object store=Object]
["selectionchange", Object singleSelect=true selections=[1] last=2 lastActive=2]
["click", Object browserEvent=Event click button=0 type=click]
["rowclick", Object container=Object id=md_fahrzeug_vorgang, 2, Object browserEvent=Event click button=0 type=click]
["cellclick", Object container=Object id=md_fahrzeug_vorgang, 2, 6, Object browserEvent=Event click button=0 type=click]
//2nd click on the same row in the grid
["beforerowselect", Object singleSelect=true selections=[1] last=2 lastActive=2, 2, false]
["remove", Object id=24 data=Object json=Object store=Object, "24"]
["rowdeselect", Object singleSelect=true selections=[0] last=false, 2]
["selectionchange", Object singleSelect=true selections=[0] last=false]
["clear"]
["add", 0, Object id=24 data=Object json=Object store=Object, "24"]
["rowselect", Object singleSelect=true selections=[1] last=2 lastActive=2, 2, Object id=24 data=Object json=Object store=Object]
["selectionchange", Object singleSelect=true selections=[1] last=2 lastActive=2]
["click", Object browserEvent=Event click button=0 type=click]
["rowclick", Object container=Object id=md_fahrzeug_vorgang, 2, Object browserEvent=Event click button=0 type=click]
["cellclick", Object container=Object id=md_fahrzeug_vorgang, 2, 6, Object browserEvent=Event click button=0 type=click]
//new click on another row in the grid
["beforerowselect", Object singleSelect=true selections=[1] last=2 lastActive=2, 3, false]
["remove", Object id=24 data=Object json=Object store=Object, "24"]
["rowdeselect", Object singleSelect=true selections=[0] last=false, 2]
["selectionchange", Object singleSelect=true selections=[0] last=false]
["clear"]
["add", 0, Object id=25 data=Object json=Object store=Object, "25"]
["rowselect", Object singleSelect=true selections=[1] last=3 lastActive=3, 3, Object id=25 data=Object json=Object store=Object]
["selectionchange", Object singleSelect=true selections=[1] last=3 lastActive=3]
["click", Object browserEvent=Event click button=0 type=click]
["rowclick", Object container=Object id=md_fahrzeug_vorgang, 3, Object browserEvent=Event click button=0 type=click]
["cellclick", Object container=Object id=md_fahrzeug_vorgang, 3, 6, Object browserEvent=Event click button=0 type=click]
["beforeload", Object data=[2] baseParams=Object paramNames=Object, Object]
["beforeload", Object events=Object conn=Object useAjax=true, Object start=0 limit=20 id_fz=25 sort=adatum dir=DESC]
["beforerequest", Object autoAbort=false events=Object transId=false, Object params=Object request=Object reader=Object]
["requestcomplete", Object autoAbort=false events=Object transId=false, Object tId=33 status=200 statusText=OK, Object params=Object request=Object reader=Object]
["load", Object events=Object conn=Object useAjax=true, Object params=Object request=Object reader=Object, Object]
["clear"]
["datachanged", Object data=[0] baseParams=Object paramNames=Object]
["beforerefresh", Object grid=Object events=Object el=Object]
["refresh", Object grid=Object events=Object el=Object]
["load", Object data=[0] baseParams=Object paramNames=Object, [], Object]

Wolfgang
18 Aug 2007, 2:29 AM
One note:
The "load" events created when clicking on another row are created from the 2nd grid.

Wolfgang
20 Aug 2007, 2:51 AM
Anyone having a similar issue with the "selectionchange" event or can point out wether i misunderstand this event?

Wolfgang
22 Aug 2007, 11:51 PM
Can someone comment wether selectionchange is suppose to fire only when the clicked row changed and/or wether this is/might be a possible bug?

Animal
23 Aug 2007, 12:18 AM
Well the code is



selectRow : function(index, keepExisting, preventViewNotify){
if(this.locked || (index < 0 || index >= this.grid.dataSource.getCount())) return;
if(this.fireEvent("beforerowselect", this, index, keepExisting) !== false){
if(!keepExisting || this.singleSelect){
this.clearSelections();
}
var r = this.grid.dataSource.getAt(index);
this.selections.add(r);
this.last = this.lastActive = index;
if(!preventViewNotify){
this.grid.getView().onRowSelect(index);
}
this.fireEvent("rowselect", this, index, r);
this.fireEvent("selectionchange", this);
}
},


You can see that it first clears the current selection which will fire the "selectionchange" event. And then it selects the row, and fires the "selectionchange" event.

I think it's a bug, and it should be:



selectRow : function(index, keepExisting, preventViewNotify){
if (this.isSelected(index)) {
return;
}
if(this.locked || (index < 0 || index >= this.grid.dataSource.getCount())) return;
if(this.fireEvent("beforerowselect", this, index, keepExisting) !== false){
if(!keepExisting || this.singleSelect){
this.clearSelections();
}
var r = this.grid.dataSource.getAt(index);
this.selections.add(r);
this.last = this.lastActive = index;
if(!preventViewNotify){
this.grid.getView().onRowSelect(index);
}
this.fireEvent("rowselect", this, index, r);
this.fireEvent("selectionchange", this);
}
},

Wolfgang
23 Aug 2007, 9:44 AM
Thank you animal.

I though it was a bug, but was not sure. Your fix makes perfect sense.

Do you want me to open a thread in the bug report forum for this to ensure it gets fixed in the upcoming release?

Animal
23 Aug 2007, 11:03 PM
Perhaps Jack made it work that for a reason. It's never a good idea to second guess him!

But I think posting a thread and the suggested fix in the Bugs forum might be a good idea. If it's intentional then we might get an explanation.

Wolfgang
24 Aug 2007, 8:03 AM
http://extjs.com/forum/showthread.php?p=57403#post57403