You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

354 lines
10 KiB

/* ******************************
Modal
Author: Jack Lukic
Notes: First Commit May 14, 2012
Manages modal state and
stage dimming
****************************** */
;(function ( $, window, document, undefined ) {
$.dimScreen = function(parameters) {
var
// if parameter is string it is callback function
settings = (typeof parameters == 'function')
? $.extend({}, $.fn.modal.settings, { dim: parameters })
: $.extend({}, $.fn.modal.settings, parameters),
$context = $(settings.context),
$dimmer = $context.children(settings.selector.dimmer),
dimmerExists = ($dimmer.size() > 0),
currentOpacity = $dimmer.css('opacity')
;
if(!dimmerExists) {
$dimmer = $('<div/>')
.attr('id','dimmer')
.html('<div class="content"></div>')
;
$context
.append($dimmer)
;
}
if(currentOpacity != settings.opacity) {
$dimmer
.one('click', function() {
settings.unDim();
$.unDimScreen();
})
;
if(settings.duration === 0) {
$dimmer
.css({
visibility : 'visible'
})
.find('.content')
.css({
opacity : settings.opacity,
visibility : 'visible'
})
;
}
else {
$dimmer
.css({
visibility : 'visible'
})
.find('.content')
.css({
opacity : 0,
visibility : 'visible'
})
.fadeTo(settings.duration, settings.opacity, settings.dim)
;
}
}
return this;
};
$.unDimScreen = function(parameters) {
var
settings = (typeof parameters == 'function')
? $.extend({}, $.fn.modal.settings, { unDim: parameters })
: $.extend({}, $.fn.modal.settings, parameters),
$context = $(settings.context),
$dimmer = $context.children(settings.selector.dimmer),
dimmerExists = ($dimmer.size() > 0)
;
if(dimmerExists) {
// callback before unDim
settings.unDim();
if(settings.duration === 0) {
$dimmer
.css({
visibility: 'hidden'
})
.remove()
;
}
else {
$dimmer
.find('.content')
.fadeTo(settings.duration, 0, function(){
$dimmer.remove();
})
;
}
}
return this;
};
$.fn.modal = function(parameters) {
var
settings = $.extend(true, {}, $.fn.modal.settings, parameters),
// make arguments available
query = arguments[0],
passedArguments = [].slice.call(arguments, 1),
invokedResponse
;
$(this)
.each(function() {
var
$modal = $(this),
$closeButton = $modal.find(settings.selector.closeButton),
$dimmer = $(settings.context).find(settings.selector.dimmer),
$modals = $(settings.context).children(settings.selector.modal),
$otherModals = $modals.not($modal),
instance = $modal.data('module-' + settings.namespace),
methodInvoked = (typeof query == 'string'),
className = settings.className,
namespace = settings.namespace,
module
;
module = {
initialize: function() {
// attach events
$modal
.on('modalShow.' + namespace, module.show)
.on('modalHide.' + namespace, module.hide)
.data('module-' + namespace, module)
;
},
show: function() {
var
modalHeight = $modal.outerHeight(),
windowHeight = $(window).height(),
cantFit = (modalHeight > windowHeight),
modalType = (cantFit)
? 'absolute'
: 'fixed',
topCentering = (cantFit)
? '0'
: '50%',
offsetTop = (cantFit)
? (windowHeight / 8)
: -( (modalHeight - settings.closeSpacing) / 2),
finalPosition = ($modal.css('position') == 'absolute')
? offsetTop + $(window).prop('pageYOffset')
: offsetTop,
startPosition = finalPosition + settings.animationOffset
;
// set top margin as offset
if($.fn.popIn !== undefined) {
$modal
.addClass(modalType)
.css({
display : 'block',
opacity : 0,
top: topCentering,
marginTop : finalPosition + 'px'
})
.popIn()
;
}
else {
$modal
.addClass(modalType)
.css({
display : 'block',
opacity : 0,
top: topCentering,
marginTop : startPosition + 'px'
})
.animate({
opacity : 1,
marginTop : finalPosition + 'px'
}, (settings.duration + 300), settings.easing)
;
}
if( $otherModals.is(':visible') ) {
$otherModals
.filter(':visible')
.hide()
;
}
$.dimScreen({
context : settings.context,
duration : 0,
dim : function() {
$(document)
.on('keyup.' + namespace, function(event) {
var
keyCode = event.which,
escapeKey = 27
;
switch(keyCode) {
case escapeKey:
$modal.trigger('modalHide');
event.preventDefault();
break;
}
})
;
$closeButton
.one('click', function() {
$modal.trigger('modalHide');
})
;
settings.dim();
},
unDim: function() {
$modal.trigger('modalHide');
$closeButton.unbind('click');
}
});
},
hide: function() {
// remove keyboard detection
$(document)
.off('keyup.' + namespace)
;
$.unDimScreen({
duration: 0,
unDim: function() {
$modal
.popOut(200)
;
settings.unDim();
}
});
},
/* standard module */
setting: function(name, value) {
if(value === undefined) {
return settings[name];
}
settings[name] = value;
},
debug: function() {
var
output = [],
message = settings.moduleName + ': ' + arguments[0],
variables = [].slice.call( arguments, 1 ),
log = console.info || console.log || function(){}
;
if(settings.debug) {
output.push(message);
log.apply(console, output.concat(variables) );
}
},
error: function() {
var
output = [],
errorMessage = settings.moduleName + ': ' + arguments[0],
variables = [].slice.call( arguments, 1 ),
log = console.warn || console.log || function(){}
;
if(settings.debug) {
output.push(errorMessage);
output.concat(variables);
log.apply(console, output.concat(variables) );
}
},
invoke: function(query, context, passedArguments) {
var
maxDepth,
found
;
passedArguments = passedArguments || [].slice.call( arguments, 2 );
if(typeof query == 'string' && instance !== undefined) {
query = query.split('.');
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
return true;
}
else if( instance[value] !== undefined ) {
found = instance[value];
return true;
}
module.error(settings.errors.method);
return false;
});
}
if ( $.isFunction( found ) ) {
return found.apply(context, passedArguments);
}
// return retrieved variable or chain
return found;
}
};
// check for invoking internal method
if(methodInvoked) {
invokedResponse = module.invoke(query, this, passedArguments);
}
// otherwise initialize
else {
module.initialize();
}
})
;
// chain or return queried method
return (invokedResponse !== undefined)
? invokedResponse
: this
;
};
$.fn.modal.settings = {
moduleName : 'Modal',
debug : false,
namespace : 'modal',
errors: {
method : 'The method you called is not defined'
},
dim : function(){},
unDim : function(){},
hide : function(){},
show : function(){},
context : 'body',
opacity : 0.8,
closeSpacing : 25,
animationOffset : 15,
duration : 400,
easing : 'easeOutExpo',
selector : {
dimmer : '#dimmer',
modal : '.modal',
closeButton : '.close'
}
};
})( jQuery, window , document );