/* * Ajax Popup plugin * * Documentation: ../docs/popup.md * * Require: * - bootstrap/modal */ +function ($) { "use strict"; var Base = $.wn.foundation.base, BaseProto = Base.prototype // POPUP CLASS DEFINITION // ============================ var Popup = function(element, options) { this.options = options this.$el = $(element) this.$container = null this.$modal = null this.$backdrop = null this.isOpen = false this.isLoading = false this.firstDiv = null this.allowHide = true this.$container = this.createPopupContainer() this.$content = this.$container.find('.modal-content:first') this.$dialog = this.$container.find('.modal-dialog:first') this.$modal = this.$container.modal({ show: false, backdrop: false, keyboard: this.options.keyboard }) $.wn.foundation.controlUtils.markDisposable(element) Base.call(this) this.initEvents() this.init() } Popup.prototype = Object.create(BaseProto) Popup.prototype.constructor = Popup Popup.DEFAULTS = { ajax: null, handler: null, keyboard: true, extraData: {}, content: null, size: null, adaptiveHeight: false, zIndex: null } Popup.prototype.init = function(){ var self = this /* * Do not allow the same popup to open twice */ if (self.isOpen) return /* * Show loading panel */ this.setBackdrop(true) if (!this.options.content) { this.setLoading(true) } /* * Winter AJAX */ if (this.options.handler) { this.$el.request(this.options.handler, { data: paramToObj('data-extra-data', this.options.extraData), success: function(data, textStatus, jqXHR) { this.success(data, textStatus, jqXHR).done(function(){ self.setContent(data.result) $(window).trigger('ajaxUpdateComplete', [this, data, textStatus, jqXHR]) self.triggerEvent('popupComplete') // Deprecated self.triggerEvent('complete.oc.popup') }) }, error: function(jqXHR, textStatus, errorThrown) { this.error(jqXHR, textStatus, errorThrown).done(function(){ if (self.isLoading) { self.hideLoading(); } else { self.hide() } self.triggerEvent('popupError') // Deprecated self.triggerEvent('error.oc.popup') }) } }) } /* * Regular AJAX */ else if (this.options.ajax) { $.ajax({ url: this.options.ajax, data: paramToObj('data-extra-data', this.options.extraData), success: function(data) { self.setContent(data) }, cache: false }) } /* * Specified content */ else if (this.options.content) { var content = typeof this.options.content == 'function' ? this.options.content.call(this.$el[0], this) : this.options.content this.setContent(content) } } Popup.prototype.initEvents = function(){ var self = this /* * Duplicate the popup reference on the .control-popup container */ this.$container.data('oc.popup', this) /* * Hook in to BS Modal events */ this.$modal.on('hide.bs.modal', function(){ self.triggerEvent('hide.oc.popup') self.isOpen = false self.setBackdrop(false) }) this.$modal.on('hidden.bs.modal', function(){ self.triggerEvent('hidden.oc.popup') $.wn.foundation.controlUtils.disposeControls(self.$container.get(0)) self.$container.remove() $(document.body).removeClass('modal-open') self.dispose() }) this.$modal.on('show.bs.modal', function(){ self.isOpen = true self.setBackdrop(true) $(document.body).addClass('modal-open') }) this.$modal.on('shown.bs.modal', function(){ self.triggerEvent('shown.oc.popup') }) this.$modal.on('close.oc.popup', function(){ self.hide() return false }) } Popup.prototype.dispose = function() { this.$modal.off('hide.bs.modal') this.$modal.off('hidden.bs.modal') this.$modal.off('show.bs.modal') this.$modal.off('shown.bs.modal') this.$modal.off('close.oc.popup') this.$el.off('dispose-control', this.proxy(this.dispose)) this.$el.removeData('oc.popup') this.$container.removeData('oc.popup') this.$container = null this.$content = null this.$dialog = null this.$modal = null this.$el = null // In some cases options could contain callbacks, // so it's better to clean them up too. this.options = null BaseProto.dispose.call(this) } Popup.prototype.createPopupContainer = function() { var modal = $('
').prop({ class: 'control-popup modal fade', role: 'dialog', tabindex: -1 }), modalDialog = $('
').addClass('modal-dialog'), modalContent = $('
').addClass('modal-content') if (this.options.size) modalDialog.addClass('size-' + this.options.size) if (this.options.adaptiveHeight) modalDialog.addClass('adaptive-height') if (this.options.zIndex !== null) modal.css('z-index', this.options.zIndex + 20) return modal.append(modalDialog.append(modalContent)) } Popup.prototype.setContent = function(contents) { this.$content.html(contents) this.setLoading(false) this.show() // Duplicate the popup object reference on to the first div // inside the popup. Eg: $('#firstDiv').popup('hide') this.firstDiv = this.$content.find('>div:first') if (this.firstDiv.length > 0) this.firstDiv.data('oc.popup', this) var $defaultFocus = $('[default-focus]', this.$content) if ($defaultFocus.is(":visible")) { window.setTimeout(function() { $defaultFocus.focus() $defaultFocus = null }, 300) } } Popup.prototype.setBackdrop = function(val) { if (val && !this.$backdrop) { this.$backdrop = $('