/* A simple jQuery modal (http://github.com/kylefox/jquery-modal) Version 0.9.2 */ (function (factory) { // Making your jQuery plugin work better with npm tools // http://blog.npmjs.org/post/112712169830/making-your-jquery-plugin-work-better-with-npm if (typeof module === "object" && typeof module.exports === "object") { factory(require("jquery"), window, document); } else { factory(jQuery, window, document); } }(function ($, window, document, undefined) { var modals = [], getCurrent = function () { return modals.length ? modals[modals.length - 1] : null; }, selectCurrent = function () { var i, selected = false; for (i=modals.length-1; i>=0; i--) { if (modals[i].$blocker) { modals[i].$blocker.toggleClass('current',!selected).toggleClass('behind',selected); selected = true; } } }; $.modal = function (el, options) { var remove, target; this.$body = $('body'); this.options = $.extend({}, $.modal.defaults, options); this.options.doFade = !isNaN(parseInt(this.options.fadeDuration, 10)); this.$blocker = null; if (this.options.closeExisting) { while ($.modal.isActive()) { $.modal.close(); // Close any open modals. } } modals.push(this); if (el.is('a')) { target = el.attr('href'); this.anchor = el; //Select element by id from href if (/^#/.test(target)) { this.$elm = $(target); if (this.$elm.length !== 1) { return null; } this.$body.append(this.$elm); this.open(); //AJAX } else { this.$elm = $('
'); this.$body.append(this.$elm); remove = function (event, modal) { modal.elm.remove(); }; this.showSpinner(); el.trigger($.modal.AJAX_SEND); $.get(target).done(function (html) { if (!$.modal.isActive()) { return; } el.trigger($.modal.AJAX_SUCCESS); var current = getCurrent(); current.$elm.empty().append(html).on($.modal.CLOSE, remove); current.hideSpinner(); current.open(); el.trigger($.modal.AJAX_COMPLETE); }).fail(function () { el.trigger($.modal.AJAX_FAIL); var current = getCurrent(); current.hideSpinner(); modals.pop(); // remove expected modal from the list el.trigger($.modal.AJAX_COMPLETE); }); } } else { this.$elm = el; this.anchor = el; this.$body.append(this.$elm); this.open(); } }; $.modal.prototype = { constructor: $.modal, open: function () { var m = this; this.block(); this.anchor.blur(); if (this.options.doFade) { setTimeout(function () { m.show(); }, this.options.fadeDuration * this.options.fadeDelay); } else { this.show(); } $(document).off('keydown.modal').on('keydown.modal', function (event) { var current = getCurrent(); if (event.which === 27 && current.options.escapeClose) { current.close(); } }); if (this.options.clickClose) { this.$blocker.click(function (e) { if (e.target === this) { $.modal.close(); } }); } }, close: function () { modals.pop(); this.unblock(); this.hide(); if (!$.modal.isActive()) { $(document).off('keydown.modal'); } }, block: function () { this.$elm.trigger($.modal.BEFORE_BLOCK, [this._ctx()]); this.$body.css('overflow','hidden'); this.$blocker = $('
').appendTo(this.$body); selectCurrent(); if (this.options.doFade) { this.$blocker.css('opacity',0).animate({opacity: 1}, this.options.fadeDuration); } this.$elm.trigger($.modal.BLOCK, [this._ctx()]); }, unblock: function (now) { if (!now && this.options.doFade) { this.$blocker.fadeOut(this.options.fadeDuration, this.unblock.bind(this,true)); } else { this.$blocker.children().appendTo(this.$body); this.$blocker.remove(); this.$blocker = null; selectCurrent(); if (!$.modal.isActive()) { this.$body.css('overflow',''); } } }, show: function () { this.$elm.trigger($.modal.BEFORE_OPEN, [this._ctx()]); if (this.options.showClose) { this.closeButton = $('' + this.options.closeText + ''); this.$elm.append(this.closeButton); } this.$elm.addClass(this.options.modalClass).appendTo(this.$blocker); if (this.options.doFade) { this.$elm.css({opacity: 0, display: 'inline-block'}).animate({opacity: 1}, this.options.fadeDuration); } else { this.$elm.css('display', 'inline-block'); } this.$elm.trigger($.modal.OPEN, [this._ctx()]); }, hide: function () { this.$elm.trigger($.modal.BEFORE_CLOSE, [this._ctx()]); if (this.closeButton) { this.closeButton.remove(); } var _this = this; if (this.options.doFade) { this.$elm.fadeOut(this.options.fadeDuration, function () { _this.$elm.trigger($.modal.AFTER_CLOSE, [_this._ctx()]); }); } else { this.$elm.hide(0, function () { _this.$elm.trigger($.modal.AFTER_CLOSE, [_this._ctx()]); }); } this.$elm.trigger($.modal.CLOSE, [this._ctx()]); }, showSpinner: function () { if (!this.options.showSpinner) { return; } this.spinner = this.spinner || $('
') .append(this.options.spinnerHtml); this.$body.append(this.spinner); this.spinner.show(); }, hideSpinner: function () { if (this.spinner) { this.spinner.remove(); } }, //Return context for custom events _ctx: function () { return { elm: this.$elm, $elm: this.$elm, $blocker: this.$blocker, options: this.options, $anchor: this.anchor }; } }; $.modal.close = function (event) { if (!$.modal.isActive()) { return; } if (event) { event.preventDefault(); } var current = getCurrent(); current.close(); return current.$elm; }; // Returns if there currently is an active modal $.modal.isActive = function () { return modals.length > 0; }; $.modal.getCurrent = getCurrent; $.modal.defaults = { closeExisting: true, escapeClose: true, clickClose: true, closeText: 'Close', closeClass: '', modalClass: "modal", blockerClass: "jquery-modal", spinnerHtml: '
', showSpinner: true, showClose: true, fadeDuration: null, // Number of milliseconds the fade animation takes. fadeDelay: 1.0 // Point during the overlay's fade-in that the modal begins to fade in (.5 = 50%, 1.5 = 150%, etc.) }; // Event constants $.modal.BEFORE_BLOCK = 'modal:before-block'; $.modal.BLOCK = 'modal:block'; $.modal.BEFORE_OPEN = 'modal:before-open'; $.modal.OPEN = 'modal:open'; $.modal.BEFORE_CLOSE = 'modal:before-close'; $.modal.CLOSE = 'modal:close'; $.modal.AFTER_CLOSE = 'modal:after-close'; $.modal.AJAX_SEND = 'modal:ajax:send'; $.modal.AJAX_SUCCESS = 'modal:ajax:success'; $.modal.AJAX_FAIL = 'modal:ajax:fail'; $.modal.AJAX_COMPLETE = 'modal:ajax:complete'; $.fn.modal = function (options) { if (this.length === 1) { new $.modal(this, options); } return this; }; // Automatically bind links with rel="modal:close" to, well, close the modal. $(document).on('click.modal', 'a[rel~="modal:close"]', $.modal.close); $(document).on('click.modal', 'a[rel~="modal:open"]', function (event) { event.preventDefault(); $(this).modal(); }); }));