268 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			268 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
| /**
 | |
|  * 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 = $('<div class="' + _self.options.shadowHinter + '"></div>');
 | |
|                 _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 = $('<div></div>');
 | |
|             }
 | |
|         },
 | |
| 
 | |
|         /**
 | |
|          * @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;
 | |
| });
 |