/*global define: true */ /** * The multiSplit component groups multiple buttons and other * button-like items into an expandable menu. */ define([ 'jquery', 'ui/component', 'ui/button', 'ui/utils' ], function ( $, Component, Button, Utils ) { 'use strict'; /** * MultiSplit component type. * @class * @api * @extends {Component} */ var MultiSplit = Component.extend({ _activeButton: null, _isOpen: false, /** * @override */ init: function () { this._super(); var multiSplit = this; var element = this.element = $('
', { 'class': 'aloha-multisplit' }); var content = this.contentElement = $('
', { 'class': 'aloha-multisplit-content' }).appendTo(element); var toggle = this.toggleButton = Utils.makeButtonElement({ 'class': 'aloha-multisplit-toggle', click: function () { multiSplit.toggle(); } }).button().appendTo(element); this.buttons = []; var buttons = this.getButtons(); if (0 === buttons.length) { element.hide(); } for (var i = 0; i < buttons.length; i++) { this.addButton(buttons[i]); } $('body').click(function (event) { if (multiSplit._isOpen && !multiSplit.element.is(event.target) && 0 === multiSplit.element.find(event.target).length) { multiSplit.close(); } }); }, /** * Adds a button to this multisplit component. * * @param button * - name * The name of the button. * Used by setActiveButton(name), show(name), * hide(name) to identify the correct button. * * - tooltip * - icon * The tooltip and icon. * * - wide * A boolean indicating whether the button should * extend the entire width of the multi split button. * * - init * An optional init function. Will be invoked with the * button component instance as context. * * - click * A click handler for the button. * @api */ addButton: function (props) { var multiSplit = this; var component = new (Button.extend({ tooltip: props.tooltip, icon: props.wide ? props.icon : 'aloha-large-icon ' + props.icon, iconOnly: props.wide ? false : true, init: function () { this._super(); if (props.init) { props.init.call(this); } }, click: function () { props.click.apply(multiSplit, arguments); multiSplit.close(); } }))(); if (!props.wide) { component.element.addClass('aloha-large-button'); } multiSplit.buttons[props.name] = { settings: props, component: component, element: component.element, visible: true }; // Ensure non-wide buttons always come before wide buttons var fullwidthButtons = this.contentElement.children('.aloha-ui-multisplit-fullwidth'); if (!props.wide && fullwidthButtons.length) { fullwidthButtons.before(component.element[0]); } else { this.contentElement.append(component.element[0]); } }, /** * @api */ setActiveButton: function (name) { if (!name) { name = null; } if (null !== this._activeButton) { this.buttons[this._activeButton] .element.removeClass('aloha-multisplit-active'); } this._activeButton = name; if (null !== name) { this.buttons[name] .element.addClass('aloha-multisplit-active'); } }, /** * Toggles the multisplit menu * @api */ toggle: function () { this.element.toggleClass('aloha-multisplit-open'); this._isOpen = !this._isOpen; }, /** * Opens the multisplit menu * @api */ open: function () { this.element.addClass('aloha-multisplit-open'); this._isOpen = true; }, /** * Closes the multisplit menu * @api */ close: function () { this.element.removeClass('aloha-multisplit-open'); this._isOpen = false; }, /** * Show the button with given index * @api * @param {Number} index button index */ show: function (name) { if (!name) { name = null; } if (null !== name && this.buttons[name] !== undefined) { this.buttons[name].element.show(); this.buttons[name].visible = true; // since we show at least one button now, we need to show the multisplit button this.element.show(); } }, /** * Hide the button with given index * @api * @param {Number} index button index */ hide: function (name) { var button, visible = false; if (!name) { name = null; } if (null !== name && this.buttons[name] !== undefined) { this.buttons[name].element.hide(); this.buttons[name].visible = false; // now check, if there is a visible button for (button in this.buttons) { if (this.buttons.hasOwnProperty(button)) { if (this.buttons[button].visible) { this.element.show(); visible = true; break; } } } if (!visible) { this.element.hide(); } } } }); /** * This module is part of the Aloha API. * It is valid to override this module via requirejs to provide a * custom behaviour. An overriding module must implement all API * methods. Every member must have an api annotation. No non-api * members are allowed. * @api */ return MultiSplit; });