3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.menu.Item
17 * @extends Ext.Component
19 * A base class for all menu items that require menu-related functionality such as click handling,
20 * sub-menus, icons, etc.
22 * {@img Ext.menu.Menu/Ext.menu.Menu.png Ext.menu.Menu component}
26 * Ext.create('Ext.menu.Menu', {
29 * floating: false, // usually you want this set to True (default)
30 * renderTo: Ext.getBody(), // usually rendered by it's containing component
43 Ext.define('Ext.menu.Item', {
44 extend: 'Ext.Component',
45 alias: 'widget.menuitem',
46 alternateClassName: 'Ext.menu.TextItem',
49 * @property {Boolean} activated
50 * Whether or not this item is currently activated
54 * @cfg {String} activeCls
55 * The CSS class added to the menu item when the item is activated (focused/mouseover).
56 * Defaults to `Ext.baseCSSPrefix + 'menu-item-active'`.
59 activeCls: Ext.baseCSSPrefix + 'menu-item-active',
62 * @cfg {String} ariaRole @hide
67 * @cfg {Boolean} canActivate
68 * Whether or not this menu item can be activated when focused/mouseovered. Defaults to `true`.
74 * @cfg {Number} clickHideDelay
75 * The delay in milliseconds to wait before hiding the menu after clicking the menu item.
76 * This only has an effect when `hideOnClick: true`. Defaults to `1`.
82 * @cfg {Boolean} destroyMenu
83 * Whether or not to destroy any associated sub-menu when this item is destroyed. Defaults to `true`.
88 * @cfg {String} disabledCls
89 * The CSS class added to the menu item when the item is disabled.
90 * Defaults to `Ext.baseCSSPrefix + 'menu-item-disabled'`.
93 disabledCls: Ext.baseCSSPrefix + 'menu-item-disabled',
97 * The href attribute to use for the underlying anchor link. Defaults to `#`.
102 * @cfg {String} hrefTarget
103 * The target attribute to use for the underlying anchor link. Defaults to `undefined`.
108 * @cfg {Boolean} hideOnClick
109 * Whether to not to hide the owning menu when this item is clicked. Defaults to `true`.
116 * The path to an icon to display in this item. Defaults to `Ext.BLANK_IMAGE_URL`.
121 * @cfg {String} iconCls
122 * A CSS class that specifies a `background-image` to use as the icon for this item. Defaults to `undefined`.
130 * Either an instance of {@link Ext.menu.Menu} or a config object for an {@link Ext.menu.Menu}
131 * which will act as a sub-menu to this item.
133 * @property {Ext.menu.Menu} menu The sub-menu associated with this item, if one was configured.
137 * @cfg {String} menuAlign
138 * The default {@link Ext.core.Element#getAlignToXY Ext.Element.getAlignToXY} anchor position value for this
139 * item's sub-menu relative to this item's position. Defaults to `'tl-tr?'`.
145 * @cfg {Number} menuExpandDelay
146 * The delay in milliseconds before this item's sub-menu expands after this item is moused over. Defaults to `200`.
149 menuExpandDelay: 200,
152 * @cfg {Number} menuHideDelay
153 * The delay in milliseconds before this item's sub-menu hides after this item is moused out. Defaults to `200`.
159 * @cfg {Boolean} plain
160 * Whether or not this item is plain text/html with no icon or visual activation. Defaults to `false`.
169 '<a class="' + Ext.baseCSSPrefix + 'menu-item-link" href="{href}" <tpl if="hrefTarget">target="{hrefTarget}"</tpl> hidefocus="true" unselectable="on">',
170 '<img src="{icon}" class="' + Ext.baseCSSPrefix + 'menu-item-icon {iconCls}" />',
171 '<span class="' + Ext.baseCSSPrefix + 'menu-item-text" <tpl if="menu">style="margin-right: 17px;"</tpl> >{text}</span>',
173 '<img src="' + Ext.BLANK_IMAGE_URL + '" class="' + Ext.baseCSSPrefix + 'menu-item-arrow" />',
179 maskOnDisable: false,
183 * The text/html to display in this item. Defaults to `undefined`.
187 activate: function() {
190 if (!me.activated && me.canActivate && me.rendered && !me.isDisabled() && me.isVisible()) {
191 me.el.addCls(me.activeCls);
194 me.fireEvent('activate', me);
199 this.$focused = false;
200 this.callParent(arguments);
203 deactivate: function() {
207 me.el.removeCls(me.activeCls);
210 me.activated = false;
211 me.fireEvent('deactivate', me);
215 deferExpandMenu: function() {
218 if (!me.menu.rendered || !me.menu.isVisible()) {
219 me.parentMenu.activeChild = me.menu;
220 me.menu.parentItem = me;
221 me.menu.parentMenu = me.menu.ownerCt = me.parentMenu;
222 me.menu.showBy(me, me.menuAlign);
226 deferHideMenu: function() {
227 if (this.menu.isVisible()) {
232 deferHideParentMenus: function() {
233 Ext.menu.Manager.hideAll();
236 expandMenu: function(delay) {
240 clearTimeout(me.hideMenuTimer);
242 me.deferExpandMenu();
244 me.expandMenuTimer = Ext.defer(me.deferExpandMenu, Ext.isNumber(delay) ? delay : me.menuExpandDelay, me);
250 this.$focused = true;
251 this.callParent(arguments);
254 getRefItems: function(deep){
255 var menu = this.menu,
259 items = menu.getRefItems(deep);
265 hideMenu: function(delay) {
269 clearTimeout(me.expandMenuTimer);
270 me.hideMenuTimer = Ext.defer(me.deferHideMenu, Ext.isNumber(delay) ? delay : me.menuHideDelay, me);
274 initComponent: function() {
276 prefix = Ext.baseCSSPrefix,
277 cls = [prefix + 'menu-item'];
282 * Fires when this item is activated
283 * @param {Ext.menu.Item} item The activated item
289 * Fires when this item is clicked
290 * @param {Ext.menu.Item} item The item that was clicked
291 * @param {Ext.EventObject} e The underyling {@link Ext.EventObject}.
297 * Fires when this tiem is deactivated
298 * @param {Ext.menu.Item} item The deactivated item
304 cls.push(prefix + 'menu-item-plain');
311 me.cls = cls.join(' ');
314 me.menu = Ext.menu.Manager.get(me.menu);
317 me.callParent(arguments);
320 onClick: function(e) {
331 if (me.hideOnClick) {
332 me.deferHideParentMenusTimer = Ext.defer(me.deferHideParentMenus, me.clickHideDelay, me);
335 Ext.callback(me.handler, me.scope || me, [me, e]);
336 me.fireEvent('click', me, e);
338 if (!me.hideOnClick) {
343 onDestroy: function() {
346 clearTimeout(me.expandMenuTimer);
347 clearTimeout(me.hideMenuTimer);
348 clearTimeout(me.deferHideParentMenusTimer);
351 delete me.menu.parentItem;
352 delete me.menu.parentMenu;
353 delete me.menu.ownerCt;
354 if (me.destroyMenu !== false) {
358 me.callParent(arguments);
361 onRender: function(ct, pos) {
363 prefix = '.' + Ext.baseCSSPrefix;
365 Ext.applyIf(me.renderData, {
366 href: me.href || '#',
367 hrefTarget: me.hrefTarget,
368 icon: me.icon || Ext.BLANK_IMAGE_URL,
369 iconCls: me.iconCls + (me.checkChangeDisabled ? ' ' + me.disabledCls : ''),
370 menu: Ext.isDefined(me.menu),
375 Ext.applyIf(me.renderSelectors, {
376 itemEl: prefix + 'menu-item-link',
377 iconEl: prefix + 'menu-item-icon',
378 textEl: prefix + 'menu-item-text',
379 arrowEl: prefix + 'menu-item-arrow'
382 me.callParent(arguments);
386 * Sets the {@link #click} handler of this item
387 * @param {Function} fn The handler function
388 * @param {Object} scope (optional) The scope of the handler function
390 setHandler: function(fn, scope) {
391 this.handler = fn || null;
396 * Sets the {@link #iconCls} of this item
397 * @param {String} iconCls The CSS class to set to {@link #iconCls}
399 setIconCls: function(iconCls) {
404 me.iconEl.removeCls(me.iconCls);
408 me.iconEl.addCls(iconCls);
412 me.iconCls = iconCls;
416 * Sets the {@link #text} of this item
417 * @param {String} text The {@link #text}
419 setText: function(text) {
421 el = me.textEl || me.el;
426 el.update(text || '');
427 // cannot just call doComponentLayout due to stretchmax
428 me.ownerCt.redoComponentLayout();