PDA

View Full Version : best way to handle clicks on a button menu?



gskluzacek
24 Feb 2010, 7:05 PM
complete beginner question here...

I have a button on a toolbar that has the menu config item set... I have 3 items in the menu and want to have a function called when one of the menu items is selected. I figured there are 2 approaches:

1) put a handler on each menu item

2) put a listener on the object that contains the objects and have it determine which menu item triggered the event.

While option 1 is the simpler method, if you have a lot of menu items you end up with many listeners. And in my case all the menu items do the same thing, but just use different values. For instance, what ever menu item is clicked it will set the button text to a value thats unique to that button. It will then set some parameters that will be used in a JSON datastore to refresh some data in a grid.

Am I on the right track going with option 2? Is it possible?

I've tried adding an on click listener on the button, but I can't figure out how to get at the menu item properties.

this is what I've tried


var menubtn = Ext.getCmp('serachbybtn').on("click", function(btn, evt) {
var target = Ext.fly(evt.getTarget()).down('button');
});


Thanks for the help
-- Greg

evant
24 Feb 2010, 7:10 PM
Menu items have handlers themselves:



var m = new Ext.menu.Menu({
items: {
text: 'Foo',
handler: function(){
console.log('Foo');
}
}
});
m.showAt([100, 100]);

gskluzacek
24 Feb 2010, 8:20 PM
OK, so are you saying that each menu should have its own handler? While that will work, all my menu items do the same thing... they read their btnText property (a custom property is set) and then set the text of the button the menu is configured to, to the value of the btnText property.


{
xtype: 'button',
text: 'Search Series by',
id: 'searchbybtn',
width: 125,
menu: [{
text: 'Contains',
checked: false,
group: 'searchby',
id: 'gsa-better-menu-item',
btntext: 'Series contains',
handler: function(menu_item, evt) {
var btn = Ext.getCmp('searchbybtn');
btn.setText(menu_item.btntext);
}
}, {
text: 'Starts With',
btntext: 'Series starts with',
checked: false,
group: 'searchby',
handler: function(menu_item, evt) {
var btn = Ext.getCmp('searchbybtn');
btn.setText(menu_item.btntext);
}
}, {
text: 'Exact Match',
btntext: 'Series equals',
checked: false,
group: 'searchby',
handler: function(menu_item, evt) {
var btn = Ext.getCmp('searchbybtn');
btn.setText(menu_item.btntext);
}
}]
}

See each handler has the exact same code... there must be a better way... I could factor out the 2 lines of code and put it into a function that each handler would call, but I would think there would be someplace to put a listener (like on the object that contains all the menu items) where the click on the menu item bubbles up and the one listener would implement the common code above.

evant
24 Feb 2010, 8:22 PM
Of course!



function fn(menu, item){
//do stuff
}

handler: fn

gskluzacek
26 Feb 2010, 7:24 AM
I tried using the handler: config item for my menu, didn't work (see below), so I looked up the Ext.menu.Menu in the API, there is no handler: config item for menu. :(


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Greg Test Page</title>
<link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css">
<style type="text/css">
<!--
.padded1 {
padding: 10px 10px 10px 10px;
}
.padded2 {
padding: 0px 10px 10px 10px;
}
.instructions {
font-family: Arial, Helvetica, sans-serif;
font-size: x-small;
padding: 4px;
}
-->
</style>
<script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext/ext-all-debug.js"></script>
<script type="text/javascript">
Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';

Ext.onReady(function() {
Ext.QuickTips.init();

console.log('woohoo!!!');

var topnav2 = new Ext.Panel({
renderTo: 'topnav2',
width: 600, height: 75,
tbar: {
items: [{
xtype: 'button',
text: 'Search Series by',
id: 'searchbybtn2',
width: 125,
menu: {
xtype: 'menu',
handler: set_button_text2,
items: [{
text: 'Contains',
btntext: 'Series contains',
checked: false,
group: 'searchby'
}, {
text: 'Starts With',
btntext: 'Series starts with',
checked: true,
group: 'searchby'
}, {
text: 'Exact Match',
btntext: 'Series equals',
checked: false,
group: 'searchby'
}]
}
}]
}

});

});

function set_button_text2(menu, menu_item) {
console.log('set_button_text2 was called');
var btn = Ext.getCmp('searchbybtn2');
btn.setText(menu_item.btntext);
}

</script>

</head>
<body>

<div id="topnav2" class="padded1"></div>

</body>
</html>

There is a listeners: config item, the API says:


listeners : Object
A config object containing one or more event handlers to be added to this object during initialization. This should be a valid listeners config object as specified in the addListener example for attaching multiple handlers at once.
...
Attaching multiple handlers in 1 call
The method also allows for a single argument to be passed which is a config object containing properties which specify multiple handlers.

myGridPanel.on({
'click' : {
fn: this.onClick,
scope: this,
delay: 100
},
'mouseover' : {
fn: this.onMouseOver,
scope: this
},
'mouseout' : {
fn: this.onMouseOut,
scope: this
}
});

so I got rid of the handler: config item and added the listeners: config item as follows:

var topnav2 = new Ext.Panel({
renderTo: 'topnav2',
width: 600, height: 75,
tbar: {
items: [{
xtype: 'button',
text: 'Search Series by',
id: 'searchbybtn2',
width: 125,
menu: {
xtype: 'menu',
handler: set_button_text2,
items: [{
text: 'Contains',
btntext: 'Series contains',
checked: false,
group: 'searchby'
}, {
text: 'Starts With',
btntext: 'Series starts with',
checked: true,
group: 'searchby'
}, {
text: 'Exact Match',
btntext: 'Series equals',
checked: false,
group: 'searchby'
}],
listeners: {
'click': {fn: set_button_text2}
}
}
}]
}

});

and it works now....

:-/I wonder why the handler: config item is not available for the Ext.menu.Menu class.

Thanks for your help :D
-- Greg