2014-05-14 23:24:20 +10:00
|
|
|
/*
|
|
|
|
* Ajax Popup plugin
|
2014-08-20 15:37:10 +10:00
|
|
|
*
|
2014-11-07 19:39:13 +11:00
|
|
|
* Options:
|
|
|
|
* - content: content HTML string or callback
|
|
|
|
*
|
2014-05-14 23:24:20 +10:00
|
|
|
* Data attributes:
|
|
|
|
* - data-control="popup" - enables the ajax popup plugin
|
|
|
|
* - data-ajax="popup-content.htm" - ajax content to load
|
|
|
|
* - data-handler="widget:pluginName" - October ajax request name
|
|
|
|
* - data-keyboard="false" - Allow popup to be closed with the keyboard
|
|
|
|
* - data-request-data="file_id: 1" - October ajax request data
|
|
|
|
*
|
|
|
|
* JavaScript API:
|
|
|
|
* $('a#someLink').popup({ ajax: 'popup-content.htm' })
|
|
|
|
* $('a#someLink').popup({ handler: 'onOpenPopupForm' })
|
|
|
|
*
|
|
|
|
* Dependences:
|
|
|
|
* - Bootstrap Modal (modal.js)
|
|
|
|
*/
|
|
|
|
|
|
|
|
+function ($) { "use strict";
|
|
|
|
|
|
|
|
// POPUP CLASS DEFINITION
|
|
|
|
// ============================
|
|
|
|
|
|
|
|
var Popup = function(element, options) {
|
|
|
|
var self = this
|
2014-11-07 19:39:13 +11:00
|
|
|
this.options = options
|
|
|
|
this.$el = $(element)
|
|
|
|
this.$container = null
|
|
|
|
this.$modal = null
|
|
|
|
this.$backdrop = null
|
|
|
|
this.isOpen = false
|
|
|
|
this.firstDiv = null
|
|
|
|
this.allowHide = true
|
|
|
|
|
|
|
|
this.$container = this.createPopupContainer()
|
|
|
|
this.$content = this.$container.find('.modal-content:first')
|
|
|
|
this.$modal = this.$container.modal({ show: false, backdrop: false, keyboard: this.options.keyboard })
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-07-17 18:42:12 +10:00
|
|
|
/*
|
|
|
|
* Duplicate the popup reference on the .control-popup container
|
|
|
|
*/
|
2014-11-07 19:39:13 +11:00
|
|
|
this.$container.data('oc.popup', this)
|
2014-07-17 18:42:12 +10:00
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
/*
|
|
|
|
* Hook in to BS Modal events
|
|
|
|
*/
|
|
|
|
this.$modal.on('hide.bs.modal', function(){
|
|
|
|
self.isOpen = false
|
|
|
|
self.setBackdrop(false)
|
2014-11-07 19:39:13 +11:00
|
|
|
})
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-11-07 19:39:13 +11:00
|
|
|
this.$modal.on('hidden.bs.modal', function(){
|
|
|
|
self.$container.remove()
|
|
|
|
self.$el.data('oc.popup', null)
|
2014-05-14 23:24:20 +10:00
|
|
|
})
|
2014-07-17 18:42:12 +10:00
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
this.$modal.on('show.bs.modal', function(){
|
|
|
|
self.isOpen = true
|
|
|
|
self.setBackdrop(true)
|
|
|
|
})
|
|
|
|
|
2014-11-07 19:39:13 +11:00
|
|
|
this.$modal.on('shown.bs.modal', function(){
|
|
|
|
self.triggerEvent('shown.oc.popup')
|
|
|
|
})
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
this.$modal.on('close.oc.popup', function(){
|
2014-11-07 20:13:16 +11:00
|
|
|
self.hide()
|
2014-05-14 23:24:20 +10:00
|
|
|
return false
|
|
|
|
})
|
|
|
|
|
|
|
|
this.init()
|
|
|
|
}
|
|
|
|
|
|
|
|
Popup.DEFAULTS = {
|
|
|
|
ajax: null,
|
|
|
|
handler: null,
|
|
|
|
keyboard: true,
|
2014-11-07 19:39:13 +11:00
|
|
|
extraData: {},
|
|
|
|
content: null
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2014-11-07 19:39:13 +11:00
|
|
|
|
|
|
|
if (!this.options.content)
|
|
|
|
this.setLoading(true)
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
* October AJAX
|
|
|
|
*/
|
|
|
|
if (this.options.handler) {
|
|
|
|
|
|
|
|
this.$el.request(this.options.handler, {
|
|
|
|
data: this.options.extraData,
|
|
|
|
success: function(data, textStatus, jqXHR) {
|
2014-08-20 10:12:44 +10:00
|
|
|
this.success(data, textStatus, jqXHR).done(function(){
|
|
|
|
self.setContent(data.result)
|
|
|
|
$(window).trigger('ajaxUpdateComplete', [this, data, textStatus, jqXHR])
|
2014-11-07 19:39:13 +11:00
|
|
|
self.triggerEvent('popupComplete') // Deprecated
|
|
|
|
self.triggerEvent('complete.oc.popup')
|
2014-08-20 10:12:44 +10:00
|
|
|
})
|
2014-05-14 23:24:20 +10:00
|
|
|
},
|
|
|
|
error: function(jqXHR, textStatus, errorThrown) {
|
2014-08-20 15:37:10 +10:00
|
|
|
this.error(jqXHR, textStatus, errorThrown).done(function(){
|
|
|
|
self.hide()
|
2014-11-07 19:39:13 +11:00
|
|
|
self.triggerEvent('popupError') // Deprecated
|
|
|
|
self.triggerEvent('error.oc.popup')
|
2014-08-20 15:37:10 +10:00
|
|
|
})
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Regular AJAX
|
|
|
|
*/
|
|
|
|
else if (this.options.ajax) {
|
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
url: this.options.ajax,
|
|
|
|
data: this.options.extraData,
|
|
|
|
success: function(data) {
|
|
|
|
self.setContent(data)
|
|
|
|
},
|
|
|
|
cache: false
|
2014-11-07 19:39:13 +11:00
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-11-07 19:39:13 +11:00
|
|
|
this.setContent(content)
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Popup.prototype.createPopupContainer = function() {
|
|
|
|
var
|
|
|
|
modal = $('<div />').prop({
|
|
|
|
class: 'control-popup modal fade',
|
|
|
|
role: 'dialog',
|
|
|
|
tabindex: -1
|
|
|
|
}),
|
|
|
|
modalDialog = $('<div />').addClass('modal-dialog'),
|
|
|
|
modalContent = $('<div />').addClass('modal-content')
|
|
|
|
|
|
|
|
return modal.append(modalDialog.append(modalContent))
|
|
|
|
}
|
|
|
|
|
|
|
|
Popup.prototype.setContent = function(contents) {
|
|
|
|
this.$content.html(contents)
|
2014-11-07 19:39:13 +11:00
|
|
|
this.setLoading(false)
|
|
|
|
this.show()
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
|
|
|
Popup.prototype.setBackdrop = function(val) {
|
|
|
|
if (val && !this.$backdrop) {
|
|
|
|
this.$backdrop = $('<div class="popup-backdrop fade" />')
|
|
|
|
.appendTo(document.body)
|
|
|
|
|
|
|
|
this.$backdrop.addClass('in')
|
2014-07-17 18:42:12 +10:00
|
|
|
this.$backdrop.append($('<div class="modal-content popup-loading-indicator" />'))
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
else if (!val && this.$backdrop) {
|
|
|
|
this.$backdrop.remove()
|
2014-11-07 19:39:13 +11:00
|
|
|
this.$backdrop = null
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
}
|
2014-08-20 15:37:10 +10:00
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
Popup.prototype.setLoading = function(val) {
|
|
|
|
if (!this.$backdrop)
|
|
|
|
return;
|
|
|
|
|
2014-07-17 18:42:12 +10:00
|
|
|
var self = this
|
2014-05-14 23:24:20 +10:00
|
|
|
if (val) {
|
|
|
|
setTimeout(function(){ self.$backdrop.addClass('loading'); }, 100)
|
2014-07-17 18:42:12 +10:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
else {
|
|
|
|
this.$backdrop.removeClass('loading');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-17 18:42:12 +10:00
|
|
|
Popup.prototype.hideLoading = function(val) {
|
|
|
|
this.setLoading(false)
|
|
|
|
|
|
|
|
// Wait for animations to complete
|
|
|
|
var self = this
|
|
|
|
setTimeout(function() { self.setBackdrop(false) }, 250)
|
|
|
|
setTimeout(function() { self.hide() }, 500)
|
|
|
|
}
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
Popup.prototype.triggerEvent = function(eventName, params) {
|
|
|
|
if (!params)
|
|
|
|
params = [this.$el, this.$modal]
|
|
|
|
|
2014-11-07 19:39:13 +11:00
|
|
|
var eventObject = jQuery.Event(eventName, { relatedTarget: this.$container.get(0) })
|
|
|
|
|
|
|
|
this.$el.trigger(eventObject, params)
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
if (this.firstDiv)
|
2014-11-07 19:39:13 +11:00
|
|
|
this.firstDiv.trigger(eventObject, params)
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
Popup.prototype.reload = function() {
|
|
|
|
this.init()
|
|
|
|
}
|
|
|
|
|
|
|
|
Popup.prototype.show = function() {
|
|
|
|
this.$modal.modal('show')
|
2014-11-07 19:39:13 +11:00
|
|
|
|
|
|
|
this.$modal.on('click.dismiss.popup', '[data-dismiss="popup"]', $.proxy(this.hide, this))
|
|
|
|
this.triggerEvent('popupShow') // Deprecated
|
|
|
|
this.triggerEvent('show.oc.popup')
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
Popup.prototype.hide = function() {
|
2014-11-07 19:39:13 +11:00
|
|
|
this.triggerEvent('popupHide') // Deprecated
|
|
|
|
this.triggerEvent('hide.oc.popup')
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
if (this.allowHide)
|
|
|
|
this.$modal.modal('hide')
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Hide the popup without destroying it,
|
|
|
|
* you should call .hide() once finished
|
|
|
|
*/
|
|
|
|
Popup.prototype.visible = function(val) {
|
|
|
|
if (val)
|
|
|
|
this.$modal.addClass('in')
|
|
|
|
else
|
|
|
|
this.$modal.removeClass('in')
|
|
|
|
this.setBackdrop(val)
|
|
|
|
}
|
|
|
|
|
|
|
|
Popup.prototype.toggle = function() {
|
2014-11-07 19:39:13 +11:00
|
|
|
this.triggerEvent('popupToggle', [this.$modal]) // Deprecated
|
|
|
|
this.triggerEvent('toggle.oc.popup', [this.$modal])
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
this.$modal.modal('toggle')
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Lock the popup from closing
|
|
|
|
*/
|
|
|
|
Popup.prototype.lock = function(val) {
|
|
|
|
this.allowHide = !val
|
|
|
|
}
|
|
|
|
|
|
|
|
// POPUP PLUGIN DEFINITION
|
|
|
|
// ============================
|
|
|
|
|
|
|
|
var old = $.fn.popup
|
|
|
|
|
|
|
|
$.fn.popup = function (option) {
|
|
|
|
var args = Array.prototype.slice.call(arguments, 1)
|
|
|
|
return this.each(function () {
|
|
|
|
var $this = $(this)
|
|
|
|
var data = $this.data('oc.popup')
|
|
|
|
var options = $.extend({}, Popup.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
|
|
|
if (!data) $this.data('oc.popup', (data = new Popup(this, options)))
|
|
|
|
else if (typeof option == 'string') data[option].apply(data, args)
|
|
|
|
else data.reload()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
$.fn.popup.Constructor = Popup
|
|
|
|
|
|
|
|
// POPUP NO CONFLICT
|
|
|
|
// =================
|
|
|
|
|
|
|
|
$.fn.popup.noConflict = function () {
|
|
|
|
$.fn.popup = old
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
|
|
|
// POPUP DATA-API
|
|
|
|
// ===============
|
|
|
|
|
|
|
|
$(document).on('click.oc.popup', '[data-control="popup"]', function() {
|
|
|
|
$(this).popup()
|
|
|
|
|
|
|
|
return false
|
|
|
|
});
|
|
|
|
|
2014-07-17 18:42:12 +10:00
|
|
|
$(document)
|
|
|
|
.on('ajaxPromise', '[data-popup-load-indicator]', function() {
|
|
|
|
$(this).closest('.control-popup').removeClass('in').popup('setLoading', true)
|
|
|
|
})
|
|
|
|
.on('ajaxFail', '[data-popup-load-indicator]', function() {
|
|
|
|
$(this).closest('.control-popup').addClass('in').popup('setLoading', false)
|
|
|
|
})
|
|
|
|
.on('ajaxDone', '[data-popup-load-indicator]', function() {
|
|
|
|
$(this).closest('.control-popup').popup('hideLoading')
|
|
|
|
})
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
}(window.jQuery);
|