/** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ define([ 'jquery', 'jquery-ui-modules/dialog', 'mage/translate' ], function ($) { 'use strict'; var timer = null; /** * Dropdown Widget - this widget is a wrapper for the jQuery UI Dialog */ $.widget('mage.dropdownDialog', $.ui.dialog, { options: { triggerEvent: 'click', triggerClass: null, parentClass: null, triggerTarget: null, defaultDialogClass: 'mage-dropdown-dialog', dialogContentClass: null, shadowHinter: null, closeOnMouseLeave: true, closeOnClickOutside: true, minHeight: null, minWidth: null, width: null, modal: false, timeout: null, autoOpen: false, createTitleBar: false, autoPosition: false, autoSize: false, draggable: false, resizable: false, bodyClass: '', buttons: [ { 'class': 'action close', 'text': $.mage.__('Close'), /** * Click action. */ 'click': function () { $(this).dropdownDialog('close'); } } ] }, /** * extend default functionality to bind the opener for dropdown * @private */ _create: function () { var _self = this; this._super(); this.uiDialog.addClass(this.options.defaultDialogClass); if (_self.options.triggerTarget) { $(_self.options.triggerTarget).on(_self.options.triggerEvent, function (event) { event.preventDefault(); event.stopPropagation(); if (!_self._isOpen) { $('.' + _self.options.defaultDialogClass + ' > .ui-dialog-content').dropdownDialog('close'); _self.open(); } else { _self.close(event); } }); } if (_self.options.shadowHinter) { _self.hinter = $('
'); _self.element.append(_self.hinter); } }, /** * Extend default functionality to close the dropdown * with custom delay on mouse out and also to close when clicking outside */ open: function () { var _self = this; this._super(); if (_self.options.dialogContentClass) { _self.element.addClass(_self.options.dialogContentClass); } if (_self.options.closeOnMouseLeave) { this._mouseEnter(_self.uiDialog); this._mouseLeave(_self.uiDialog); if (_self.options.triggerTarget) { this._mouseLeave($(_self.options.triggerTarget)); } } if (_self.options.closeOnClickOutside) { $('body').on('click.outsideDropdown', function (event) { if (_self._isOpen && !$(event.target).closest('.ui-dialog').length) { if (timer) { clearTimeout(timer); } _self.close(event); } }); } // adding the class on the opener and parent element for dropdown if (_self.options.triggerClass) { $(_self.options.triggerTarget).addClass(_self.options.triggerClass); } if (_self.options.parentClass) { $(_self.options.appendTo).addClass(_self.options.parentClass); } if (_self.options.bodyClass) { $('body').addClass(_self.options.bodyClass); } if (_self.options.shadowHinter) { _self._setShadowHinterPosition(); } }, /** * extend default functionality to reset the timer and remove the active class for opener */ close: function () { this._super(); if (this.options.dialogContentClass) { this.element.removeClass(this.options.dialogContentClass); } if (this.options.triggerClass) { $(this.options.triggerTarget).removeClass(this.options.triggerClass); } if (this.options.parentClass) { $(this.options.appendTo).removeClass(this.options.parentClass); } if (this.options.bodyClass) { $('body').removeClass(this.options.bodyClass); } if (timer) { clearTimeout(timer); } if (this.options.triggerTarget) { $(this.options.triggerTarget).off('mouseleave'); } this.uiDialog.off('mouseenter'); this.uiDialog.off('mouseleave'); $('body').off('click.outsideDropdown'); }, /** * _setShadowHinterPosition * @private */ _setShadowHinterPosition: function () { var _self = this, offset; offset = _self.options.position.of.offset().left - _self.element.offset().left + _self.options.position.of.outerWidth() / 2; offset = isNaN(offset) ? 0 : Math.floor(offset); _self.hinter.css('left', offset); }, /** * @private */ _position: function () { if (this.options.autoPosition) { this._super(); } }, /** * @private */ _createTitlebar: function () { if (this.options.createTitleBar) { this._super(); } else { // the title bar close button is referenced // in _focusTabbable function, so to prevent errors it must be declared this.uiDialogTitlebarClose = $('
'); } }, /** * @private */ _size: function () { if (this.options.autoSize) { this._super(); } }, /** * @param {Object} handler * @private */ _mouseLeave: function (handler) { var _self = this; handler.on('mouseleave', function (event) { event.stopPropagation(); if (_self._isOpen) { if (timer) { clearTimeout(timer); } timer = setTimeout(function (e) { _self.close(e); }, _self.options.timeout); } }); }, /** * @param {Object} handler * @private */ _mouseEnter: function (handler) { handler.on('mouseenter', function (event) { event.stopPropagation(); if (timer) { clearTimeout(timer); } }); }, /** * @param {String} key * @param {*} value * @private */ _setOption: function (key, value) { this._super(key, value); if (key === 'triggerTarget') { this.options.triggerTarget = value; } } }); return $.mage.dropdownDialog; });