123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- "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 = $('<li role="presentation" class="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 = $('<li id="' + this._getItemId(item.name) + '">');
- var action = null;
- if (item.checked) {
- action = $('<a role="menuitem" href="#" aria-label="' + item.label + '" aria-checked="true" class="menuitem-toggled">' + item.label + '</a>');
- } else {
- action = $('<a role="menuitem" href="#" aria-label="' + item.label + '" aria-checked="false">' + item.label + '</a>');
- }
- 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 = $('<span class="' + this.icon + '"></span>');
- 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;
- });
|