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 * A base class for all menu items that require menu-related functionality such as click handling,
17 * sub-menus, icons, etc.
20 * Ext.create('Ext.menu.Menu', {
23 * floating: false, // usually you want this set to True (default)
24 * renderTo: Ext.getBody(), // usually rendered by it's containing component
36 Ext.define('Ext.menu.Item', {
37 extend: 'Ext.Component',
38 alias: 'widget.menuitem',
39 alternateClassName: 'Ext.menu.TextItem',
42 * @property {Boolean} activated
43 * Whether or not this item is currently activated
47 * @property {Ext.menu.Menu} parentMenu
48 * The parent Menu of this item.
52 * @cfg {String} activeCls
53 * The CSS class added to the menu item when the item is activated (focused/mouseover).
54 * Defaults to `Ext.baseCSSPrefix + 'menu-item-active'`.
56 activeCls: Ext.baseCSSPrefix + 'menu-item-active',
59 * @cfg {String} ariaRole @hide
64 * @cfg {Boolean} canActivate
65 * Whether or not this menu item can be activated when focused/mouseovered. Defaults to `true`.
70 * @cfg {Number} clickHideDelay
71 * The delay in milliseconds to wait before hiding the menu after clicking the menu item.
72 * This only has an effect when `hideOnClick: true`. Defaults to `1`.
77 * @cfg {Boolean} destroyMenu
78 * Whether or not to destroy any associated sub-menu when this item is destroyed. Defaults to `true`.
83 * @cfg {String} disabledCls
84 * The CSS class added to the menu item when the item is disabled.
85 * Defaults to `Ext.baseCSSPrefix + 'menu-item-disabled'`.
87 disabledCls: Ext.baseCSSPrefix + 'menu-item-disabled',
91 * The href attribute to use for the underlying anchor link. Defaults to `#`.
96 * @cfg {String} hrefTarget
97 * The target attribute to use for the underlying anchor link. Defaults to `undefined`.
102 * @cfg {Boolean} hideOnClick
103 * Whether to not to hide the owning menu when this item is clicked. Defaults to `true`.
110 * The path to an icon to display in this item. Defaults to `Ext.BLANK_IMAGE_URL`.
115 * @cfg {String} iconCls
116 * A CSS class that specifies a `background-image` to use as the icon for this item. Defaults to `undefined`.
124 * Either an instance of {@link Ext.menu.Menu} or a config object for an {@link Ext.menu.Menu}
125 * which will act as a sub-menu to this item.
127 * @property {Ext.menu.Menu} menu The sub-menu associated with this item, if one was configured.
131 * @cfg {String} menuAlign
132 * The default {@link Ext.Element#getAlignToXY Ext.Element.getAlignToXY} anchor position value for this
133 * item's sub-menu relative to this item's position. Defaults to `'tl-tr?'`.
139 * @cfg {Number} menuExpandDelay
140 * The delay in milliseconds before this item's sub-menu expands after this item is moused over. Defaults to `200`.
143 menuExpandDelay: 200,
146 * @cfg {Number} menuHideDelay
147 * The delay in milliseconds before this item's sub-menu hides after this item is moused out. Defaults to `200`.
153 * @cfg {Boolean} plain
154 * Whether or not this item is plain text/html with no icon or visual activation. Defaults to `false`.
163 '<a id="{id}-itemEl" class="' + Ext.baseCSSPrefix + 'menu-item-link" href="{href}" <tpl if="hrefTarget">target="{hrefTarget}"</tpl> hidefocus="true" unselectable="on">',
164 '<img id="{id}-iconEl" src="{icon}" class="' + Ext.baseCSSPrefix + 'menu-item-icon {iconCls}" />',
165 '<span id="{id}-textEl" class="' + Ext.baseCSSPrefix + 'menu-item-text" <tpl if="menu">style="margin-right: 17px;"</tpl> >{text}</span>',
167 '<img id="{id}-arrowEl" src="{blank}" class="' + Ext.baseCSSPrefix + 'menu-item-arrow" />',
173 maskOnDisable: false,
177 * The text/html to display in this item. Defaults to `undefined`.
181 activate: function() {
184 if (!me.activated && me.canActivate && me.rendered && !me.isDisabled() && me.isVisible()) {
185 me.el.addCls(me.activeCls);
188 me.fireEvent('activate', me);
193 this.$focused = false;
194 this.callParent(arguments);
197 deactivate: function() {
201 me.el.removeCls(me.activeCls);
204 me.activated = false;
205 me.fireEvent('deactivate', me);
209 deferExpandMenu: function() {
212 if (!me.menu.rendered || !me.menu.isVisible()) {
213 me.parentMenu.activeChild = me.menu;
214 me.menu.parentItem = me;
215 me.menu.parentMenu = me.menu.ownerCt = me.parentMenu;
216 me.menu.showBy(me, me.menuAlign);
220 deferHideMenu: function() {
221 if (this.menu.isVisible()) {
226 deferHideParentMenus: function() {
227 Ext.menu.Manager.hideAll();
230 expandMenu: function(delay) {
234 clearTimeout(me.hideMenuTimer);
236 me.deferExpandMenu();
238 me.expandMenuTimer = Ext.defer(me.deferExpandMenu, Ext.isNumber(delay) ? delay : me.menuExpandDelay, me);
244 this.$focused = true;
245 this.callParent(arguments);
248 getRefItems: function(deep){
249 var menu = this.menu,
253 items = menu.getRefItems(deep);
259 hideMenu: function(delay) {
263 clearTimeout(me.expandMenuTimer);
264 me.hideMenuTimer = Ext.defer(me.deferHideMenu, Ext.isNumber(delay) ? delay : me.menuHideDelay, me);
268 initComponent: function() {
270 prefix = Ext.baseCSSPrefix,
271 cls = [prefix + 'menu-item'];
276 * Fires when this item is activated
277 * @param {Ext.menu.Item} item The activated item
283 * Fires when this item is clicked
284 * @param {Ext.menu.Item} item The item that was clicked
285 * @param {Ext.EventObject} e The underyling {@link Ext.EventObject}.
291 * Fires when this tiem is deactivated
292 * @param {Ext.menu.Item} item The deactivated item
298 cls.push(prefix + 'menu-item-plain');
305 me.cls = cls.join(' ');
308 me.menu = Ext.menu.Manager.get(me.menu);
311 me.callParent(arguments);
314 onClick: function(e) {
325 if (me.hideOnClick) {
326 me.deferHideParentMenusTimer = Ext.defer(me.deferHideParentMenus, me.clickHideDelay, me);
329 Ext.callback(me.handler, me.scope || me, [me, e]);
330 me.fireEvent('click', me, e);
332 if (!me.hideOnClick) {
337 onDestroy: function() {
340 clearTimeout(me.expandMenuTimer);
341 clearTimeout(me.hideMenuTimer);
342 clearTimeout(me.deferHideParentMenusTimer);
345 delete me.menu.parentItem;
346 delete me.menu.parentMenu;
347 delete me.menu.ownerCt;
348 if (me.destroyMenu !== false) {
352 me.callParent(arguments);
355 onRender: function(ct, pos) {
357 blank = Ext.BLANK_IMAGE_URL;
359 Ext.applyIf(me.renderData, {
360 href: me.href || '#',
361 hrefTarget: me.hrefTarget,
362 icon: me.icon || blank,
363 iconCls: me.iconCls + (me.checkChangeDisabled ? ' ' + me.disabledCls : ''),
364 menu: Ext.isDefined(me.menu),
370 me.addChildEls('itemEl', 'iconEl', 'textEl', 'arrowEl');
372 me.callParent(arguments);
376 * Sets the {@link #click} handler of this item
377 * @param {Function} fn The handler function
378 * @param {Object} scope (optional) The scope of the handler function
380 setHandler: function(fn, scope) {
381 this.handler = fn || null;
386 * Sets the {@link #iconCls} of this item
387 * @param {String} iconCls The CSS class to set to {@link #iconCls}
389 setIconCls: function(iconCls) {
394 me.iconEl.removeCls(me.iconCls);
398 me.iconEl.addCls(iconCls);
402 me.iconCls = iconCls;
406 * Sets the {@link #text} of this item
407 * @param {String} text The {@link #text}
409 setText: function(text) {
411 el = me.textEl || me.el;
416 el.update(text || '');
417 // cannot just call doComponentLayout due to stretchmax
418 me.ownerCt.redoComponentLayout();