PDA

View Full Version : Grid top toolBar and button problem



Cyberangel67
9 Jan 2011, 8:35 PM
I am creating a widget that is extending on the GridPanel, and seem to have run into something that I am not sure is the best way to do it.

I need a Top toolBar and from the searches I have done I need to define the tbar at instantiation.

So in the code I have something like this.



Ext.extend(Ext.ux.newGrid, Ext.grid.GridPanel, {
tbar: [

'keywords: ',
{
id: 'search-field',
xtype: 'textfield',
width: 400
}, {
xtype: 'button',
text: 'Search',
handler: this.onSearch,
scope: this
}
],
});


It all seems to be good it displays the required bar, and the field and button. However the handler is not being called. If I swap the function with atual code it works, if I remove the this scope from the onSearch function name I get a method doesn't exist.

Any one have an idea what is wrong here.

Also is there a better way than this, or is the best practice way?

mitchellsimoens
10 Jan 2011, 5:23 AM
Scope issue

Cyberangel67
10 Jan 2011, 11:48 AM
How is that answer even helpful?

mitchellsimoens
10 Jan 2011, 11:58 AM
It tells you what your error is. Now find out how to fix your error or do you want me to just tell you?

Cyberangel67
10 Jan 2011, 12:03 PM
Really, I would have never guessed.

You know that has got to be the most arrogant response I have seen in these forums, why do you epext everyone to know the answer?

If it was documented easily enough I would not have even bothered asking.

Your answer comes across as well it is an easy problem, well it might be for you guys. But for us newer guys it isn't, nor is it an easy find in any of the documentation that you should or need to do this.

If you want to be smart about it I would prefer you not answer at all.

mitchellsimoens
10 Jan 2011, 12:15 PM
I'm not trying to be arrogant, it's just basic JavaScript and usage of scope so here is a quick tutorial.

Components are just JavaScript Objects. So a Panel for instance looks like this:


{
id: "myPanel",
width: 200,
height: 200,
.....
}

With that being known, you cannot access the scope of the Panel object like this:


{
id: "myPanel",
width: 200,
height: 200,
testme: this,
....
}

and then:


console.log(myPanel.testme);

It won't be the correct scope. However, if you do this in a function, the scope will now be under the Panel:


{
id: "myPanel",
width: 200,
height: 200,
testme: function() {
return this;
}
}
console.log(myPanel.testme());

Now it will return the correct scope.

So in your instance, you are trying to set the scope to this and it's not finding the function you attached to your handler because of what I just went through. You need to set the toolbar and button bar inside a function like initComponent (don't forget to call the superclass of it).

Understand what's going on a little better (this statement is not meant to be ignorant so please don't take it that way).

Cyberangel67
10 Jan 2011, 12:24 PM
I sort of understand that.

But what I don't understand is that this is a self contained widget, that extends the GridPanel.

The config option tbar: is still in the this scope which is the widget, so this is what I am maybe not understanding. As it is a config option I have succesfully done something like this in the past.



Ext.extend(Ext.ux.newGrid, Ext.grid.GridPanel, {
tbar: this.myToolbar
});

If I understand you right, you are now saying that when it is doing this



Ext.extend(Ext.ux.newGrid, Ext.grid.GridPanel, {
tbar: [

'keywords: ',
{
id: 'search-field',
xtype: 'textfield',
width: 400
}, {
xtype: 'button',
text: 'Search',
}
],
});


And it is traversing through the settings code, the this scope is no longer available. So I am no step closer to how I should do this. Even though it hasn't left the this scope?

mitchellsimoens
10 Jan 2011, 12:37 PM
The config option tbar: is still in the this scope which is the widget

You would think however it isn't. What you will need to do is something like this:


Ext.ns("Ext.ux");
Ext.ux.NewGrid = Ext.extend(Ext.grid.GridPanel, {
initComponent: function() {
this.tbar = this.buildTBar();
Ext.ux.NewGrid.superclass.initComponent.call(this); //very important, this will call the parent's initComponent
},
buildTBar: function() {
return [{
xtype: 'button',
text: 'Search',
handler: this.onSearch,
scope: this
}];
},
onSearch: function() {
console.log(this); //will be scope of Ext.ux.NewGrid, I promise!
}
});
Ext.reg("newgrid", Ext.ux.NewGrid);

Cyberangel67
10 Jan 2011, 3:35 PM
Thanks, I knew about that method of doing it, but I didn't see why I had to do it that way. I guess I still have a bit to learn.

mitchellsimoens
10 Jan 2011, 3:40 PM
Thanks, I knew about that method of doing it, but I didn't see why I had to do it that way. I guess I still have a bit to learn.

You can do it the way that you were doing it but I just see more and more people doing it this way. As long as you understand the scope thing, that is the important thing here.