Add useAnimation to popover, refactor popup so it behaves more like popover

This commit is contained in:
Sam Georges 2014-11-07 19:39:13 +11:00
parent 38170d3101
commit c0dc85eefb
4 changed files with 150 additions and 64 deletions

View File

@ -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;

View File

@ -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 = $('<div />')
.addClass('control-popover')
.css('visibility', 'hidden')
this.$container = $('<div />').addClass('control-popover')
if (this.options.containerClass)
this.$container.addClass(this.options.containerClass)
if (this.options.useAnimation)
this.$container.addClass('fade')
var $content = $('<div />').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

View File

@ -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($('<div class="modal-content popup-loading-indicator" />'))
}
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')
}

View File

@ -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;