/* * * (c) Copyright Ascensio System Limited 2010-2018 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, * EU, LV-1021. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ /** * Button.js * * Created by Alexander Yuzhin on 1/20/14 * Copyright (c) 2018 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'; var templateBtnIcon = '<% if ( iconImg ) { %>' + '' + '<% } else { %>' + '<% if (/svgicon/.test(iconCls)) {' + 'print(\'\');' + '} else ' + 'print(\' \'); %>' + '<% } %>'; var templateHugeCaption = ''; var templateHugeMenuCaption = '
' + '' + '
'; var templateHugeSplitCaption = '
' + '' + '' + '
'; 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, visible : true }, template: _.template([ '<% var applyicon = function() { %>', '<% if (iconImg) { print(\'\'); } else { %>', // '<% if (iconCls != "") { print(\' \'); }} %>', '<% if (iconCls != "") { ' + ' if (/svgicon/.test(iconCls)) {' + 'print(\'\');' + '} else ' + 'print(\' \'); ' + '}} %>', '<% } %>', '<% if ( !menu ) { %>', '', '<% } 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.visible = me.options.visible; 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) { if ( /icon-top/.test(me.cls) && !!me.caption && /huge/.test(me.cls) ) { if ( me.split === true ) { !!me.cls && (me.cls = me.cls.replace(/\s?(?:x-huge|icon-top)/g, '')); this.template = _.template(templateHugeSplitCaption); } else if ( !!me.menu ) { this.template = _.template(templateHugeMenuCaption); } else { this.template = _.template(templateHugeCaption); } } me.cmpEl = $(this.template({ id : me.id, cls : me.cls, iconCls : me.iconCls, iconImg : me.options.iconImg, menu : me.menu, split : me.split, disabled : me.disabled, pressed : me.pressed, caption : me.caption, style : me.style })); if (me.menu && _.isObject(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'); if (typeof me.options.hint == 'object' && me.options.hint.length>1 && $('button', el).length>0) { var btnEl = $('button', el); me.btnEl = $(btnEl[0]); me.btnMenuEl = $(btnEl[1]); } else { me.btnEl = me.cmpEl; me.btnEl.attr('data-toggle', 'tooltip'); } me.btnEl.tooltip({ title : (typeof me.options.hint == 'string') ? me.options.hint : me.options.hint[0], placement : me.options.hintAnchor||'cursor' }); me.btnMenuEl && me.btnMenuEl.tooltip({ title : me.options.hint[1], placement : me.options.hintAnchor||'cursor' }); if (modalParents.length > 0) { me.btnEl.data('bs.tooltip').tip().css('z-index', parseInt(modalParents.css('z-index')) + 10); me.btnMenuEl && me.btnMenuEl.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.btnEl.data('bs.tooltip'); if (tip) { if (tip.dontShow===undefined) tip.dontShow = true; tip.hide(); } } me.trigger('click', me, e); } }; var doSplitSelect = function(select, element, e) { if (!select) { // Is mouse under button var isUnderMouse = false; $('button', el).each(function(index, button){ if ($(button).is(':hover')) { isUnderMouse = true; return false; } }); if (!isUnderMouse) { el.removeClass('over'); $('button', el).removeClass('over'); } } if ( element == 'button') { 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); } else $('[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.btnMenuEl ? me.btnMenuEl : me.btnEl).data('bs.tooltip'); if (tip) { if (tip.dontShow===undefined) tip.dontShow = true; tip.hide(); } } var isOpen = el.hasClass('open'); doSplitSelect(!isOpen, 'arrow', e); } } }; var doSetActiveState = function(e, state) { if (isSplit) { doSplitSelect(state, 'button', e); } else { el.toggleClass('active', state); $('button', el).toggleClass('active', state); } }; var splitElement; var onMouseDown = function (e) { splitElement = e.currentTarget.className.match(/dropdown/) ? 'arrow' : 'button'; doSplitSelect(true, splitElement, e); $(document).on('mouseup', onMouseUp); }; var onMouseUp = function (e) { doSplitSelect(false, splitElement, e); $(document).off('mouseup', onMouseUp); }; var onAfterHideMenu = function(e, isFromInputControl) { 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, 'arrow')); el.on('show.bs.dropdown', _.bind(doSplitSelect, me, true, 'arrow')); 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=false)); } if (!me.visible) { me.setVisible(me.visible); } 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 && this.disabled != disabled) { var el = this.cmpEl, isGroup = el.hasClass('btn-group'), me = this; disabled = (disabled===true); if (disabled !== el.hasClass('disabled')) { var decorateBtn = function(button) { button.toggleClass('disabled', disabled); if (!me.options.allowMouseEventsOnDisabled) (disabled) ? button.attr({disabled: disabled}) : button.removeAttr('disabled'); }; decorateBtn(el); isGroup && decorateBtn(el.children('button')); } if ((disabled || !Common.Utils.isGecko) && this.options.hint) { var tip = this.btnEl.data('bs.tooltip'); if (tip) { disabled && tip.hide(); !Common.Utils.isGecko && (tip.enabled = !disabled); } if (this.btnMenuEl) { tip = this.btnMenuEl.data('bs.tooltip'); if (tip) { disabled && tip.hide(); !Common.Utils.isGecko && (tip.enabled = !disabled); } } } } this.disabled = disabled; }, isDisabled: function() { return this.disabled; }, setIconCls: function(cls) { var btnIconEl = $(this.el).find('.icon'), oldCls = this.iconCls; this.iconCls = cls; btnIconEl.removeClass(oldCls); btnIconEl.addClass(cls || ''); }, setVisible: function(visible) { if (this.cmpEl) this.cmpEl.toggleClass('hidden', !visible); this.visible = visible; }, isVisible: function() { return (this.cmpEl) ? this.cmpEl.is(":visible") : $(this.el).is(":visible"); }, updateHint: function(hint) { this.options.hint = hint; if (!this.rendered) return; var cmpEl = this.cmpEl, modalParents = cmpEl.closest('.asc-window'); if (!this.btnEl) { if (typeof this.options.hint == 'object' && this.options.hint.length>1 && $('button', cmpEl).length>0) { var btnEl = $('button', cmpEl); this.btnEl = $(btnEl[0]); this.btnMenuEl = $(btnEl[1]); } else { this.btnEl = cmpEl; this.btnEl.attr('data-toggle', 'tooltip'); } } if (this.btnEl.data('bs.tooltip')) this.btnEl.removeData('bs.tooltip'); if (this.btnMenuEl && this.btnMenuEl.data('bs.tooltip')) this.btnMenuEl.removeData('bs.tooltip'); this.btnEl.tooltip({ title : (typeof hint == 'string') ? hint : hint[0], placement : this.options.hintAnchor||'cursor' }); this.btnMenuEl && this.btnMenuEl.tooltip({ title : hint[1], placement : this.options.hintAnchor||'cursor' }); if (modalParents.length > 0) { this.btnEl.data('bs.tooltip').tip().css('z-index', parseInt(modalParents.css('z-index')) + 10); this.btnMenuEl && this.btnMenuEl.data('bs.tooltip').tip().css('z-index', parseInt(modalParents.css('z-index')) + 10); } if (this.disabled || !Common.Utils.isGecko) { var tip = this.btnEl.data('bs.tooltip'); if (tip) { this.disabled && tip.hide(); !Common.Utils.isGecko && (tip.enabled = !this.disabled); } if (this.btnMenuEl) { tip = this.btnMenuEl.data('bs.tooltip'); if (tip) { this.disabled && tip.hide(); !Common.Utils.isGecko && (tip.enabled = !this.disabled); } } } }, setCaption: function(caption) { if (this.caption != caption) { this.caption = caption; if (this.rendered) { var captionNode = this.cmpEl.find('button:first > .caption').addBack().filter('button > .caption'); if (captionNode.length > 0) { captionNode.text(caption); } else { this.cmpEl.find('button:first').addBack().filter('button').text(caption); } } } }, setMenu: function (m) { if (m && _.isObject(m) && _.isFunction(m.render)){ this.menu = m; if (this.rendered) this.menu.render(this.cmpEl); } } }); });