PDA

View Full Version : Possible to enable/disable multiple buttons (grid actions) in jQuery-like way?



DCstewieG
9 Mar 2012, 8:19 AM
I have a grid with multiple toolbar actions that should only be enabled after a row is selected. I was hoping to do this in a way similar to jQuery but it doesn't seem that Ext works like it for multiple components. In my grid view, I have cls: 'itemAction' defined on my buttons in the docked toolbar. I was hoping this would work:



refs:
[
{ selector: 'gridalias button[class=itemAction]', ref: 'itemActions' }
],

init: function()
{
this.control(
{
'gridalias':
{
select: this.enableActions
}
}
},

enableActions: function()
{
this.getItemActions().enable();
}

But this.getItemActions() is undefined. I guess you can't use classes to do component queries? Or to get multiple components? So then I tried:



refs:
[
{ selector: 'gridalias', ref: 'grid' }
],

init: function()
{
this.control(
{
'gridalias':
{
select: this.enableActions
}
}
},

enableActions: function()
{
this.getGrid().query('button[class=itemAction]').enable();
}

Still no good, I get an empty array, and enable() isn't available anyway. What's the best way to select multiple components and then do something with all of them? Seems I'll have to use each() but still not sure how to do my query in this case.

mitchellsimoens
9 Mar 2012, 11:59 AM
button[class=itemAction]

Should be


button[cls=itemAction]

Do note that the query() method will always return an array.

arthurakay
9 Mar 2012, 12:09 PM
I was hoping to do this in a way similar to jQuery but it doesn't seem that Ext works like it for multiple components.

I assume you mean the ability to chain methods... and you're right, ExtJS doesn't do that quite the way you're looking for. That's not necessarily a bad thing - just a difference in the approach.

So let's say you need to find the buttons in question via a component query:



var buttons = mygrid.query('button[cls=itemAction]');
//your query might need to be massaged to work... you didn't post your button configs


"buttons" would now be an array, so you could run the following:

Ext.Array.each(buttons, function(button) { button.enable(); });

DCstewieG
9 Mar 2012, 12:16 PM
I still get an empty array with [cls=itemAction]. Just for a sanity check I tried this.getGrid().query('button') and I do get back all of the buttons (including some that should always be enabled) so I know I'm querying in the right place, just that my selector is wrong.

For reference, my view includes this:


initComponent: function()
{
this.dockedItems =
[
{
xtype: 'toolbar',
dock: 'top',
items:
[
{ text: 'Add'
},{ text: 'Change', cls: 'itemAction', disabled: true
},'-'
,{ text: 'Cut', cls: 'itemAction', disabled: true
},{ text: 'Copy', cls: 'itemAction', disabled: true
},'-'
,{ text: 'Delete', cls: 'itemAction', disabled: true
},
'->'
,{ text: 'Collapse Sections', action: 'collapse'
},{ text: 'Expand Sections', action: 'expand'
}
]
}
];

...
}

mitchellsimoens
9 Mar 2012, 12:24 PM
enableActions: function(grid) {
var buttons = grid.query('button[class=itemAction]'),
bLen = buttons.length,
b, button;

for (b = 0; b < bLen; b++) {
button = buttons[b];

button.enable();
}
}

Won't work?

DCstewieG
9 Mar 2012, 12:43 PM
Correct.



this.getGrid().query('button[cls=itemAction]')
this.getGrid().query('button[class=itemAction]')
this.getGrid().query('button[class]')
this.getGrid().query('button[cls]')
all return Array[0]



this.getGrid().query('button')
returns Array[7]

Using 4.0.7

mitchellsimoens
9 Mar 2012, 1:07 PM
Look at my code, I'm not using the getGrid method, the grid is passed as an argument.

DCstewieG
9 Mar 2012, 1:24 PM
Look at my code, I'm not using the getGrid method, the grid is passed as an argument.
Sorry, I thought you were just simplifiying the code at first glance. But no, that doesn't work either as the argument to a select event in a grid panel is a RowModel.

I'm attacking this in a new way now, saving the buttons I want to the controller in the onLaunch method using this.getGrid().query('button[disabled]'). Still curious about querying multiple components using classes or similar.

mitchellsimoens
9 Mar 2012, 1:43 PM
Ok, my way the first argument was actually the selection model. Try this complete example that is working for me:


Ext.define('Test.controller.Test', {
extend : 'Ext.app.Controller',

init : function() {
this.control({
'gridpanel' : {
select : this.enableActions
}
});
},

enableActions : function(selModel) {
var grid = selModel.view.up('gridpanel'),
btns = grid.query('button[cls=itemAction]'),
bLen = btns.length,
b, btn;

for (b = 0; b < bLen; b++) {
btn = btns[b];

btn.enable();
}
}
});

Ext.application({
name : 'Test',

controllers : [ 'Test' ],

launch : function() {

new Ext.grid.Panel({
renderTo : document.body,
width : 600,
height : 400,
store : new Ext.data.Store({
fields : ['name'],
data : [
{ name : 'Mitchell' },
{ name : 'Arthur' }
]
}),
dockedItems : [
{
xtype: 'toolbar',
dock: 'top',
items: [
{ text: 'Add'},
{ text: 'Change', cls: 'itemAction', disabled: true},
'-',
{ text: 'Cut', cls: 'itemAction', disabled: true},
{ text: 'Copy', cls: 'itemAction', disabled: true},
'-',
{ text: 'Delete', cls: 'itemAction', disabled: true},
'->',
{ text: 'Collapse Sections', action: 'collapse'},
{ text: 'Expand Sections', action: 'expand'}
]
}
],
columns : [
{
header : 'Name',
dataIndex : 'name',
flex : 1
}
]
});

}
});

DCstewieG
9 Mar 2012, 2:22 PM
Well maybe we're getting closer to the root of this, because that isn't working for me! Pasted your code into my app.js with nothing else and the grid displays but clicking a row doesn't enable the buttons. Same thing where btns equals Array[0]. Tried with 4.0.7, 4.0, and 4.1pr1 in IE, Firefox, and Chrome.

:-/

mitchellsimoens
9 Mar 2012, 2:31 PM
This is working for me in 4.0.7:


Ext.define('Test.controller.Test', {
extend : 'Ext.app.Controller',

init : function() {
this.control({
'gridpanel' : {
select : this.enableActions
}
});
},

enableActions : function(selModel) {
var grid = selModel.view.up('gridpanel'),
btns = grid.query('button[action=itemAction]'),
bLen = btns.length,
b, btn;

for (b = 0; b < bLen; b++) {
btn = btns[b];

btn.enable();
}
}
});

Ext.application({
name : 'Test',

controllers : [ 'Test' ],

launch : function() {

new Ext.grid.Panel({
renderTo : document.body,
width : 600,
height : 400,
store : new Ext.data.Store({
fields : ['name'],
data : [
{ name : 'Mitchell' },
{ name : 'Arthur' }
]
}),
dockedItems : [
{
xtype: 'toolbar',
dock: 'top',
items: [
{ text: 'Add'},
{ text: 'Change', action : 'itemAction', cls: 'itemAction', disabled: true},
'-',
{ text: 'Cut', action : 'itemAction', cls: 'itemAction', disabled: true},
{ text: 'Copy', action : 'itemAction', cls: 'itemAction', disabled: true},
'-',
{ text: 'Delete', action : 'itemAction', cls: 'itemAction', disabled: true},
'->',
{ text: 'Collapse Sections', action: 'collapse'},
{ text: 'Expand Sections', action: 'expand'}
]
}
],
columns : [
{
header : 'Name',
dataIndex : 'name',
flex : 1
}
]
});

}
});

The cls is not a property so moved to using action.

DCstewieG
9 Mar 2012, 3:26 PM
Ok, well yes, now that works. But I need to put real actions on those buttons at some point (we've standardized on using the action property to hook up events in the controller). So is there a property that can be used simply for querying components that won't get in the way of anything else, the way classes are used in jQuery? Sorry, I'm not trying to make things over-complicated, just genuinely curious. Still learning the Ext ropes and want to establish the best patterns.


I assume you mean the ability to chain methods... and you're right, ExtJS doesn't do that quite the way you're looking for. That's not necessarily a bad thing - just a difference in the approach.
No, not a bad thing. Actually I was asking for an imaginary jQuery feature that I thought existed :">. I was thinking you could do $('button').disable() to disable multiple buttons but no, you can't. Well, not without a plugin anyway ;)

mitchellsimoens
9 Mar 2012, 3:35 PM
You don't have to use action... you can use something else, action is a custom property.

DCstewieG
9 Mar 2012, 3:47 PM
Oh geez, well there's my answer, I didn't know it could use absolutely anything! Didn't even realize action was custom, just tried it without looking at the API and thought I guessed right when it worked. Thanks a lot.