/** * Button.js * * Created by Alexander Yuzhin on 1/20/14 * Copyright (c) 2014 Ascensio System SIA. All rights reserved. * */ /** * Using template * * A simple button with text: * * * A simple button with icon: * * * A button with menu: *
* * *
* * A split button: *
* * * *
* * A useful classes of button size * * - `'small'` * - `'normal'` * - `'large'` * - `'huge'` * * A useful classes of button type * * - `'default'` * - `'active'` * * * Buttons can also be toggled. To enable this, you simple set the {@link #enableToggle} property to `true`. * * Example usage: * new Common.UI.Button({ * el: $('#id'), * enableToggle: true * }); * * * @property {Boolean} disabled * True if this button is disabled. Read-only. * * disabled: false, * * * @property {Boolean} pressed * True if this button is pressed (only if enableToggle = true). Read-only. * * pressed: false, * * * @cfg {Boolean} [allowDepress=true] * False to not allow a pressed Button to be depressed. Only valid when {@link #enableToggle} is true. * * @cfg {String/Object} hint * The tooltip for the button - can be a string to be used as bootstrap tooltip * */ if (Common === undefined) var Common = {}; define([ 'common/main/lib/component/BaseView', 'common/main/lib/component/ToggleManager' ], function () { 'use strict'; Common.UI.Button = Common.UI.BaseView.extend({ options : { id : null, hint : false, enableToggle : false, allowDepress : true, toggleGroup : null, cls : '', iconCls : '', caption : '', menu : null, disabled : false, pressed : false, split : false }, template: _.template([ '<% if (menu == null) { %>', '', '<% } else if (split == false) {%>', '
', '', '
', '<% } else { %>', '
', '', '', '
', '<% } %>' ].join('')), initialize : function(options) { Common.UI.BaseView.prototype.initialize.call(this, options); var me = this; me.id = me.options.id || Common.UI.getId(); me.hint = me.options.hint; me.enableToggle = me.options.enableToggle; me.allowDepress = me.options.allowDepress; me.cls = me.options.cls; me.iconCls = me.options.iconCls; me.menu = me.options.menu; me.split = me.options.split; me.toggleGroup = me.options.toggleGroup; me.disabled = me.options.disabled; me.pressed = me.options.pressed; me.caption = me.options.caption; me.template = me.options.template || me.template; me.style = me.options.style; me.rendered = false; if (me.options.el) { me.render(); } }, render: function(parentEl) { var me = this; me.trigger('render:before', me); me.cmpEl = $(me.el); if (parentEl) { me.setElement(parentEl, false); if (!me.rendered) { me.cmpEl = $(this.template({ id : me.id, cls : me.cls, iconCls : me.iconCls, menu : me.menu, split : me.split, disabled : me.disabled, pressed : me.pressed, caption : me.caption, style : me.style })); if (me.menu && _.isFunction(me.menu.render)) me.menu.render(me.cmpEl); parentEl.html(me.cmpEl); } } if (!me.rendered) { var el = me.cmpEl, isGroup = el.hasClass('btn-group'), isSplit = el.hasClass('split'); if (me.options.hint) { var modalParents = me.cmpEl.closest('.asc-window'); me.cmpEl.attr('data-toggle', 'tooltip'); me.cmpEl.tooltip({ title : me.options.hint, placement : me.options.hintAnchor||'cursor' }); if (modalParents.length > 0) { me.cmpEl.data('bs.tooltip').tip().css('z-index', parseInt(modalParents.css('z-index')) + 10); } } if (_.isString(me.toggleGroup)) { me.enableToggle = true; } var buttonHandler = function(e) { if (!me.disabled && e.which == 1) { me.doToggle(); if (me.options.hint) { var tip = me.cmpEl.data('bs.tooltip'); if (tip) { if (tip.dontShow===undefined) tip.dontShow = true; tip.hide(); } } me.trigger('click', me, e); } }; var doSplitSelect = function(select, e) { if (!select) { // Is mouse under button var isUnderMouse = false; _.each($('button', el), function(el){ if ($(el).is(':hover')) { isUnderMouse = true; return false; } }); if (!isUnderMouse) { el.removeClass('over'); $('button', el).removeClass('over'); } } if (!select && (me.enableToggle && me.allowDepress && me.pressed)) return; if (select && !isSplit && (me.enableToggle && me.allowDepress && !me.pressed)) { // to depress button with menu e.preventDefault(); return; } $('button:first', el).toggleClass('active', select); $('[data-toggle^=dropdown]', el).toggleClass('active', select); el.toggleClass('active', select); }; var menuHandler = function(e) { if (!me.disabled && e.which == 1) { if (isSplit) { if (me.options.hint) { var tip = me.cmpEl.data('bs.tooltip'); if (tip) { if (tip.dontShow===undefined) tip.dontShow = true; tip.hide(); } } var isOpen = el.hasClass('open'); doSplitSelect(!isOpen, e); } } }; var doSetActiveState = function(e, state) { if (isSplit) { doSplitSelect(state, e); } else { el.toggleClass('active', state); $('button', el).toggleClass('active', state); } }; var onMouseDown = function (e) { doSplitSelect(true, e); $(document).on('mouseup', onMouseUp); }; var onMouseUp = function (e) { doSplitSelect(false, e); $(document).off('mouseup', onMouseUp); }; var onAfterHideMenu = function(e) { me.cmpEl.find('.dropdown-toggle').blur(); if (me.cmpEl.hasClass('active') !== me.pressed) me.cmpEl.trigger('button.internal.active', [me.pressed]); }; if (isGroup) { if (isSplit) { $('[data-toggle^=dropdown]', el).on('mousedown', _.bind(menuHandler, this)); $('button', el).on('mousedown', _.bind(onMouseDown, this)); } el.on('hide.bs.dropdown', _.bind(doSplitSelect, me, false)); el.on('show.bs.dropdown', _.bind(doSplitSelect, me, true)); el.on('hidden.bs.dropdown', _.bind(onAfterHideMenu, me)); $('button:first', el).on('click', buttonHandler); } else { el.on('click', buttonHandler); } el.on('button.internal.active', _.bind(doSetActiveState, me)); el.on('mouseover', function(e) { if (!me.disabled) { me.cmpEl.addClass('over'); me.trigger('mouseover', me, e); } }); el.on('mouseout', function(e) { if (!me.disabled) { me.cmpEl.removeClass('over'); me.trigger('mouseout', me, e); } }); // Register the button in the toggle manager Common.UI.ToggleManager.register(me); } me.rendered = true; if (me.pressed) { me.toggle(me.pressed, true); } if (me.disabled) { me.setDisabled(me.disabled); } me.trigger('render:after', me); return this; }, doToggle: function(){ var me = this; if (me.enableToggle && (me.allowDepress !== false || !me.pressed)) { me.toggle(); } }, toggle: function(toggle, suppressEvent) { var state = toggle === undefined ? !this.pressed : !!toggle; this.pressed = state; if (this.cmpEl) this.cmpEl.trigger('button.internal.active', [state]); if (!suppressEvent) this.trigger('toggle', this, state); }, isActive: function() { if (this.enableToggle) return this.pressed; return this.cmpEl.hasClass('active') }, setDisabled: function(disabled) { if (this.rendered) { var el = this.cmpEl, isGroup = el.hasClass('btn-group'); disabled = (disabled===true); if (disabled !== el.hasClass('disabled')) { var decorateBtn = function(button) { button.toggleClass('disabled', disabled); (disabled) ? button.attr({disabled: disabled}) : button.removeAttr('disabled'); }; decorateBtn(el); isGroup && decorateBtn(el.children('button')); } if (disabled) { var tip = this.cmpEl.data('bs.tooltip'); if (tip) { tip.hide(); } } } this.disabled = disabled; }, isDisabled: function() { return this.disabled; }, setIconCls: function(cls) { var btnIconEl = $(this.el).find('span.btn-icon'), oldCls = this.iconCls; this.iconCls = cls; btnIconEl.removeClass(oldCls); btnIconEl.addClass(cls || ''); }, setVisible: function(visible) { if (this.cmpEl) this.cmpEl.toggleClass('hidden', !visible); }, updateHint: function(hint) { this.options.hint = hint; var cmpEl = this.cmpEl, modalParents = cmpEl.closest('.asc-window'); cmpEl.attr('data-toggle', 'tooltip'); cmpEl.tooltip('destroy').tooltip({ title : hint, placement : this.options.hintAnchor || 'cursor' }); if (modalParents.length > 0) { cmpEl.data('bs.tooltip').tip().css('z-index', parseInt(modalParents.css('z-index')) + 10); } }, setCaption: function(caption) { if (this.caption != caption) { this.caption = caption; if (this.rendered) { var captionNode = this.cmpEl.find('button:first > .caption').andSelf().filter('button > .caption'); if (captionNode.length > 0) { captionNode.text(caption); } else { this.cmpEl.find('button:first').andSelf().filter('button').text(caption); } } } } }); });