PDA

View Full Version : Scope Within Tool Handler???



arth
10 Sep 2008, 9:28 AM
Hello,

I have a function that retrieves database rows via an AJAX call. The function then creates a new panel for each row. Each panel has a 'gear' tool that is supposed to open an edit window with the particular row fields loaded and ready for editing.



// load subjects and create a draggable panel for each
var subjectGroupPanels=[];
function loadSubjects() {
Ext.Ajax.request({
url : '../server/sl.php' ,
params : { action : 'loadSubjects', study: <? echo $study_id; ?> },
method: 'GET',
success: function ( result, request ) {
// Delete any existing panels
if (subjectGroupPanels[0] != null){
for ( var i in subjectGroupPanels ){
if (typeof subjectGroupPanels[i] == 'object'){
subjectGroupPanels[i].destroy();
}
}
}
var subject_groups = eval('(' + result.responseText + ')');
for ( var i in subject_groups ){
if (typeof subject_groups[i][2] != 'undefined'){
// Add a panel for this subject group
var x = subject_groups[i][1];
subjectGroupPanels[i] = new Ext.Panel({
header: true,
html: 'details',
renderTo: 'subject_list',
collapsible: true,
collapsed: true,
draggable: true,
collapseFirst: false,
tools: [{
id:'gear',
qtip: 'Edit or Delete this subject group',
handler: function(event, toolEl, panel){
editSubjectGroup(x); // !!! always passes the value of the LAST x
}
}],
title: subject_groups[i][3] + ' ' + subject_groups[i][2]
});
}
}

// Display raw return in history for debugging
var addTo = Ext.get('history').dom;
addTo.innerHTML = result.responseText + "<br />" + addTo.innerHTML;
},
failure: function ( result, request) {
Ext.MessageBox.alert('Unable to load subjects.', result.responseText);
}
});
}


:(( I can not get my tool handler to correctly pass the database row id to the edit function. If I write:


alert(subject_groups[i][1]); // shows correct value

handler: function(event, toolEl, panel){
editSubjectGroup(subject_groups[i][1]); // alert within called function shows passed value as undefined

If I write:


var id = subject_groups[i][1];
alert(id); // shows correct value

handler: function(event, toolEl, panel){
editSubjectGroup(id); // alert within called function shows passed value as always being the LAST database id. i.e. If there are 5 panels coresponding to ids 1,2,3,4,5 - the handlers for all 5 panels will pass '5' as the id.

I have tried defining the variables outside of this function but that didn't make a difference. Can anyone point me in the right direction? Thank you!!!

mjlecomte
10 Sep 2008, 9:35 AM
collapseFirst: false,
scope: this,
tools: [{ ...

looks like you're redeclaring x each time though.

arth
10 Sep 2008, 9:43 AM
I did add 'scope: this,' and declared x earlier in the function so that it's only declared once and it did not seem to make a difference.

I also tried passing i as the argument to my function. That results in passing a function as a string! It seems that there is some basic principle of javascript that I must be missing...

Thank you!

Condor
10 Sep 2008, 10:02 AM
And if you declared the tools like this?


tools: [{
id:'gear',
qtip: 'Edit or Delete this subject group',
handler: editSubjectGroup.createDelegate(this, [x]);
}],

arth
10 Sep 2008, 10:12 AM
Yes! That does it. Thank you!

mjlecomte
10 Sep 2008, 10:54 AM
I'm not sure I understand the correction.



var x = 1;
var p = new Ext.Panel({
tools: [{
scope: this,//p
handler: function(){
x + 1;
}.createDelegate(this, [x])//append x as argument
}]
});

Is it that this was pointing to the panel. But you (Condor) appended "x" as an argument, which was in the scope of the panel instance (p)? Not sure I get it. :-?

Condor
10 Sep 2008, 11:01 AM
The correct example would be:

var x = 1;
var p = new Ext.Panel({
tools: [{
//scope: this, <- not needed, createDelegate already sets the scope
handler: function(y) { // need fuction WITH argument
alert(y + 1);
}.createDelegate(this, [x]); // append x as argument
}]
});

(but don't ask me why your original code doesn't work, because I don't understand that).

mjlecomte
10 Sep 2008, 11:16 AM
Ok, I left the scope in there for illustration, I realize that you would not need to do both scope and create delegate.

But in the example above, if this is p then there is no p.x correct?

That's why I was thinking it would not work (x is not a property of p). But, instead you appended an argument (x) which was in scope at the time tools was configured, so x was bound as an argument at a point in time that it was in scope?

Just trying to rationalize... :">

I did miss the handler arguments (you appended the argument so may was well use it right?)