diff --git a/modules/backend/assets/css/october.css b/modules/backend/assets/css/october.css index a260bf377..607e72633 100644 --- a/modules/backend/assets/css/october.css +++ b/modules/backend/assets/css/october.css @@ -12641,6 +12641,27 @@ div.control-popover { left: 0; top: 0; z-index: 170; + visibility: hidden; +} +div.control-popover.in, +div.control-popover.fade { + visibility: visible; +} +div.control-popover.fade > div { + opacity: 0; + filter: alpha(opacity=0); + -webkit-transition: all 0.3s, width 0s; + transition: all 0.3s, width 0s; + -webkit-transform: scale(0.7); + -ms-transform: scale(0.7); + transform: scale(0.7); +} +div.control-popover.fade.in > div { + opacity: 1; + filter: alpha(opacity=100); + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); } div.control-popover > div { position: relative; @@ -12833,12 +12854,12 @@ div.control-popover.placement-right .popover-head:before { } .popover-highlight { position: relative; - z-index: 162!important; + z-index: 162 !important; } .popover-highlight:hover, .popover-highlight:active, .popover-highlight:focus { - z-index: 162!important; + z-index: 162 !important; } div.popover-overlay { position: fixed; @@ -12859,12 +12880,12 @@ div.popover-overlay { position: fixed; margin: 0; padding: 10px; - width: 100%!important; + width: 100% !important; z-index: 209; - top: 0!important; - right: 0!important; - bottom: 0!important; - left: 0!important; + top: 0 !important; + right: 0 !important; + bottom: 0 !important; + left: 0 !important; } body.popover-open .control-popover > div { padding: 0; diff --git a/modules/backend/assets/js/october.popover.js b/modules/backend/assets/js/october.popover.js index 854ce1eaf..3a7399607 100644 --- a/modules/backend/assets/js/october.popover.js +++ b/modules/backend/assets/js/october.popover.js @@ -20,6 +20,8 @@ * If specified, overrides the offset property for the bottom and top popover placement. * - offsetY - Y offset in pixels to add to the calculated position, to make the position more "random". * If specified, overrides the offset property for the left and right popover placement. + * - useAnimation: adds animation to the open and close sequence, the equivalent of adding + * the CSS class 'fade' to the containerClass. * * Methods: * - hide @@ -59,6 +61,18 @@ if (e.isDefaultPrevented()) return + this.$container.removeClass('in') + this.$overlay.removeClass('in') + + $.support.transition && this.$container.hasClass('fade') + ? this.$container + .one($.support.transition.end, $.proxy(this.hidePopover, this)) + .emulateTransitionEnd(300) + : this.hidePopover() + } + + Popover.prototype.hidePopover = function() { + if (this.$container) this.$container.remove() if (this.$overlay) this.$overlay.remove() @@ -80,7 +94,7 @@ /* * Trigger the show event */ - var e = $.Event('showing.oc.popover', {relatedTarget: this.$el}) + var e = $.Event('showing.oc.popover', { relatedTarget: this.$el }) this.$el.trigger(e, this) if (e.isDefaultPrevented()) return @@ -88,13 +102,14 @@ /* * Create the popover container and overlay */ - this.$container = $('
') - .addClass('control-popover') - .css('visibility', 'hidden') + this.$container = $('').addClass('control-popover') if (this.options.containerClass) this.$container.addClass(this.options.containerClass) + if (this.options.useAnimation) + this.$container.addClass('fade') + var $content = $('').html(this.getContent()) this.$container.append($content) @@ -113,16 +128,16 @@ } if (this.options.container) - $(this.options.container).append(this.$container); + $(this.options.container).append(this.$container) else - $(document.body).append(this.$container); + $(document.body).append(this.$container) /* * Determine the popover position */ var placement = this.calcPlacement(), - position = this.calcPosition(placement); + position = this.calcPosition(placement) this.$container.css({ left: position.x, @@ -132,9 +147,11 @@ /* * Display the popover */ - this.$container.css('visibility', 'visible') + this.$container.addClass('in') + this.$overlay.addClass('in') + $(document.body).addClass('popover-open') - var showEvent = jQuery.Event( "show.oc.popover", { relatedTarget: this.$container.get(0) } ); + var showEvent = jQuery.Event('show.oc.popover', { relatedTarget: this.$container.get(0) }) this.$el.trigger(showEvent) /* @@ -150,7 +167,7 @@ this.$container.on('click', '[data-dismiss=popover]', function(e){ self.hide() - return false; + return false }) this.docClickHandler = $.proxy(this.onDocumentClick, this) @@ -170,9 +187,9 @@ } Popover.prototype.getContent = function () { - return typeof this.options.content == 'function' ? - this.options.content.call(this.$el[0], this) : - this.options.content + return typeof this.options.content == 'function' + ? this.options.content.call(this.$el[0], this) + : this.options.content } Popover.prototype.calcDimensions = function() { @@ -308,7 +325,8 @@ closeOnEsc: true, container: false, containerClass: null, - offset: 15 + offset: 15, + useAnimation: false } // POPOVER PLUGIN DEFINITION diff --git a/modules/backend/assets/js/october.popup.js b/modules/backend/assets/js/october.popup.js index 46cb5a0bf..b7a084c83 100644 --- a/modules/backend/assets/js/october.popup.js +++ b/modules/backend/assets/js/october.popup.js @@ -1,6 +1,9 @@ /* * Ajax Popup plugin * + * Options: + * - content: content HTML string or callback + * * Data attributes: * - data-control="popup" - enables the ajax popup plugin * - data-ajax="popup-content.htm" - ajax content to load @@ -23,25 +26,23 @@ var Popup = function(element, options) { var self = this - this.options = options - this.$el = $(element) - this.$target = null - this.$modal = null - this.$backdrop = null - this.isOpen = false - this.isAjax = false - this.firstDiv = null - this.allowHide = true + 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.$target = this.createPopupContainer() - this.$content = this.$target.find('.modal-content:first') - this.$modal = this.$target.modal({ show: false, backdrop: false, keyboard: this.options.keyboard }) - this.isAjax = this.options.handler || this.options.ajax + 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 }) /* * Duplicate the popup reference on the .control-popup container */ - this.$target.data('oc.popup', this) + this.$container.data('oc.popup', this) /* * Hook in to BS Modal events @@ -49,11 +50,11 @@ this.$modal.on('hide.bs.modal', function(){ self.isOpen = false self.setBackdrop(false) + }) - if (self.isAjax) { - // Wait for animation to complete - setTimeout(function() { self.$content.empty() }, 500) - } + this.$modal.on('hidden.bs.modal', function(){ + self.$container.remove() + self.$el.data('oc.popup', null) }) this.$modal.on('show.bs.modal', function(){ @@ -61,6 +62,10 @@ self.setBackdrop(true) }) + this.$modal.on('shown.bs.modal', function(){ + self.triggerEvent('shown.oc.popup') + }) + this.$modal.on('close.oc.popup', function(){ self.$modal.modal('hide') return false @@ -73,7 +78,8 @@ ajax: null, handler: null, keyboard: true, - extraData: {} + extraData: {}, + content: null } Popup.prototype.init = function(){ @@ -89,7 +95,9 @@ * Show loading panel */ this.setBackdrop(true) - this.setLoading(true) + + if (!this.options.content) + this.setLoading(true) /* * October AJAX @@ -102,14 +110,16 @@ this.success(data, textStatus, jqXHR).done(function(){ self.setContent(data.result) $(window).trigger('ajaxUpdateComplete', [this, data, textStatus, jqXHR]) - self.triggerEvent('popupComplete') + self.triggerEvent('popupComplete') // Deprecated + self.triggerEvent('complete.oc.popup') }) }, error: function(jqXHR, textStatus, errorThrown) { this.error(jqXHR, textStatus, errorThrown).done(function(){ alert(jqXHR.responseText.length ? jqXHR.responseText : jqXHR.statusText) self.hide() - self.triggerEvent('popupError') + self.triggerEvent('popupError') // Deprecated + self.triggerEvent('error.oc.popup') }) } }) @@ -128,9 +138,21 @@ 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.createPopupContainer = function() { @@ -147,9 +169,9 @@ } Popup.prototype.setContent = function(contents) { - this.show() - this.setLoading(false) 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') @@ -164,12 +186,11 @@ .appendTo(document.body) this.$backdrop.addClass('in') - this.$backdrop.append($('')) } else if (!val && this.$backdrop) { this.$backdrop.remove() - this.$backdrop = null; + this.$backdrop = null } } @@ -199,10 +220,12 @@ if (!params) params = [this.$el, this.$modal] - this.$el.trigger(eventName, params) + var eventObject = jQuery.Event(eventName, { relatedTarget: this.$container.get(0) }) + + this.$el.trigger(eventObject, params) if (this.firstDiv) - this.firstDiv.trigger(eventName, params) + this.firstDiv.trigger(eventObject, params) } Popup.prototype.reload = function() { @@ -210,14 +233,16 @@ } Popup.prototype.show = function() { - this.$modal.on('click.dismiss.popup', '[data-dismiss="popup"]', $.proxy(this.hide, this)) - this.triggerEvent('popupShow') - this.$modal.modal('show') + + this.$modal.on('click.dismiss.popup', '[data-dismiss="popup"]', $.proxy(this.hide, this)) + this.triggerEvent('popupShow') // Deprecated + this.triggerEvent('show.oc.popup') } Popup.prototype.hide = function() { - this.triggerEvent('popupHide') + this.triggerEvent('popupHide') // Deprecated + this.triggerEvent('hide.oc.popup') if (this.allowHide) this.$modal.modal('hide') @@ -236,7 +261,9 @@ } Popup.prototype.toggle = function() { - this.triggerEvent('popupToggle', [this.$modal]) + this.triggerEvent('popupToggle', [this.$modal]) // Deprecated + this.triggerEvent('toggle.oc.popup', [this.$modal]) + this.$modal.modal('toggle') } diff --git a/modules/backend/assets/less/controls/popover.less b/modules/backend/assets/less/controls/popover.less index 012ea8c40..874334352 100644 --- a/modules/backend/assets/less/controls/popover.less +++ b/modules/backend/assets/less/controls/popover.less @@ -4,6 +4,26 @@ div.control-popover { left: 0; top: 0; z-index: 170; + visibility: hidden; + + &.in, &.fade { + visibility: visible; + } + + &.fade { + & > div { + .opacity(0); + .transition(~'all 0.3s, width 0s'); + .transform(~'scale(0.7)'); + } + } + + &.fade.in { + & > div { + .opacity(1); + .transform( ~'scale(1)'); + } + } & > div { position: relative; @@ -16,8 +36,8 @@ div.control-popover { position: absolute; } - &:after {z-index: 201;} - &:before {z-index: 200;} + &:after { z-index: 201; } + &:before { z-index: 200; } } &.placement-bottom > div { @@ -150,9 +170,9 @@ div.control-popover { .popover-highlight { position: relative; - z-index: 162!important; + z-index: 162 !important; &:hover, &:active, &:focus { - z-index: 162!important; + z-index: 162 !important; } } @@ -177,12 +197,12 @@ div.popover-overlay { position: fixed; margin: 0; padding: 10px; - width: 100%!important; + width: 100% !important; z-index: 209; - top: 0!important; - right: 0!important; - bottom: 0!important; - left: 0!important; + top: 0 !important; + right: 0 !important; + bottom: 0 !important; + left: 0 !important; > div { padding: 0;