UNPKG

mikit-framework

Version:

A web framework for professional developers and designers alike.

295 lines (251 loc) 7.16 kB
/** * @library Mikit Modal * @author Mikit */ (function ($) { $.modalcurrent = null; $.modalwindow = function (options) { var opts = $.extend({}, options, { show: true }); var $element = $('<span />'); $element.modal(opts); }; })(jQuery); (function (Mikit) { Mikit.Modal = function (element, options) { this.namespace = 'modal'; this.defaults = { target: null, show: false, url: false, header: false, width: '600px', // string height: false, // or string maxHeight: false, position: 'center', // top or center overlay: true, appendForms: false, appendFields: false, animationOpen: 'show', animationClose: 'hide', callbacks: ['open', 'opened', 'close', 'closed'] }; // Parent Constructor Mikit.apply(this, arguments); // Services this.utils = new Mikit.Utils(); this.detect = new Mikit.Detect(); // Initialization this.start(); }; // Functionality Mikit.Modal.prototype = { start: function () { if (!this.hasTarget()) { return; } if (this.opts.show) this.load(); else this.$element.on('click.' + this.namespace, $.proxy(this.load, this)); }, buildModal: function () { this.$modal = this.$target.find('.mi-modal'); this.$header = this.$target.find('.mi-modal-header'); this.$close = this.$target.find('.mi-close'); this.$body = this.$target.find('.mi-modal-body'); }, buildOverlay: function () { if (this.opts.overlay === false) { return; } if ($('#mi-modal-overlay').length !== 0) { this.$overlay = $('#mi-modal-overlay'); } else { this.$overlay = $('<div id="mi-modal-overlay">').addClass('mi-hide'); $('body').prepend(this.$overlay); } this.$overlay.addClass('mi-overlay'); }, buildHeader: function () { if (this.opts.header) this.$header.html(this.opts.header); }, load: function (e) { this.buildModal(); this.buildOverlay(); this.buildHeader(); if (this.opts.url) this.buildContent(); else this.open(e); }, open: function (e) { if (e) e.preventDefault(); if (this.isOpened()) { return; } if (this.detect.isMobile()) this.opts.width = '96%'; if (this.opts.overlay) this.$overlay.removeClass('mi-hide'); this.$target.removeClass('mi-hide'); this.$modal.removeClass('mi-hide'); this.enableEvents(); this.findActions(); this.resize(); $(window).on('resize.' + this.namespace, $.proxy(this.resize, this)); if (this.detect.isDesktop()) this.utils.disableBodyScroll(); // enter this.$modal.find('input[type=text],input[type=url],input[type=email]').on('keydown.' + this.namespace, $.proxy(this.handleEnter, this)); this.callback('open'); this.$modal.animation(this.opts.animationOpen, $.proxy(this.onOpened, this)); }, close: function (e) { if (!this.$modal || !this.isOpened()) { return; } if (e) { if (this.shouldNotBeClosed(e.target)) { return; } e.preventDefault(); } this.callback('close'); this.disableEvents(); this.$modal.animation(this.opts.animationClose, $.proxy(this.onClosed, this)); if (this.opts.overlay) this.$overlay.animation(this.opts.animationClose); }, onOpened: function () { this.$modal.addClass('mi-open'); this.callback('opened'); $.modalcurrent = this; }, onClosed: function () { this.callback('closed'); this.$target.addClass('mi-hide'); this.$modal.removeClass('mi-open'); if (this.detect.isDesktop()) this.utils.enableBodyScroll(); this.$body.css('height', ''); $.modalcurrent = null; }, isOpened: function () { return (this.$modal.hasClass('mi-open')); }, getData: function () { var formdata = new Mikit.FormData(this); formdata.set(''); return formdata.get(); }, buildContent: function () { $.ajax({ url: this.opts.url + '?' + new Date().getTime(), cache: false, type: 'post', data: this.getData(), success: $.proxy(function (data) { this.$body.html(data); this.open(); }, this) }); }, buildWidth: function () { var width = this.opts.width; var top = '2%'; var bottom = '2%'; var percent = width.match(/%$/); if ((parseInt(this.opts.width) > $(window).width()) && !percent) { width = '96%'; } else if (!percent) { top = '16px'; bottom = '16px'; } this.$modal.css({ 'width': width, 'margin-top': top, 'margin-bottom': bottom }); }, buildPosition: function () { if (this.opts.position !== 'center') { return; } var windowHeight = $(window).height(); var height = this.$modal.outerHeight(); var top = (windowHeight / 2 - height / 2) + 'px'; if (this.detect.isMobile()) top = '2%'; else if (height > windowHeight) top = '16px'; this.$modal.css('margin-top', top); }, buildHeight: function () { var windowHeight = $(window).height(); if (this.opts.maxHeight) { var padding = parseInt(this.$body.css('padding-top')) + parseInt(this.$body.css('padding-bottom')); var margin = parseInt(this.$modal.css('margin-top')) + parseInt(this.$modal.css('margin-bottom')); var height = windowHeight - this.$header.innerHeight() - padding - margin; this.$body.height(height); } else if (this.opts.height !== false) { this.$body.css('height', this.opts.height); } var modalHeight = this.$modal.outerHeight(); if (modalHeight > windowHeight) { this.opts.animationOpen = 'show'; this.opts.animationClose = 'hide'; } }, resize: function () { this.buildWidth(); this.buildPosition(); this.buildHeight(); }, enableEvents: function () { this.$close.on('click.' + this.namespace, $.proxy(this.close, this)); $(document).on('keyup.' + this.namespace, $.proxy(this.handleEscape, this)); this.$target.on('click.' + this.namespace, $.proxy(this.close, this)); }, disableEvents: function () { this.$close.off('.' + this.namespace); $(document).off('.' + this.namespace); this.$target.off('.' + this.namespace); $(window).off('.' + this.namespace); }, findActions: function () { this.$body.find('[data-action="modal-close"]').on('mousedown.' + this.namespace, $.proxy(this.close, this)); }, setHeader: function (header) { this.$header.html(header); }, setContent: function (content) { this.$body.html(content); }, setWidth: function (width) { this.opts.width = width; this.resize(); }, getModal: function () { return this.$modal; }, getBody: function () { return this.$body; }, getHeader: function () { return this.$header; }, handleEnter: function (e) { if (e.which === 13) { e.preventDefault(); this.close(false); } }, handleEscape: function (e) { return (e.which === 27) ? this.close(false) : true; }, shouldNotBeClosed: function (el) { if ($(el).attr('data-action') === 'modal-close' || el === this.$close[0]) { return false; } else if ($(el).closest('.mi-modal').length === 0) { return false; } return true; } }; // Inheritance Mikit.Modal.inherits(Mikit); // Plugin Mikit.Plugin.create('Modal'); Mikit.Plugin.autoload('Modal'); }(Mikit));