"use strict";
/**
* Licensed Materials - Property of IBM
* IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2017
* US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
define(['bi/commons/ui/View', 'jquery', 'underscore', 'bi/commons/utils/BidiUtil', 'text!../templates/Menu.html'], function (View, $, _, bidi, template) {
var MenuItem = null;
/**
* Represents a drop down menu that can be added to an app bar
*/
MenuItem = View.extend({
templateString: template,
events: {
'keydown': '_handleKeyboard',
'click .dropdown-menuitem': '_handleClick'
},
itemActions: null,
itemSpecMap: null,
baseClass: 'toolbar',
hcLabel: null,
// create an element for high contrast label
showTitle: true,
/**
* Creates a new menu item
*
* @param spec -
* The menu item spec
* @param root -
* A reference to the root menu item, where items go if the app bar is collapsed horizontally
*/
init: function init(spec) {
_.defaults(spec, {
hcLabel: true
});
_.extend(this, spec);
this.itemActions = {};
this.itemSpecMap = {};
_.each(this.items, function (item) {
this.itemSpecMap[item.name] = item;
}.bind(this));
MenuItem.inherited('init', this, arguments);
},
_handleClick: function _handleClick(event) {
event.preventDefault();
this._performAction(event.currentTarget.id);
},
_performAction: function _performAction(id) {
var action = this.itemActions[id];
if (action) {
// Delay the action slightly to allow bootstrap to close the menu before
// the action is fired
setTimeout(function () {
action();
}, 10);
}
},
/**
* Removes a menu item
*/
removeItem: function removeItem(name) {
var id = this.viewId + '_' + name;
this.$menu.children('#' + id).remove();
delete this.itemSpecMap[name];
delete this.itemActions[id];
},
addDivider: function addDivider() {
var divider = $('
');
this.$menu.append(divider);
return divider;
},
/**
* Adds a new menu item to the drop down
*/
addItem: function addItem(item) {
this.itemSpecMap[item.name] = item;
var menuItem = $('');
var action = null;
if (item.checked) {
action = $('');
} else {
action = $('' + item.label + '');
}
menuItem.append(action);
menuItem.addClass('dropdown-menuitem');
menuItem.addClass(item.name);
this.$menu.append(menuItem);
this._buildMenuItem(item);
return menuItem;
},
showItem: function showItem(name) {
this.$menu.find('.' + name).removeClass('hidden');
},
hideItem: function hideItem(name) {
this.$menu.find('.' + name).addClass('hidden');
},
/*jshint maxcomplexity:13 */
_handleKeyboard: function _handleKeyboard(e) {
var keyCode = e.which || e.keyCode || e.charCode;
var $target = $(e.target);
var $nextFocus;
switch (keyCode) {
case 9:
//tabkey
if (e.shiftKey) {
if ($target.hasClass('firstMenuItem')) {
$nextFocus = $target.closest('ul').find('a.lastMenuItem');
$nextFocus.focus();
e.preventDefault();
}
} else {
if ($target.hasClass('lastMenuItem')) {
$nextFocus = $target.closest('ul').find('a.firstMenuItem');
$nextFocus.focus();
e.preventDefault();
}
}
break;
case 13: // enter key
case 32:
// space
e.preventDefault();
this.$toggle.dropdown('toggle');
if ($(e.target).hasClass('dropdown-toggle')) {
var first = this.$el.find('.dropdown-menu a').first();
first.focus();
} else {
var currentItem = this.getTarget(e.target, 'dropdown-menuitem');
this._performAction(currentItem.id);
}
break;
case 37: // left arrow
case 39:
// right arrow
if ($(e.target.parentNode).hasClass('dropdown-menuitem')) {
var downKeyEvt = _.clone(e);
downKeyEvt.keyCode = keyCode + 1; // left to up arrow: 38, right to down arrow:40;
$(e.target).trigger(downKeyEvt); // delegate to bootstrap
}
break;
default:
break;
}
},
_templateParams: function _templateParams() {
return {
id: this.viewId,
items: this.items,
label: this.label,
icon: this.icon,
hcLabel: this.hcLabel,
baseClass: this.baseClass,
labelOnly: this.labelOnly,
showTitle: this.showTitle
};
},
/**
* Draws the MenuItem
*/
render: function render() {
var sHtml = this.dotTemplate(this._templateParams());
this.$el.append(sHtml);
this.$el.addClass(this.baseClass + 'ItemWrapper');
this.$el.addClass('dropdown');
this.$toggle = this.$el.children('.dropdown-toggle');
this.$toggle.addClass(this.baseClass + 'Icon');
this.$iconImage = $('');
if (this.icon) {
this.$toggle.prepend(this.$iconImage);
}
this.$toggle.attr('title', this.label);
this.$toggle.addClass(this.baseClass + 'Item');
this.$menu = this.$el.children('.dropdown-menu');
if (this.trailing) {
this.$menu.addClass('dropdown-menu-right');
}
var promise = this._buildDropDown();
this.$menuLabel = this.$el.find('.menu-label');
return promise;
},
_buildDropDown: function _buildDropDown() {
var deferred = $.Deferred();
require(['bsdropdown'], function () {
this.$toggle.dropdown();
/**
* A callback can be passed to opening behavior
*/
if (this.action) {
this.$el.on('show.bs.dropdown', this.action.bind(this));
}
this._buildMenuItems();
deferred.resolve(this.$el);
}.bind(this));
return deferred.promise();
},
_buildMenuItems: function _buildMenuItems() {
_.each(this.items, function (item) {
this._buildMenuItem(item);
}.bind(this));
},
_getItemId: function _getItemId(name) {
return this.viewId + '_' + name;
},
_buildMenuItem: function _buildMenuItem(item) {
var itemID = this._getItemId(item.name);
this.itemActions[itemID] = item.action;
var itemNode = $('#' + itemID);
var elem = itemNode.get(0);
if (elem) {
bidi.initElementForBidi(elem);
}
}
});
return MenuItem;
});