Browse Source
Former-commit-id: 9fe80ef6c97b7c52cca61f9a066d9c6a5704b8f0 Former-commit-id: 0afd7e867a17a12e3b00c46376b538320ea20a37beta
Jack Lukic
12 years ago
89 changed files with 7701 additions and 329 deletions
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 5.5 KiB |
@ -0,0 +1,196 @@ |
|||||
|
/* ****************************** |
||||
|
Accordion |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit July 19, 2012 |
||||
|
|
||||
|
Simple accordion design |
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ($, window, document, undefined) { |
||||
|
|
||||
|
$.fn.accordion = function(parameters) { |
||||
|
var |
||||
|
settings = $.extend(true, {}, $.fn.accordion.settings, parameters), |
||||
|
// hoist arguments
|
||||
|
moduleArguments = arguments || false |
||||
|
; |
||||
|
$(this) |
||||
|
.each(function() { |
||||
|
|
||||
|
var |
||||
|
$module = $(this), |
||||
|
$title = $module.find(settings.selector.title), |
||||
|
$icon = $module.find(settings.selector.icon), |
||||
|
$content = $module.find(settings.selector.content), |
||||
|
|
||||
|
instance = $module.data('module'), |
||||
|
className = settings.className, |
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
initialize: function() { |
||||
|
// initializing
|
||||
|
$title |
||||
|
.on('click', module.change) |
||||
|
; |
||||
|
$module |
||||
|
.data('module', module) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
change: function() { |
||||
|
var |
||||
|
$activeTitle = $(this), |
||||
|
$activeContent = $activeTitle.next($content), |
||||
|
contentIsOpen = $activeTitle.hasClass(className.active) |
||||
|
; |
||||
|
if(contentIsOpen) { |
||||
|
if(settings.collapsible) { |
||||
|
$.proxy(module.close, $activeTitle)(); |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
$.proxy(module.open, $activeTitle)(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
open: function() { |
||||
|
var |
||||
|
$activeTitle = $(this), |
||||
|
$activeContent = $activeTitle.next($content), |
||||
|
$currentTitle = $title.filter('.' + className.active), |
||||
|
$currentContent = $currentTitle.next($title) |
||||
|
; |
||||
|
if(settings.exclusive && $currentTitle.size() > 0) { |
||||
|
|
||||
|
$currentTitle |
||||
|
.removeClass('active') |
||||
|
; |
||||
|
$currentContent |
||||
|
.stop() |
||||
|
.slideUp(settings.speed , settings.easing, function() { |
||||
|
$(this) |
||||
|
.removeClass('active') |
||||
|
.removeAttr('style') |
||||
|
; |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
$activeTitle |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
$activeContent |
||||
|
.hide() |
||||
|
.addClass(className.active) |
||||
|
.stop() |
||||
|
.slideDown(settings.speed, settings.easing, function() { |
||||
|
$(this) |
||||
|
.removeAttr('style') |
||||
|
; |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
close: function() { |
||||
|
var |
||||
|
$activeTitle = $(this), |
||||
|
$activeContent = $activeTitle.next($content) |
||||
|
; |
||||
|
$activeTitle |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
$activeContent |
||||
|
.removeClass(className.active) |
||||
|
.show() |
||||
|
.stop() |
||||
|
.slideUp(settings.speed, settings.easing, function(){ |
||||
|
$(this) |
||||
|
.removeAttr('style') |
||||
|
; |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
debug: function(message) { |
||||
|
if(settings.debug) { |
||||
|
console.info(settings.moduleName + ': ' + message); |
||||
|
} |
||||
|
}, |
||||
|
error: function(errorMessage) { |
||||
|
console.warn(settings.moduleName + ': ' + errorMessage); |
||||
|
}, |
||||
|
invoke: function(methodName, context, methodArguments) { |
||||
|
var |
||||
|
method |
||||
|
; |
||||
|
methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 ); |
||||
|
if(typeof methodName == 'string' && instance !== undefined) { |
||||
|
methodName = methodName.split('.'); |
||||
|
$.each(methodName, function(index, name) { |
||||
|
if( $.isPlainObject( instance[name] ) ) { |
||||
|
instance = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
else if( $.isFunction( instance[name] ) ) { |
||||
|
method = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
module.error(settings.errors.method); |
||||
|
return false; |
||||
|
}); |
||||
|
} |
||||
|
if ( $.isFunction( method ) ) { |
||||
|
return method.apply(context, methodArguments); |
||||
|
} |
||||
|
// return retrieved variable or chain
|
||||
|
return method; |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
// calling a method
|
||||
|
if(instance !== undefined && moduleArguments) { |
||||
|
// simpler than invoke realizing to invoke itself (and losing scope due prototype.call()
|
||||
|
if(moduleArguments[0] == 'invoke') { |
||||
|
moduleArguments = Array.prototype.slice.call( moduleArguments, 1 ); |
||||
|
} |
||||
|
return module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) ); |
||||
|
} |
||||
|
// initializing
|
||||
|
module.initialize(); |
||||
|
|
||||
|
}) |
||||
|
; |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
$.fn.accordion.settings = { |
||||
|
moduleName : 'Accordion', |
||||
|
debug : false, |
||||
|
|
||||
|
exclusive : true, |
||||
|
collapsible : true, |
||||
|
|
||||
|
errors: { |
||||
|
method : 'The method you called is not defined' |
||||
|
}, |
||||
|
|
||||
|
className : { |
||||
|
active : 'active', |
||||
|
hover : 'hover' |
||||
|
}, |
||||
|
|
||||
|
selector : { |
||||
|
title : '.title', |
||||
|
icon : '.icon', |
||||
|
content : '.content' |
||||
|
}, |
||||
|
|
||||
|
speed : 500, |
||||
|
easing : 'easeInOutQuint' |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,247 @@ |
|||||
|
/* ****************************** |
||||
|
Animation |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit May 24, 2012 |
||||
|
|
||||
|
A collection of FX/Animations |
||||
|
|
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ( $, window, document, undefined ) { |
||||
|
|
||||
|
|
||||
|
// handles simplification of animation settings
|
||||
|
$.animationSettings = function(settings, duration, easing, complete) { |
||||
|
// no parameters
|
||||
|
if(duration === undefined) { |
||||
|
settings = settings; |
||||
|
} |
||||
|
// duration is actually settings object
|
||||
|
else if(typeof duration == 'object') { |
||||
|
settings = $.extend({} , settings, duration); |
||||
|
} |
||||
|
// easing is actually complete callback
|
||||
|
else if(typeof easing == 'function') { |
||||
|
settings = $.extend({} , settings, { |
||||
|
duration: duration, |
||||
|
complete: easing |
||||
|
}); |
||||
|
} |
||||
|
// easing is actually settings
|
||||
|
else if(typeof easing == 'object') { |
||||
|
settings = $.extend(true, {} , settings, {duration: duration}, easing); |
||||
|
} |
||||
|
//
|
||||
|
else { |
||||
|
settings = $.extend({} , settings, { |
||||
|
duration : duration, |
||||
|
easing : easing, |
||||
|
complete : complete |
||||
|
}); |
||||
|
} |
||||
|
return settings; |
||||
|
}; |
||||
|
|
||||
|
/* ****************************** |
||||
|
Pop In - |
||||
|
Animates one at a time |
||||
|
scaling in |
||||
|
****************************** */ |
||||
|
|
||||
|
$.fn.popIn = function(duration, easing, complete) { |
||||
|
var |
||||
|
settings = $.animationSettings($.fn.popIn.settings, duration, easing, complete), |
||||
|
|
||||
|
$this = $(this), |
||||
|
totalElements = $this.size(), |
||||
|
currentElement = 0, |
||||
|
callback = function() { |
||||
|
var |
||||
|
elementsDoneAnimating = ($this.filter(':animated').size() == 0) |
||||
|
; |
||||
|
currentElement++; |
||||
|
$(this) |
||||
|
.css('transform', '') |
||||
|
.removeClass(settings.className.init) |
||||
|
; |
||||
|
$.proxy(settings.eachComplete, this)(); |
||||
|
if(currentElement == totalElements) { |
||||
|
$.proxy(settings.complete, $this)(); |
||||
|
} |
||||
|
}, |
||||
|
animate = function(index) { |
||||
|
$(this) |
||||
|
.delay(settings.delay * index) |
||||
|
.animate({ |
||||
|
opacity : settings.endOpacity, |
||||
|
transform : 'scale('+ settings.endScale +')' |
||||
|
}, settings.duration, settings.easing, callback) |
||||
|
; |
||||
|
} |
||||
|
; |
||||
|
if(settings.isLegacyBrowser) { |
||||
|
$this |
||||
|
.show() |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$this |
||||
|
.addClass(settings.className.init) |
||||
|
.show() |
||||
|
.css({ |
||||
|
opacity : settings.startOpacity, |
||||
|
transform : 'scale('+ settings.startScale +')' |
||||
|
}) |
||||
|
.each(animate) |
||||
|
; |
||||
|
} |
||||
|
return $(this); |
||||
|
}; |
||||
|
|
||||
|
$.fn.popOut = function(duration, easing, complete) { |
||||
|
var |
||||
|
parameters = $.animationSettings($.fn.popIn.settings, duration, easing, complete), |
||||
|
// flip some defaults
|
||||
|
defaults = { |
||||
|
complete: function() { |
||||
|
$(this).hide(); |
||||
|
$.proxy(parameters.complete, this)(); |
||||
|
}, |
||||
|
startOpacity : parameters.endOpacity, |
||||
|
endOpacity : 0, |
||||
|
startScale : parameters.endScale, |
||||
|
endScale : parameters.startScale |
||||
|
}, |
||||
|
settings = $.extend(true, {}, parameters, defaults) |
||||
|
; |
||||
|
$(this) |
||||
|
.popIn(settings) |
||||
|
; |
||||
|
}; |
||||
|
|
||||
|
$.fn.popIn.settings = { |
||||
|
|
||||
|
// legacy browser
|
||||
|
isLegacyBrowser: ($.browser.msie && parseInt($.browser.version) <= 8), |
||||
|
|
||||
|
// class given until animation ends
|
||||
|
className: { |
||||
|
init : 'init' |
||||
|
}, |
||||
|
// duration of each animation
|
||||
|
duration : 450, |
||||
|
// easing for animation
|
||||
|
easing : 'easeOutExpo', |
||||
|
// delay before each
|
||||
|
delay : 100, |
||||
|
|
||||
|
startOpacity : 0, |
||||
|
endOpacity : 1, |
||||
|
|
||||
|
startScale : 0.7, |
||||
|
endScale : 1, |
||||
|
// called after each element completes
|
||||
|
eachComplete : function(){}, |
||||
|
// called after entire chain of animation completes
|
||||
|
complete : function(){} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
$.fn.kenBurns = function(duration, easing, complete) { |
||||
|
var |
||||
|
settings = $.animationSettings($.fn.kenBurns.settings, duration, easing, complete), |
||||
|
module = { |
||||
|
|
||||
|
randomPosition: function(starting, rangeMin, rangeMax) { |
||||
|
var |
||||
|
rangeMax = (rangeMax !== undefined) |
||||
|
? rangeMax |
||||
|
: rangeMin, |
||||
|
number = Math.random() * ((starting + rangeMax) - (starting - rangeMin) ) + (starting - rangeMin) |
||||
|
; |
||||
|
return parseInt(number, 10); |
||||
|
}, |
||||
|
|
||||
|
animate: function() { |
||||
|
var |
||||
|
startingPosition = {}, |
||||
|
endingPosition = {}, |
||||
|
startingScale, |
||||
|
endingScale |
||||
|
; |
||||
|
|
||||
|
startingPosition = (settings.useStartPosition) |
||||
|
? { |
||||
|
x: parseInt( $(this).css('background-position-x'), 10), |
||||
|
y: parseInt( $(this).css('background-position-y'), 10) |
||||
|
} |
||||
|
: { |
||||
|
x: module.randomPosition(50, settings.xRange), |
||||
|
y: module.randomPosition(50, settings.yRange) |
||||
|
} |
||||
|
; |
||||
|
// determine direction of animation based on origin position
|
||||
|
endingPosition.x = (startingPosition.x > 50) |
||||
|
? module.randomPosition(startingPosition.x, settings.xMaxTravelDistance, -settings.xMinTravelDistance) |
||||
|
: module.randomPosition(startingPosition.x, -settings.xMinTravelDistance, settings.xMaxTravelDistance) |
||||
|
; |
||||
|
endingPosition.y = (startingPosition.y > 50) |
||||
|
? module.randomPosition(startingPosition.y, settings.yMaxTravelDistance, -settings.yMinTravelDistance) |
||||
|
: module.randomPosition(startingPosition.y, -settings.yMinTravelDistance, settings.yMaxTravelDistance) |
||||
|
; |
||||
|
|
||||
|
/*console.log(startingPosition.x + '% ' + startingPosition.y + '%'); |
||||
|
console.log(endingPosition.x + '% ' + endingPosition.y + '%');*/ |
||||
|
|
||||
|
$(this) |
||||
|
.css({ |
||||
|
backgroundPosition: startingPosition.x + '%', |
||||
|
backgroundPositionY: startingPosition.y + '%' |
||||
|
}) |
||||
|
.stop() |
||||
|
.animate({ |
||||
|
backgroundPosition: endingPosition.x + '%', |
||||
|
backgroundPositionY: endingPosition.y + '%' |
||||
|
}, settings.duration, settings.easing, settings.complete) |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
; |
||||
|
if(!settings.isLegacyBrowser) { |
||||
|
$(this) |
||||
|
.each(module.animate) |
||||
|
; |
||||
|
} |
||||
|
return $(this); |
||||
|
}; |
||||
|
|
||||
|
$.fn.kenBurns.settings = { |
||||
|
|
||||
|
// legacy browser
|
||||
|
isLegacyBrowser : ($.browser.msie && parseInt($.browser.version, 10) <= 8), |
||||
|
|
||||
|
// duration of animation
|
||||
|
duration : 10000, |
||||
|
// easing for animation
|
||||
|
easing : 'linear', |
||||
|
useStartPosition : false, |
||||
|
|
||||
|
xRange : 40, |
||||
|
yRange : 20, |
||||
|
|
||||
|
xMinTravelDistance : 30, |
||||
|
xMaxTravelDistance : 60, |
||||
|
|
||||
|
yMinTravelDistance : 20, |
||||
|
yMaxTravelDistance : 40, |
||||
|
|
||||
|
// not yet implemented, need css hook for background-size
|
||||
|
scale : 0.1, |
||||
|
|
||||
|
// called after entire chain of animation completes
|
||||
|
complete : function(){} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,515 @@ |
|||||
|
/* ****************************** |
||||
|
API |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit May 08, 2012 |
||||
|
|
||||
|
These are modules which bind API functionality to the DOM |
||||
|
|
||||
|
Requires: nada |
||||
|
|
||||
|
Initialization: |
||||
|
$('.button') |
||||
|
.apiButton({ |
||||
|
success: function() {} |
||||
|
}) |
||||
|
; |
||||
|
|
||||
|
in our example api is automapped to an object literal |
||||
|
@ quirky.config.endpoint.api |
||||
|
|
||||
|
HTML: |
||||
|
<div class="button" action="follow" data-id="5"> |
||||
|
|
||||
|
URL : quirky.config.endpoint.api.follow |
||||
|
Given Value: /follow/{$id}/ |
||||
|
Sent Value : /follow/5/ |
||||
|
|
||||
|
(4 ways to map api endpoint, each will be looked for in succession) |
||||
|
url mapping order: |
||||
|
first : defined in plugin init as url (arbitrary url) |
||||
|
second : defined in plugin init as action (action in obj literal grouping 'api') |
||||
|
third : defined in data-url |
||||
|
fourth : defined in data-action |
||||
|
|
||||
|
beforeSend: |
||||
|
this callback can be used to modify request settings before XHR |
||||
|
it also can be used to look for for pre-conditions to prevent API |
||||
|
call by returning "false" |
||||
|
|
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ( $, window, document, undefined ) { |
||||
|
|
||||
|
$.api = $.fn.api = function(parameters) { |
||||
|
|
||||
|
var |
||||
|
settings = $.extend(true, {}, $.api.settings, parameters), |
||||
|
|
||||
|
// if this keyword isn't a jQuery object, create one
|
||||
|
context = (typeof this != 'function') |
||||
|
? this |
||||
|
: $('<div/>'), |
||||
|
// context defines the element used for loading/error state
|
||||
|
$context = (settings.stateContext) |
||||
|
? $(settings.stateContext) |
||||
|
: $(context), |
||||
|
// module is the thing that initiates the api action, can be independent of context
|
||||
|
$module = typeof this == 'object' |
||||
|
? $(context) |
||||
|
: $context, |
||||
|
|
||||
|
action = $module.data(settings.metadata.action) || settings.action || false, |
||||
|
|
||||
|
className = settings.className, |
||||
|
metadata = settings.metadata, |
||||
|
errors = settings.errors, |
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
initialize: function() { |
||||
|
var |
||||
|
exitConditions = false, |
||||
|
|
||||
|
runSettings, |
||||
|
|
||||
|
loadingTimer = new Date().getTime(), |
||||
|
loadingDelay, |
||||
|
|
||||
|
promise, |
||||
|
url, |
||||
|
urlVariables, |
||||
|
|
||||
|
formData = {}, |
||||
|
data, |
||||
|
|
||||
|
ajaxSettings = {}, |
||||
|
xhr, |
||||
|
|
||||
|
errors = settings.errors |
||||
|
; |
||||
|
|
||||
|
// serialize parent form if requested!
|
||||
|
if(settings.serializeForm && $(this).toJSON() !== undefined) { |
||||
|
formData = $module |
||||
|
.closest('form') |
||||
|
.toJSON() |
||||
|
; |
||||
|
$.extend(true, settings.data, formData); |
||||
|
module.debug('Adding form data to API Request', formData); |
||||
|
} |
||||
|
|
||||
|
// let beforesend change settings object
|
||||
|
runSettings = $.proxy(settings.beforeSend, $module)(settings); |
||||
|
|
||||
|
// check for exit conditions
|
||||
|
if(runSettings !== undefined && !runSettings) { |
||||
|
module.error(errors.beforeSend); |
||||
|
module.reset(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if(action) { |
||||
|
module.debug('Initializing API Request for: ', action); |
||||
|
if(settings.api[action] !== undefined) { |
||||
|
url = settings.api[action]; |
||||
|
} |
||||
|
else { |
||||
|
module.error(errors.missingAction); |
||||
|
} |
||||
|
} |
||||
|
// override with url if specified
|
||||
|
if(settings.url) { |
||||
|
url = settings.url; |
||||
|
module.debug('Using specified url: ', url); |
||||
|
} |
||||
|
|
||||
|
if(!url) { |
||||
|
module.error(errors.missingURL); |
||||
|
module.reset(); |
||||
|
} |
||||
|
|
||||
|
// replace url data in url
|
||||
|
urlVariables = url.match(settings.regExpTemplate); |
||||
|
|
||||
|
if(urlVariables) { |
||||
|
module.debug('Looking for URL variables', urlVariables); |
||||
|
$.each(urlVariables, function(index, templateValue){ |
||||
|
var |
||||
|
term = templateValue.substr( 2, templateValue.length - 3), |
||||
|
termValue = ($.isPlainObject(parameters.urlData) && parameters.urlData[term] !== undefined) |
||||
|
? parameters.urlData[term] |
||||
|
: ($module.data(term) !== undefined) |
||||
|
? $module.data(term) |
||||
|
: settings.urlData[term] |
||||
|
; |
||||
|
module.verbose('Looking for variable', term, $module, $module.data(term), settings.urlData[term]); |
||||
|
// remove optional value
|
||||
|
if(termValue === false) { |
||||
|
module.debug('Removing variable from URL', urlVariables); |
||||
|
url = url.replace('/' + templateValue, ''); |
||||
|
} |
||||
|
// undefined condition
|
||||
|
else if(termValue === undefined || !termValue) { |
||||
|
module.error(errors.missingParameter + term); |
||||
|
exitConditions = true; |
||||
|
} |
||||
|
else { |
||||
|
url = url.replace(templateValue, termValue); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// exit conditions reached from missing url parameters
|
||||
|
if( exitConditions ) { |
||||
|
module.reset(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// promise handles notification on api request, so loading min. delay can occur for all notifications
|
||||
|
promise = |
||||
|
$.Deferred() |
||||
|
.always(function() { |
||||
|
if(settings.stateContext) { |
||||
|
$context |
||||
|
.removeClass(className.loading) |
||||
|
; |
||||
|
} |
||||
|
$.proxy(settings.complete, $module)(); |
||||
|
}) |
||||
|
.done(function(response) { |
||||
|
module.debug('API request successful'); |
||||
|
// take a stab at finding success state if json
|
||||
|
if(settings.dataType == 'json') { |
||||
|
if(response.success === true) { |
||||
|
$.proxy(settings.success, $context)(response, settings, $module); |
||||
|
} |
||||
|
else { |
||||
|
module.debug('JSON success flag is not set.'); |
||||
|
if (response.error !== undefined) { |
||||
|
$.proxy(settings.failure, $context)(response.error, settings, $module); |
||||
|
} |
||||
|
else if ($.isArray(response.errors)) { |
||||
|
$.proxy(settings.failure, $context)(response.errors[0], settings, $module); |
||||
|
} |
||||
|
else if(response.message !== undefined) { |
||||
|
$.proxy(settings.failure, $context)(response.message, settings, $module); |
||||
|
} |
||||
|
else { |
||||
|
$.proxy(settings.failure, $context)(errors.error, settings, $module); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// otherwise
|
||||
|
else { |
||||
|
$.proxy(settings.success, $context)(response, settings, $module); |
||||
|
} |
||||
|
}) |
||||
|
.fail(function(xhr, status, httpMessage) { |
||||
|
var |
||||
|
errorMessage = (settings.errors[status] !== undefined) |
||||
|
? settings.errors[status] |
||||
|
: httpMessage, |
||||
|
response |
||||
|
; |
||||
|
// let em know unless request aborted
|
||||
|
if(xhr !== undefined) { |
||||
|
// readyState 4 = done, anything less is not really sent
|
||||
|
if(xhr.readyState !== undefined && xhr.readyState == 4) { |
||||
|
|
||||
|
// if http status code returned and json returned error, look for it
|
||||
|
if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') { |
||||
|
module.error(errors.statusMessage + httpMessage); |
||||
|
} |
||||
|
else { |
||||
|
if(status == 'error' && settings.dataType == 'json') { |
||||
|
try { |
||||
|
response = $.parseJSON(xhr.responseText); |
||||
|
if(response && response.error !== undefined) { |
||||
|
errorMessage = response.error; |
||||
|
} |
||||
|
} |
||||
|
catch(error) { |
||||
|
module.error(errors.JSONParse); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
$context |
||||
|
.removeClass(className.loading) |
||||
|
.addClass(className.error) |
||||
|
; |
||||
|
// show error state only for duration specified in settings
|
||||
|
if(settings.errorLength > 0) { |
||||
|
setTimeout(function(){ |
||||
|
$context |
||||
|
.removeClass(className.error) |
||||
|
; |
||||
|
}, settings.errorLength); |
||||
|
} |
||||
|
module.debug('API Request error:', errorMessage); |
||||
|
$.proxy(settings.failure, $context)(errorMessage, settings, this); |
||||
|
} |
||||
|
else { |
||||
|
module.debug('Request Aborted (Most likely caused by page change)'); |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
; |
||||
|
|
||||
|
// look for params in data
|
||||
|
$.extend(true, ajaxSettings, settings, { |
||||
|
type : settings.method || settings.type, |
||||
|
data : data, |
||||
|
url : url, |
||||
|
beforeSend : settings.beforeXHR |
||||
|
}); |
||||
|
|
||||
|
if(settings.stateContext) { |
||||
|
$context |
||||
|
.addClass(className.loading) |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
if(settings.progress) { |
||||
|
module.verbose('Adding progress events'); |
||||
|
$.extend(true, ajaxSettings, { |
||||
|
xhr: function() { |
||||
|
var |
||||
|
xhr = new window.XMLHttpRequest() |
||||
|
; |
||||
|
xhr.upload.addEventListener('progress', function(event) { |
||||
|
var |
||||
|
percentComplete |
||||
|
; |
||||
|
if (event.lengthComputable) { |
||||
|
percentComplete = Math.round(event.loaded / event.total * 10000) / 100 + '%'; |
||||
|
$.proxy(settings.progress, $context)(percentComplete, event); |
||||
|
} |
||||
|
}, false); |
||||
|
xhr.addEventListener('progress', function(event) { |
||||
|
var |
||||
|
percentComplete |
||||
|
; |
||||
|
if (event.lengthComputable) { |
||||
|
percentComplete = Math.round(event.loaded / event.total * 10000) / 100 + '%'; |
||||
|
$.proxy(settings.progress, $context)(percentComplete, event); |
||||
|
} |
||||
|
}, false); |
||||
|
return xhr; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
module.verbose('Creating AJAX request with settings: ', ajaxSettings); |
||||
|
xhr = |
||||
|
$.ajax(ajaxSettings) |
||||
|
.always(function() { |
||||
|
// calculate if loading time was below minimum threshold
|
||||
|
loadingDelay = ( settings.loadingLength - (new Date().getTime() - loadingTimer) ); |
||||
|
settings.loadingDelay = loadingDelay < 0 |
||||
|
? 0 |
||||
|
: loadingDelay |
||||
|
; |
||||
|
}) |
||||
|
.done(function(response) { |
||||
|
var |
||||
|
context = this |
||||
|
; |
||||
|
setTimeout(function(){ |
||||
|
promise.resolveWith(context, [response]); |
||||
|
}, settings.loadingDelay); |
||||
|
}) |
||||
|
.fail(function(xhr, status, httpMessage) { |
||||
|
var |
||||
|
context = this |
||||
|
; |
||||
|
// page triggers abort on navigation, dont show error
|
||||
|
if(status != 'abort') { |
||||
|
setTimeout(function(){ |
||||
|
promise.rejectWith(context, [xhr, status, httpMessage]); |
||||
|
}, settings.loadingDelay); |
||||
|
} |
||||
|
else { |
||||
|
$context |
||||
|
.removeClass(className.error) |
||||
|
.removeClass(className.loading) |
||||
|
; |
||||
|
} |
||||
|
}) |
||||
|
; |
||||
|
if(settings.stateContext) { |
||||
|
$module |
||||
|
.data(metadata.promise, promise) |
||||
|
.data(metadata.xhr, xhr) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// reset api request
|
||||
|
reset: function() { |
||||
|
$module |
||||
|
.data(metadata.promise, false) |
||||
|
.data(metadata.xhr, false) |
||||
|
; |
||||
|
$context |
||||
|
.removeClass(className.error) |
||||
|
.removeClass(className.loading) |
||||
|
; |
||||
|
module.error(errors.exitConditions); |
||||
|
}, |
||||
|
|
||||
|
/* standard module */ |
||||
|
setting: function(name, value) { |
||||
|
if(value === undefined) { |
||||
|
return settings[name]; |
||||
|
} |
||||
|
settings[name] = value; |
||||
|
}, |
||||
|
verbose: function() { |
||||
|
if(settings.verbose) { |
||||
|
module.debug.apply(this, arguments); |
||||
|
} |
||||
|
}, |
||||
|
debug: function() { |
||||
|
var |
||||
|
output = [], |
||||
|
message = settings.moduleName + ': ' + arguments[0], |
||||
|
variables = [].slice.call( arguments, 1 ), |
||||
|
log = console.info || console.log || function(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
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(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
if(settings.debug) { |
||||
|
output.push(errorMessage); |
||||
|
output.concat(variables); |
||||
|
log.apply(console, output.concat(variables) ); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
module.initialize(); |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
// handle DOM attachment to API functionality
|
||||
|
$.fn.apiButton = function(parameters) { |
||||
|
$(this) |
||||
|
.each(function(){ |
||||
|
var |
||||
|
// if only function passed it is success callback
|
||||
|
$module = $(this), |
||||
|
element = this, |
||||
|
selector = $(this).selector || '', |
||||
|
|
||||
|
settings = ( $.isFunction(parameters) ) |
||||
|
? $.extend(true, {}, $.api.settings, $.fn.apiButton.settings, { stateContext: this, success: parameters }) |
||||
|
: $.extend(true, {}, $.api.settings, $.fn.apiButton.settings, { stateContext: this}, parameters), |
||||
|
module |
||||
|
; |
||||
|
module = { |
||||
|
initialize: function() { |
||||
|
if(settings.context && selector !== '') { |
||||
|
$(settings.context) |
||||
|
.on(selector, 'click.' + settings.namespace, module.click) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$module |
||||
|
.on('click.' + settings.namespace, module.click) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
click: function() { |
||||
|
if(!settings.filter || $(this).filter(settings.filter).size() === 0) { |
||||
|
$.proxy( $.api, this )(settings); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
module.initialize(); |
||||
|
}) |
||||
|
; |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
$.api.settings = { |
||||
|
moduleName : 'API Module', |
||||
|
namespace : 'api', |
||||
|
|
||||
|
verbose : true, |
||||
|
debug : true, |
||||
|
|
||||
|
api : {}, |
||||
|
|
||||
|
beforeSend : function(settings) { |
||||
|
return settings; |
||||
|
}, |
||||
|
beforeXHR : function(xhr) {}, |
||||
|
|
||||
|
success : function(response) {}, |
||||
|
complete : function(response) {}, |
||||
|
failure : function(errorCode) {}, |
||||
|
progress : false, |
||||
|
|
||||
|
errors : { |
||||
|
missingAction : 'API action used but no url was defined', |
||||
|
missingURL : 'URL not specified for the API action', |
||||
|
missingParameter : 'Missing an essential URL parameter: ', |
||||
|
|
||||
|
timeout : 'Your request timed out', |
||||
|
error : 'There was an error with your request', |
||||
|
parseError : 'There was an error parsing your request', |
||||
|
JSONParse : 'JSON could not be parsed during error handling', |
||||
|
statusMessage : 'Server gave an error: ', |
||||
|
beforeSend : 'The before send function has aborted the request', |
||||
|
exitConditions : 'API Request Aborted. Exit conditions met' |
||||
|
}, |
||||
|
|
||||
|
className: { |
||||
|
loading : 'loading', |
||||
|
error : 'error' |
||||
|
}, |
||||
|
|
||||
|
metadata: { |
||||
|
action : 'action', |
||||
|
promise : 'promise', |
||||
|
xhr : 'xhr' |
||||
|
}, |
||||
|
|
||||
|
regExpTemplate: /\{\$([A-z]+)\}/g, |
||||
|
|
||||
|
action : false, |
||||
|
url : false, |
||||
|
urlData : false, |
||||
|
serializeForm : false, |
||||
|
|
||||
|
stateContext : false, |
||||
|
|
||||
|
method : 'get', |
||||
|
data : {}, |
||||
|
dataType : 'json', |
||||
|
cache : true, |
||||
|
|
||||
|
loadingLength : 200, |
||||
|
errorLength : 2000 |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
$.fn.apiButton.settings = { |
||||
|
filter : '.disabled, .loading', |
||||
|
context : false, |
||||
|
stateContext : false |
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,271 @@ |
|||||
|
/* ****************************** |
||||
|
Colorizer |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit June 06, 2012 |
||||
|
|
||||
|
Tooltip Wrapper for loading |
||||
|
colorizes of ideations, concepts and users |
||||
|
|
||||
|
Will eventually rewrite to use own tooltip lib |
||||
|
|
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ( $, window, document, undefined ) { |
||||
|
|
||||
|
$.fn.colorize = function(parameters) { |
||||
|
var |
||||
|
settings = $.extend(true, {}, $.fn.colorize.settings, parameters), |
||||
|
// hoist arguments
|
||||
|
moduleArguments = arguments || false |
||||
|
; |
||||
|
$(this) |
||||
|
.each(function(instanceIndex) { |
||||
|
|
||||
|
var |
||||
|
$module = $(this), |
||||
|
|
||||
|
mainCanvas = $('<canvas />')[0], |
||||
|
imageCanvas = $('<canvas />')[0], |
||||
|
overlayCanvas = $('<canvas />')[0], |
||||
|
|
||||
|
backgroundImage = new Image(), |
||||
|
|
||||
|
// defs
|
||||
|
mainContext, |
||||
|
imageContext, |
||||
|
overlayContext, |
||||
|
|
||||
|
image, |
||||
|
imageName, |
||||
|
|
||||
|
width, |
||||
|
height, |
||||
|
|
||||
|
// shortucts
|
||||
|
colors = settings.colors, |
||||
|
paths = settings.paths, |
||||
|
namespace = settings.namespace, |
||||
|
errors = settings.errors, |
||||
|
|
||||
|
// boilerplate
|
||||
|
instance = $module.data('module-' + namespace), |
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
checkPreconditions: function() { |
||||
|
module.debug('Checking pre-conditions'); |
||||
|
|
||||
|
if( !$.isPlainObject(colors) || $.isEmptyObject(colors) ) { |
||||
|
module.error(errors.undefinedColors); |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
}, |
||||
|
|
||||
|
async: function(callback) { |
||||
|
if(settings.async) { |
||||
|
setTimeout(callback, 0); |
||||
|
} |
||||
|
else { |
||||
|
callback(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
getMetadata: function() { |
||||
|
module.debug('Grabbing metadata'); |
||||
|
image = $module.data('image') || settings.image || undefined; |
||||
|
imageName = $module.data('name') || settings.name || instanceIndex; |
||||
|
width = settings.width || $module.width(); |
||||
|
height = settings.height || $module.height(); |
||||
|
if(width === 0 || height === 0) { |
||||
|
module.error(errors.undefinedSize); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
initialize: function() { |
||||
|
module.debug('Initializing with colors', colors); |
||||
|
if( module.checkPreconditions() ) { |
||||
|
|
||||
|
module.async(function() { |
||||
|
module.getMetadata(); |
||||
|
module.canvas.create(); |
||||
|
|
||||
|
module.draw.image(function() { |
||||
|
module.draw.colors(); |
||||
|
module.canvas.merge(); |
||||
|
}); |
||||
|
$module |
||||
|
.data('module-' + namespace, module) |
||||
|
; |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
redraw: function() { |
||||
|
module.debug('Redrawing image'); |
||||
|
module.async(function() { |
||||
|
module.canvas.clear(); |
||||
|
module.draw.colors(); |
||||
|
module.canvas.merge(); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
change: { |
||||
|
color: function(colorName, color) { |
||||
|
module.debug('Changing color', colorName); |
||||
|
if(colors[colorName] === undefined) { |
||||
|
module.error(errors.missingColor); |
||||
|
return false; |
||||
|
} |
||||
|
colors[colorName] = color; |
||||
|
module.redraw(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
canvas: { |
||||
|
create: function() { |
||||
|
module.debug('Creating canvases'); |
||||
|
|
||||
|
mainCanvas.width = width; |
||||
|
mainCanvas.height = height; |
||||
|
imageCanvas.width = width; |
||||
|
imageCanvas.height = height; |
||||
|
overlayCanvas.width = width; |
||||
|
overlayCanvas.height = height; |
||||
|
|
||||
|
mainContext = mainCanvas.getContext('2d'); |
||||
|
imageContext = imageCanvas.getContext('2d'); |
||||
|
overlayContext = overlayCanvas.getContext('2d'); |
||||
|
|
||||
|
$module |
||||
|
.append( mainCanvas ) |
||||
|
; |
||||
|
mainContext = $module.children('canvas')[0].getContext('2d'); |
||||
|
}, |
||||
|
clear: function(context) { |
||||
|
module.debug('Clearing canvas'); |
||||
|
overlayContext.fillStyle = '#FFFFFF'; |
||||
|
overlayContext.fillRect(0, 0, width, height); |
||||
|
}, |
||||
|
merge: function() { |
||||
|
if( !$.isFunction(mainContext.blendOnto) ) { |
||||
|
module.error(errors.missingPlugin); |
||||
|
return; |
||||
|
} |
||||
|
mainContext.putImageData( imageContext.getImageData(0, 0, width, height), 0, 0); |
||||
|
overlayContext.blendOnto(mainContext, 'multiply'); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
draw: { |
||||
|
|
||||
|
image: function(callback) { |
||||
|
module.debug('Drawing image'); |
||||
|
callback = callback || function(){}; |
||||
|
if(image) { |
||||
|
backgroundImage.src = image; |
||||
|
backgroundImage.onload = function() { |
||||
|
imageContext.drawImage(backgroundImage, 0, 0); |
||||
|
callback(); |
||||
|
}; |
||||
|
} |
||||
|
else { |
||||
|
module.error(errors.noImage); |
||||
|
callback(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
colors: function() { |
||||
|
module.debug('Drawing color overlays', colors); |
||||
|
$.each(colors, function(colorName, color) { |
||||
|
settings.onDraw(overlayContext, imageName, colorName, color); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
debug: function(message, variableName) { |
||||
|
if(settings.debug) { |
||||
|
if(variableName !== undefined) { |
||||
|
console.info(settings.moduleName + ': ' + message, variableName); |
||||
|
} |
||||
|
else { |
||||
|
console.info(settings.moduleName + ': ' + message); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
error: function(errorMessage) { |
||||
|
console.warn(settings.moduleName + ': ' + errorMessage); |
||||
|
}, |
||||
|
invoke: function(methodName, context, methodArguments) { |
||||
|
var |
||||
|
method |
||||
|
; |
||||
|
methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 ); |
||||
|
|
||||
|
if(typeof methodName == 'string' && instance !== undefined) { |
||||
|
methodName = methodName.split('.'); |
||||
|
$.each(methodName, function(index, name) { |
||||
|
if( $.isPlainObject( instance[name] ) ) { |
||||
|
instance = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
else if( $.isFunction( instance[name] ) ) { |
||||
|
method = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
module.error(settings.errors.method); |
||||
|
return false; |
||||
|
}); |
||||
|
} |
||||
|
return ( $.isFunction( method ) ) |
||||
|
? method.apply(context, methodArguments) |
||||
|
: false |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
if(instance !== undefined && moduleArguments) { |
||||
|
// simpler than invoke realizing to invoke itself (and losing scope due prototype.call()
|
||||
|
if(moduleArguments[0] == 'invoke') { |
||||
|
moduleArguments = Array.prototype.slice.call( moduleArguments, 1 ); |
||||
|
} |
||||
|
return module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) ); |
||||
|
} |
||||
|
// initializing
|
||||
|
module.initialize(); |
||||
|
}) |
||||
|
; |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
$.fn.colorize.settings = { |
||||
|
moduleName : 'Image Colorizer', |
||||
|
debug : true, |
||||
|
namespace : 'colorize', |
||||
|
|
||||
|
onDraw: function(overlayContext, imageName, colorName, color) {}, |
||||
|
|
||||
|
// whether to block execution while updating canvas
|
||||
|
async: true, |
||||
|
// object containing names and default values of color regions
|
||||
|
colors: {}, |
||||
|
|
||||
|
metadata: { |
||||
|
image : 'image', |
||||
|
name : 'name' |
||||
|
}, |
||||
|
|
||||
|
errors: { |
||||
|
noImage : 'No tracing image specified', |
||||
|
undefinedColors : 'No default colors specified.', |
||||
|
missingColor : 'Attempted to change color that does not exist', |
||||
|
missingPlugin : 'Blend onto plug-in must be included', |
||||
|
undefinedHeight : 'The width or height of image canvas could not be automatically determined. Please specify a height.' |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,104 @@ |
|||||
|
/* ****************************** |
||||
|
Default Text (Form) |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit April 08, 2012 |
||||
|
|
||||
|
Refactored Aug 13, 2012 |
||||
|
|
||||
|
allows you to set a default text value which will be added and removed on form field focus |
||||
|
|
||||
|
****************************** */ |
||||
|
;(function ( $, window, document, undefined ) { |
||||
|
|
||||
|
$.fn.defaultText = function(parameters) { |
||||
|
var |
||||
|
// overload for shorthand to default value
|
||||
|
settings = (typeof parameters == 'string') |
||||
|
? $.extend({}, $.fn.defaultText.settings, { defaultValue: parameters }) |
||||
|
: $.extend(true, {}, $.fn.defaultText.settings, parameters) |
||||
|
; |
||||
|
// overload function
|
||||
|
if(typeof parameters == 'string') { |
||||
|
parameters = { defaultValue: parameters }; |
||||
|
} |
||||
|
$.extend(settings, parameters); |
||||
|
$(this) |
||||
|
.each(function() { |
||||
|
var |
||||
|
$element = $(this), |
||||
|
module = { |
||||
|
|
||||
|
checkDefault: function() { |
||||
|
if($element.val().toLowerCase() != settings.defaultValue.toLowerCase()) { |
||||
|
$element.addClass(settings.filledClass); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
placeholder: { |
||||
|
add: function(){ |
||||
|
if( $element.filter(settings.disabledClassList).size() === 0 ) { |
||||
|
if( $element.val() == settings.replaceValue ) { |
||||
|
if(settings.alwaysReplace) { |
||||
|
$element |
||||
|
.removeClass(settings.filledClass) |
||||
|
.val($element.attr('last')) |
||||
|
.removeAttr('last') |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$element |
||||
|
.removeClass(settings.filledClass) |
||||
|
.val(settings.defaultValue) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
$element |
||||
|
.addClass(settings.filledClass) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
remove: function() { |
||||
|
if( $element.filter(settings.disabledClassList).size() === 0 ) { |
||||
|
if(settings.alwaysReplace) { |
||||
|
$element |
||||
|
.attr('last', $element.val()) |
||||
|
.val(settings.replaceValue) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
if( $element.val().toLowerCase() == settings.defaultValue.toLowerCase() ) { |
||||
|
$element |
||||
|
.val(settings.replaceValue) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
; |
||||
|
if(settings.defaultValue == 'auto') { |
||||
|
settings.defaultValue = $(this).val(); |
||||
|
} |
||||
|
$element |
||||
|
.on('focus', module.placeholder.remove) |
||||
|
.on('blur', module.placeholder.add) |
||||
|
; |
||||
|
// check for user value on load
|
||||
|
module.checkDefault(); |
||||
|
}) |
||||
|
; |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
$.fn.defaultText.settings = { |
||||
|
defaultValue : 'auto', |
||||
|
replaceValue : '', |
||||
|
alwaysReplace : false, |
||||
|
disabledClassList : '.readonly, .disabled', |
||||
|
filledClass : 'filled' |
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,649 @@ |
|||||
|
/* ****************************** |
||||
|
Module |
||||
|
State |
||||
|
Change text based on state context |
||||
|
Hover/Pressed/Active/Inactive |
||||
|
Author: Jack Lukic |
||||
|
Last revision: May 2012 |
||||
|
|
||||
|
State text module is used to apply text to a given node |
||||
|
depending on the elements "state" |
||||
|
|
||||
|
State is either defined as "active" or "inactive" depending |
||||
|
on the returned value of a test function |
||||
|
|
||||
|
Usage: |
||||
|
|
||||
|
$button |
||||
|
.state({ |
||||
|
states: { |
||||
|
active: true |
||||
|
}, |
||||
|
text: { |
||||
|
inactive: 'Follow', |
||||
|
active : 'Following', |
||||
|
enable : 'Add', |
||||
|
disable : 'Remove' |
||||
|
} |
||||
|
}) |
||||
|
; |
||||
|
|
||||
|
"Follow", turns to "Add" on hover, then "Following" on active |
||||
|
and finally "Remove" on active hover |
||||
|
|
||||
|
This plugin works in correlation to API module and will, by default, |
||||
|
use deffered object accept/reject to determine state. |
||||
|
|
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ( $, window, document, undefined ) { |
||||
|
|
||||
|
$.fn.state = function(parameters) { |
||||
|
var |
||||
|
|
||||
|
$allModules = $(this), |
||||
|
|
||||
|
// make available in scope
|
||||
|
selector = $allModules.selector || '', |
||||
|
query = arguments[0], |
||||
|
passedArguments = [].slice.call(arguments, 1), |
||||
|
|
||||
|
// set up performance tracking
|
||||
|
time = new Date().getTime(), |
||||
|
performance = [], |
||||
|
|
||||
|
invokedResponse |
||||
|
; |
||||
|
$allModules |
||||
|
.each(function() { |
||||
|
var |
||||
|
$module = $(this), |
||||
|
|
||||
|
settings = $.extend(true, {}, $.fn.state.settings, parameters), |
||||
|
|
||||
|
element = this, |
||||
|
instance = $module.data('module-' + settings.namespace), |
||||
|
methodInvoked = (typeof query == 'string'), |
||||
|
|
||||
|
// shortcuts
|
||||
|
namespace = settings.namespace, |
||||
|
metadata = settings.metadata, |
||||
|
className = settings.className, |
||||
|
states = settings.states, |
||||
|
text = settings.text, |
||||
|
|
||||
|
module |
||||
|
; |
||||
|
module = { |
||||
|
|
||||
|
initialize: function() { |
||||
|
module.verbose('Initializing module', element); |
||||
|
|
||||
|
// allow module to guess desired state based on element
|
||||
|
if(settings.automatic) { |
||||
|
module.add.defaults(); |
||||
|
} |
||||
|
|
||||
|
// bind events with delegated events
|
||||
|
if(settings.context && selector !== '') { |
||||
|
if( module.allows('hover') ) { |
||||
|
$(element, settings.context) |
||||
|
.on(selector, 'mouseenter.' + namespace, module.hover.enable) |
||||
|
.on(selector, 'mouseleave.' + namespace, module.hover.disable) |
||||
|
; |
||||
|
} |
||||
|
if( module.allows('pressed') ) { |
||||
|
$(element, settings.context) |
||||
|
.on(selector, 'mousedown.' + namespace, module.pressed.enable) |
||||
|
.on(selector, 'mouseup.' + namespace, module.pressed.disable) |
||||
|
; |
||||
|
} |
||||
|
if( module.allows('focus') ) { |
||||
|
$(element, settings.context) |
||||
|
.on(selector, 'focus.' + namespace, module.focus.enable) |
||||
|
.on(selector, 'blur.' + namespace, module.focus.disable) |
||||
|
; |
||||
|
} |
||||
|
$(settings.context) |
||||
|
.on(selector, 'mouseenter.' + namespace, module.text.change) |
||||
|
.on(selector, 'mouseleave.' + namespace, module.text.reset) |
||||
|
.on(selector, 'click.' + namespace, module.toggle) |
||||
|
; |
||||
|
|
||||
|
} |
||||
|
else { |
||||
|
if( module.allows('hover') ) { |
||||
|
$module |
||||
|
.on('mouseenter.' + namespace, module.hover.enable) |
||||
|
.on('mouseleave.' + namespace, module.hover.disable) |
||||
|
; |
||||
|
} |
||||
|
if( module.allows('pressed') ) { |
||||
|
$module |
||||
|
.on('mousedown.' + namespace, module.pressed.enable) |
||||
|
.on('mouseup.' + namespace, module.pressed.disable) |
||||
|
; |
||||
|
} |
||||
|
if( module.allows('focus') ) { |
||||
|
$module |
||||
|
.on('focus.' + namespace, module.focus.enable) |
||||
|
.on('blur.' + namespace, module.focus.disable) |
||||
|
; |
||||
|
} |
||||
|
$module |
||||
|
.on('mouseenter.' + namespace, module.text.change) |
||||
|
.on('mouseleave.' + namespace, module.text.reset) |
||||
|
.on('click.' + namespace, module.toggle) |
||||
|
; |
||||
|
} |
||||
|
$module |
||||
|
.data('module-' + namespace, module) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
destroy: function() { |
||||
|
module.verbose('Destroying previous module', element); |
||||
|
$module |
||||
|
.off('.' + namespace) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
refresh: function() { |
||||
|
module.verbose('Refreshing selector cache', element); |
||||
|
$module = $(element); |
||||
|
}, |
||||
|
|
||||
|
add: { |
||||
|
defaults: function() { |
||||
|
var |
||||
|
userStates = parameters && $.isPlainObject(parameters.states) |
||||
|
? parameters.states |
||||
|
: {} |
||||
|
; |
||||
|
$.each(settings.defaults, function(type, typeStates) { |
||||
|
if( module.is[type] !== undefined && module.is[type]() ) { |
||||
|
module.verbose('Adding default states', type, element); |
||||
|
$.extend(settings.states, typeStates, userStates); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
is: { |
||||
|
|
||||
|
active: function() { |
||||
|
return $module.hasClass(className.active); |
||||
|
}, |
||||
|
loading: function() { |
||||
|
return $module.hasClass(className.loading); |
||||
|
}, |
||||
|
inactive: function() { |
||||
|
return !( $module.hasClass(className.active) ); |
||||
|
}, |
||||
|
|
||||
|
enabled: function() { |
||||
|
return !( $module.is(settings.filter.active) ); |
||||
|
}, |
||||
|
disabled: function() { |
||||
|
return ( $module.is(settings.filter.active) ); |
||||
|
}, |
||||
|
textEnabled: function() { |
||||
|
return !( $module.is(settings.filter.text) ); |
||||
|
}, |
||||
|
|
||||
|
// definitions for automatic type detection
|
||||
|
button: function() { |
||||
|
return $module.is('.button:not(a, .submit)'); |
||||
|
}, |
||||
|
input: function() { |
||||
|
return $module.is('input'); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
allows: function(state) { |
||||
|
return states[state] || false; |
||||
|
}, |
||||
|
enable: function(state) { |
||||
|
if(module.allows(state)) { |
||||
|
$module.addClass( className[state] ); |
||||
|
} |
||||
|
}, |
||||
|
disable: function(state) { |
||||
|
if(module.allows(state)) { |
||||
|
$module.removeClass( className[state] ); |
||||
|
} |
||||
|
}, |
||||
|
textFor: function(state) { |
||||
|
return text[state] || false; |
||||
|
}, |
||||
|
|
||||
|
focus : { |
||||
|
enable: function() { |
||||
|
$module.addClass(className.focus); |
||||
|
}, |
||||
|
disable: function() { |
||||
|
$module.removeClass(className.focus); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
hover : { |
||||
|
enable: function() { |
||||
|
$module.addClass(className.hover); |
||||
|
}, |
||||
|
disable: function() { |
||||
|
$module.removeClass(className.hover); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
pressed : { |
||||
|
enable: function() { |
||||
|
$module |
||||
|
.addClass(className.pressed) |
||||
|
.one('mouseleave', module.pressed.disable) |
||||
|
; |
||||
|
}, |
||||
|
disable: function() { |
||||
|
$module.removeClass(className.pressed); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// determines method for state activation
|
||||
|
toggle: function() { |
||||
|
var |
||||
|
apiRequest = $module.data(metadata.promise) |
||||
|
; |
||||
|
if( module.allows('active') && module.is.enabled() ) { |
||||
|
module.refresh(); |
||||
|
if(apiRequest !== undefined) { |
||||
|
module.listenTo(apiRequest); |
||||
|
} |
||||
|
else { |
||||
|
module.change(); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
listenTo: function(apiRequest) { |
||||
|
module.debug('API request detected, waiting for state signal', apiRequest); |
||||
|
if(apiRequest) { |
||||
|
if(text.loading) { |
||||
|
module.text.update(text.loading); |
||||
|
} |
||||
|
$.when(apiRequest) |
||||
|
.then(function() { |
||||
|
if(apiRequest.state() == 'resolved') { |
||||
|
module.debug('API request succeeded'); |
||||
|
settings.activateTest = function(){ return true; }; |
||||
|
settings.deactivateTest = function(){ return true; }; |
||||
|
} |
||||
|
else { |
||||
|
module.debug('API request failed'); |
||||
|
settings.activateTest = function(){ return false; }; |
||||
|
settings.deactivateTest = function(){ return false; }; |
||||
|
} |
||||
|
module.change(); |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
// xhr exists but set to false, beforeSend killed the xhr
|
||||
|
else { |
||||
|
settings.activateTest = function(){ return false; }; |
||||
|
settings.deactivateTest = function(){ return false; }; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// checks whether active/inactive state can be given
|
||||
|
change: function() { |
||||
|
module.debug('Determining state change direction'); |
||||
|
// inactive to active change
|
||||
|
if( module.is.inactive() ) { |
||||
|
module.activate(); |
||||
|
} |
||||
|
else { |
||||
|
module.deactivate(); |
||||
|
} |
||||
|
if(settings.sync) { |
||||
|
module.sync(); |
||||
|
} |
||||
|
settings.onChange(); |
||||
|
}, |
||||
|
|
||||
|
activate: function() { |
||||
|
if( $.proxy(settings.activateTest, element)() ) { |
||||
|
module.debug('Setting state to active'); |
||||
|
$module |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
module.text.update(text.active); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
deactivate: function() { |
||||
|
if($.proxy(settings.deactivateTest, element)() ) { |
||||
|
module.debug('Setting state to inactive'); |
||||
|
$module |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
module.text.update(text.inactive); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
sync: function() { |
||||
|
module.verbose('Syncing other buttons to current state'); |
||||
|
if( module.is.active() ) { |
||||
|
$allModules |
||||
|
.not($module) |
||||
|
.state('activate'); |
||||
|
} |
||||
|
else { |
||||
|
$allModules |
||||
|
.not($module) |
||||
|
.state('deactivate') |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
text: { |
||||
|
|
||||
|
// finds text node to update
|
||||
|
get: function() { |
||||
|
return (settings.selector.text) |
||||
|
? $module.find(settings.selector.text).text() |
||||
|
: $module.html() |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
flash: function(text, duration) { |
||||
|
var |
||||
|
previousText = module.text.get() |
||||
|
; |
||||
|
text = text || settings.text.flash; |
||||
|
duration = duration || settings.flashDuration; |
||||
|
module.text.update(text); |
||||
|
setTimeout(function(){ |
||||
|
module.text.update(previousText); |
||||
|
}, duration); |
||||
|
}, |
||||
|
|
||||
|
change: function() { |
||||
|
module.verbose('Checking if text should be changed'); |
||||
|
if( module.is.textEnabled() ) { |
||||
|
if( module.is.active() ) { |
||||
|
if(text.hover) { |
||||
|
module.verbose('Changing text to hover text', text.hover); |
||||
|
module.text.update(text.hover); |
||||
|
} |
||||
|
else if(text.disable) { |
||||
|
module.verbose('Changing text to disable text', text.disable); |
||||
|
module.text.update(text.disable); |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
if(text.hover) { |
||||
|
module.verbose('Changing text to hover text', text.disable); |
||||
|
module.text.update(text.hover); |
||||
|
} |
||||
|
else if(text.enable){ |
||||
|
module.verbose('Changing text to enable text', text.disable); |
||||
|
module.text.update(text.enable); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// on mouseout sets text to previous value
|
||||
|
reset : function() { |
||||
|
var |
||||
|
activeText = text.active || $module.data(metadata.storedText), |
||||
|
inactiveText = text.inactive || $module.data(metadata.storedText) |
||||
|
; |
||||
|
if( module.is.textEnabled() ) { |
||||
|
if( module.is.active() && activeText) { |
||||
|
module.verbose('Resetting active text', activeText); |
||||
|
module.text.update(activeText); |
||||
|
} |
||||
|
else if(inactiveText) { |
||||
|
module.verbose('Resetting inactive text', activeText); |
||||
|
module.text.update(inactiveText); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
update: function(text) { |
||||
|
var |
||||
|
currentText = module.text.get() |
||||
|
; |
||||
|
if(text && text !== currentText) { |
||||
|
module.debug('Updating text', text); |
||||
|
if(settings.selector.text) { |
||||
|
$module |
||||
|
.data(metadata.storedText, text) |
||||
|
.find(settings.selector.text) |
||||
|
.text(text) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$module |
||||
|
.data(metadata.storedText, text) |
||||
|
.html(text) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
/* standard module */ |
||||
|
setting: function(name, value) { |
||||
|
if(value === undefined) { |
||||
|
return settings[name]; |
||||
|
} |
||||
|
settings[name] = value; |
||||
|
}, |
||||
|
performance: { |
||||
|
log: function(message) { |
||||
|
var |
||||
|
currentTime, |
||||
|
executionTime |
||||
|
; |
||||
|
if(settings.performance) { |
||||
|
currentTime = new Date().getTime(); |
||||
|
executionTime = currentTime - time; |
||||
|
time = currentTime; |
||||
|
performance.push({ |
||||
|
'Name' : message, |
||||
|
'Execution Time' : executionTime |
||||
|
}); |
||||
|
clearTimeout(module.performance.timer); |
||||
|
module.performance.timer = setTimeout(module.performance.display, 100); |
||||
|
} |
||||
|
}, |
||||
|
display: function() { |
||||
|
var |
||||
|
title = settings.moduleName + ' Performance (' + selector + ')', |
||||
|
caption = settings.moduleName + ': ' + selector + '(' + $allModules.size() + ' elements)' |
||||
|
; |
||||
|
if(console.group !== undefined && performance.length > 0) { |
||||
|
console.groupCollapsed(title); |
||||
|
if(console.table) { |
||||
|
console.table(performance); |
||||
|
} |
||||
|
else { |
||||
|
$.each(performance, function(index, data) { |
||||
|
console.log(data['Name'] + ':' + data['Execution Time']); |
||||
|
}); |
||||
|
} |
||||
|
console.groupEnd(); |
||||
|
performance = []; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
verbose: function() { |
||||
|
if(settings.verbose && settings.debug) { |
||||
|
module.performance.log(arguments[0]); |
||||
|
module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':'); |
||||
|
} |
||||
|
}, |
||||
|
debug: function() { |
||||
|
if(settings.debug) { |
||||
|
module.performance.log(arguments[0]); |
||||
|
module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':'); |
||||
|
} |
||||
|
}, |
||||
|
error: function() { |
||||
|
if(console.log !== undefined) { |
||||
|
module.error = Function.prototype.bind.call(console.log, console, settings.moduleName + ':'); |
||||
|
} |
||||
|
}, |
||||
|
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 { |
||||
|
if(instance !== undefined) { |
||||
|
module.destroy(); |
||||
|
} |
||||
|
module.initialize(); |
||||
|
} |
||||
|
}) |
||||
|
; |
||||
|
// chain or return queried method
|
||||
|
return (invokedResponse !== undefined) |
||||
|
? invokedResponse |
||||
|
: this |
||||
|
; |
||||
|
}; |
||||
|
|
||||
|
$.fn.state.settings = { |
||||
|
|
||||
|
// module info
|
||||
|
moduleName : 'State Module', |
||||
|
|
||||
|
// debug output
|
||||
|
debug : true, |
||||
|
|
||||
|
// verbose debug output
|
||||
|
verbose : false, |
||||
|
|
||||
|
// namespace for events
|
||||
|
namespace : 'state', |
||||
|
|
||||
|
// debug data includes performance
|
||||
|
performance: true, |
||||
|
|
||||
|
// callback occurs on state change
|
||||
|
onChange: function() {}, |
||||
|
|
||||
|
// state test functions
|
||||
|
activateTest : function() { return true; }, |
||||
|
deactivateTest : function() { return true; }, |
||||
|
|
||||
|
// whether to automatically map default states
|
||||
|
automatic : true, |
||||
|
|
||||
|
// activate / deactivate changes all elements instantiated at same time
|
||||
|
sync : false, |
||||
|
|
||||
|
// default flash text duration, used for temporarily changing text of an element
|
||||
|
flashDuration : 3000, |
||||
|
|
||||
|
// selector filter
|
||||
|
filter : { |
||||
|
text : '.loading, .disabled', |
||||
|
active : '.disabled' |
||||
|
}, |
||||
|
|
||||
|
context : false, |
||||
|
// errors
|
||||
|
errors: { |
||||
|
method : 'The method you called is not defined.' |
||||
|
}, |
||||
|
|
||||
|
// metadata
|
||||
|
metadata: { |
||||
|
promise : 'promise', |
||||
|
storedText : 'stored-text' |
||||
|
}, |
||||
|
|
||||
|
// change class on state
|
||||
|
className: { |
||||
|
focus : 'focus', |
||||
|
hover : 'hover', |
||||
|
pressed : 'down', |
||||
|
active : 'active', |
||||
|
loading : 'loading' |
||||
|
}, |
||||
|
|
||||
|
selector: { |
||||
|
// selector for text node
|
||||
|
text: false |
||||
|
}, |
||||
|
|
||||
|
defaults : { |
||||
|
input: { |
||||
|
hover : true, |
||||
|
focus : true, |
||||
|
pressed : true, |
||||
|
loading : false, |
||||
|
active : false |
||||
|
}, |
||||
|
button: { |
||||
|
hover : true, |
||||
|
focus : false, |
||||
|
pressed : true, |
||||
|
active : false, |
||||
|
loading : true |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
states : { |
||||
|
hover : true, |
||||
|
focus : true, |
||||
|
pressed : true, |
||||
|
loading : false, |
||||
|
active : false |
||||
|
}, |
||||
|
|
||||
|
text : { |
||||
|
flash : false, |
||||
|
hover : false, |
||||
|
active : false, |
||||
|
inactive : false, |
||||
|
enable : false, |
||||
|
disable : false |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,408 @@ |
|||||
|
/* ****************************** |
||||
|
Form Validation Components |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit April 08, 2012 |
||||
|
|
||||
|
Refactored Feb 22, 2012 |
||||
|
|
||||
|
Allows you to validate forms based on a form validation object |
||||
|
Form validation objects are bound by either data-validate="" metadata, or form id or name tags |
||||
|
|
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ( $, window, document, undefined ) { |
||||
|
|
||||
|
$.fn.validateForm = function(fields, parameters) { |
||||
|
var |
||||
|
$allModules = $(this), |
||||
|
|
||||
|
settings = $.extend(true, {}, $.fn.validateForm.settings, parameters), |
||||
|
// make arguments available
|
||||
|
query = arguments[0], |
||||
|
passedArguments = [].slice.call(arguments, 1), |
||||
|
invokedResponse |
||||
|
; |
||||
|
$allModules |
||||
|
.each(function() { |
||||
|
var |
||||
|
$module = $(this), |
||||
|
$group = $(this).find(settings.selector.group), |
||||
|
$field = $(this).find(settings.selector.field), |
||||
|
$errorPrompt = $(this).find(settings.selector.prompt), |
||||
|
|
||||
|
formErrors = [], |
||||
|
|
||||
|
selector = $module.selector || '', |
||||
|
element = this, |
||||
|
instance = $module.data('module-' + settings.namespace), |
||||
|
methodInvoked = (typeof query == 'string'), |
||||
|
|
||||
|
namespace = settings.namespace, |
||||
|
metadata = settings.metadata, |
||||
|
className = settings.className, |
||||
|
errors = settings.errors, |
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
initialize: function() { |
||||
|
module.verbose('Initializing form validation'); |
||||
|
if(fields !== undefined || !$.isEmptyObject(fields) ) { |
||||
|
// add default text if set
|
||||
|
if($.fn.defaultText !== undefined) { |
||||
|
$.each(fields, function(fieldName, field) { |
||||
|
module.field.add.defaultText(field); |
||||
|
}); |
||||
|
} |
||||
|
// attach event handler
|
||||
|
$module |
||||
|
.on('submit.' + namespace, module.validate.form) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
module.error(errors.noFields, $module); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
destroy: function() { |
||||
|
$module |
||||
|
.off(namespace) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
field: { |
||||
|
find: function(identifier) { |
||||
|
var |
||||
|
$field = $module.find(settings.selector.field) |
||||
|
; |
||||
|
if( $field.filter('#' + identifier).size() > 0 ) { |
||||
|
return $field.filter('#' + identifier); |
||||
|
} |
||||
|
else if( $field.filter('[name="' + identifier +'"]').size() > 0 ) { |
||||
|
return $field.filter('[name="' + identifier +'"]'); |
||||
|
} |
||||
|
else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').size() > 0 ) { |
||||
|
return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]'); |
||||
|
} |
||||
|
return $('<input/>'); |
||||
|
}, |
||||
|
add: { |
||||
|
defaultText: function(field) { |
||||
|
var |
||||
|
$field = module.field.find(field.identifier) |
||||
|
; |
||||
|
if(field.defaultText !== undefined) { |
||||
|
$field.defaultText(field.defaultText); |
||||
|
} |
||||
|
}, |
||||
|
error: function(field, errors) { |
||||
|
var |
||||
|
$field = module.field.find(field.identifier), |
||||
|
$errorGroup = $field.closest($group), |
||||
|
$errorPrompt = $group.find($errorPrompt), |
||||
|
promptExists = ($errorPrompt.size() !== 0) |
||||
|
; |
||||
|
$errorGroup |
||||
|
.addClass(className.error) |
||||
|
; |
||||
|
if(settings.inlineError) { |
||||
|
// create message container on first invalid validation attempt
|
||||
|
if(!promptExists) { |
||||
|
$errorPrompt = $('<div />') |
||||
|
.addClass(className.prompt) |
||||
|
.insertBefore($field) |
||||
|
; |
||||
|
} |
||||
|
// add prompt message
|
||||
|
$errorPrompt |
||||
|
.html(errors[0]) |
||||
|
.fadeIn(settings.animateSpeed) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
remove: { |
||||
|
error: function(field) { |
||||
|
var |
||||
|
$field = module.field.find(field.identifier), |
||||
|
$errorGroup = $field.closest($group), |
||||
|
$errorPrompt = $group.find($errorPrompt) |
||||
|
; |
||||
|
$errorGroup |
||||
|
.removeClass(className.error) |
||||
|
; |
||||
|
if(settings.inlineError) { |
||||
|
$errorPrompt.hide(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
validate: { |
||||
|
|
||||
|
form: function(event) { |
||||
|
var |
||||
|
allValid = true |
||||
|
; |
||||
|
// reset errors
|
||||
|
formErrors = []; |
||||
|
$.each(fields, function(fieldName, field){ |
||||
|
// form is invalid after first bad field, but keep checking
|
||||
|
if( !( module.validate.field(field) ) ) { |
||||
|
allValid = false; |
||||
|
} |
||||
|
}); |
||||
|
// Evaluate form callbacks
|
||||
|
return (allValid) |
||||
|
? $.proxy(settings.onSuccess, this)(event) |
||||
|
: $.proxy(settings.onFailure, this)(formErrors) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
// takes a validation object and returns whether field passes validation
|
||||
|
field: function(field) { |
||||
|
var |
||||
|
$field = module.field.find(field.identifier), |
||||
|
fieldValid = true, |
||||
|
fieldErrors = [] |
||||
|
; |
||||
|
if(field.rules !== undefined) { |
||||
|
// iterate over all validation types for a certain field
|
||||
|
$.each(field.rules, function(index, rule) { |
||||
|
if( !( module.validate.rule(field, rule) ) ) { |
||||
|
module.debug('Field is invalid', field.identifier, rule.type); |
||||
|
fieldErrors.push(rule.prompt); |
||||
|
fieldValid = false; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
if(fieldValid) { |
||||
|
module.field.remove.error(field, fieldErrors); |
||||
|
settings.onValid($field); |
||||
|
} |
||||
|
else { |
||||
|
formErrors = formErrors.concat(fieldErrors); |
||||
|
module.field.add.error(field, fieldErrors); |
||||
|
$.proxy(settings.onInvalid, $field)(fieldErrors); |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
}, |
||||
|
|
||||
|
// takes validation rule and returns whether field passes rule
|
||||
|
rule: function(field, validation) { |
||||
|
var |
||||
|
$field = module.field.find(field.identifier), |
||||
|
type = validation.type, |
||||
|
defaultText = (field.defaultText !== undefined) |
||||
|
? field.defaultText |
||||
|
: false, |
||||
|
value = ($field.val() == defaultText) |
||||
|
? '' |
||||
|
: $field.val(), |
||||
|
|
||||
|
bracketRegExp = /\[(.*?)\]/i, |
||||
|
bracket = bracketRegExp.exec(type), |
||||
|
isValid = true, |
||||
|
ancillary, |
||||
|
functionType |
||||
|
; |
||||
|
// if bracket notation is used, pass in extra parameters
|
||||
|
if(bracket !== undefined && bracket != null) { |
||||
|
ancillary = bracket[1]; |
||||
|
functionType = type.replace(bracket[0], ''); |
||||
|
isValid = $.proxy(settings.rules[functionType], $module)(value, ancillary); |
||||
|
} |
||||
|
// normal notation
|
||||
|
else { |
||||
|
isValid = (type == 'checked') |
||||
|
? $field.filter(':checked').size() > 0 |
||||
|
: settings.rules[type](value) |
||||
|
; |
||||
|
} |
||||
|
return isValid; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* standard module */ |
||||
|
setting: function(name, value) { |
||||
|
if(value === undefined) { |
||||
|
return settings[name]; |
||||
|
} |
||||
|
settings[name] = value; |
||||
|
}, |
||||
|
verbose: function() { |
||||
|
if(settings.verbose) { |
||||
|
module.debug.apply(this, arguments); |
||||
|
} |
||||
|
}, |
||||
|
debug: function() { |
||||
|
var |
||||
|
output = [], |
||||
|
message = settings.moduleName + ': ' + arguments[0], |
||||
|
variables = [].slice.call( arguments, 1 ), |
||||
|
log = console.info || console.log || function(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
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(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
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(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.validateForm.settings = { |
||||
|
|
||||
|
// module info
|
||||
|
moduleName : 'Validate Form Module', |
||||
|
debug : true, |
||||
|
verbose : false, |
||||
|
namespace : 'validate', |
||||
|
|
||||
|
animateSpeed : 150, |
||||
|
inlineError : false, |
||||
|
|
||||
|
onValid : function() {}, |
||||
|
onInvalid : function() {}, |
||||
|
onSuccess : function() { return true; }, |
||||
|
onFailure : function() { return false; }, |
||||
|
|
||||
|
metadata : { |
||||
|
validate: 'validate' |
||||
|
}, |
||||
|
|
||||
|
// errors
|
||||
|
errors: { |
||||
|
method : 'The method you called is not defined.', |
||||
|
noFields : 'No validation object specified.' |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
selector : { |
||||
|
group : '.field', |
||||
|
prompt : '.prompt', |
||||
|
field : 'input, textarea, select' |
||||
|
}, |
||||
|
|
||||
|
className : { |
||||
|
error : 'error', |
||||
|
prompt : 'prompt' |
||||
|
}, |
||||
|
|
||||
|
rules: { |
||||
|
empty: function(value) { |
||||
|
return !(value === undefined || '' === value); |
||||
|
}, |
||||
|
email: function(value){ |
||||
|
var |
||||
|
emailRegExp = new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?") |
||||
|
; |
||||
|
return emailRegExp.test(value); |
||||
|
}, |
||||
|
length: function(value, requiredLength) { |
||||
|
return (value !== undefined) |
||||
|
? (value.length >= requiredLength) |
||||
|
: false |
||||
|
; |
||||
|
}, |
||||
|
not: function(value, notValue) { |
||||
|
return (value != notValue); |
||||
|
}, |
||||
|
maxLength: function(value, maxLength) { |
||||
|
return (value !== undefined) |
||||
|
? (value.length <= maxLength) |
||||
|
: false |
||||
|
; |
||||
|
}, |
||||
|
match: function(value, matchingField) { |
||||
|
// use either id or name of field
|
||||
|
var |
||||
|
$form = $(this), |
||||
|
matchingValue |
||||
|
; |
||||
|
if($form.find('#' + matchingField).size() > 0) { |
||||
|
matchingValue = $form.find('#' + matchingField).val(); |
||||
|
} |
||||
|
else if($form.find('[name=' + matchingField +']').size() > 0) { |
||||
|
matchingValue = $form.find('[name=' + matchingField + ']').val(); |
||||
|
} |
||||
|
else if( $form.find('[data-validate="'+ matchingField +'"]').size() > 0 ) { |
||||
|
matchingValue = $form.find('[data-validate="'+ matchingField +'"]').val(); |
||||
|
} |
||||
|
return (matchingValue !== undefined) |
||||
|
? ( value.toString() == matchingValue.toString() ) |
||||
|
: false |
||||
|
; |
||||
|
}, |
||||
|
url: function(value) { |
||||
|
var |
||||
|
urlRegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ |
||||
|
; |
||||
|
return urlRegExp.test(value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,697 @@ |
|||||
|
/* ****************************** |
||||
|
Module - Chat Room |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit Aug 8, 2012 |
||||
|
|
||||
|
Designed as a simple modular chat component |
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ($, window, document, undefined) { |
||||
|
|
||||
|
$.fn.chat = function(key, channelName, parameters) { |
||||
|
var |
||||
|
settings = $.extend(true, {}, $.fn.chat.settings, parameters), |
||||
|
// hoist arguments
|
||||
|
moduleArguments = arguments || false |
||||
|
; |
||||
|
$(this) |
||||
|
.each(function() { |
||||
|
var |
||||
|
$module = $(this), |
||||
|
$expandButton = $module.find(settings.selector.expandButton), |
||||
|
$userListButton = $module.find(settings.selector.userListButton), |
||||
|
$userList = $module.find(settings.selector.userList), |
||||
|
$room = $module.find(settings.selector.room), |
||||
|
$userCount = $module.find(settings.selector.userCount), |
||||
|
|
||||
|
$log = $module.find(settings.selector.log), |
||||
|
$message = $module.find(settings.selector.message), |
||||
|
|
||||
|
$messageInput = $module.find(settings.selector.messageInput), |
||||
|
$messageButton = $module.find(settings.selector.messageButton), |
||||
|
|
||||
|
instance = $module.data('module'), |
||||
|
|
||||
|
className = settings.className, |
||||
|
namespace = settings.namespace, |
||||
|
|
||||
|
html = '', |
||||
|
users = {}, |
||||
|
loggedInUser, |
||||
|
|
||||
|
message, |
||||
|
count, |
||||
|
|
||||
|
height, |
||||
|
|
||||
|
pusher, |
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
channel: false, |
||||
|
width: { |
||||
|
log : $log.width(), |
||||
|
userList : $userList.outerWidth() |
||||
|
}, |
||||
|
|
||||
|
initialize: function() { |
||||
|
|
||||
|
// check error conditions
|
||||
|
if(Pusher === undefined) { |
||||
|
module.error(settings.errors.pusher); |
||||
|
} |
||||
|
if(key === undefined || channelName === undefined) { |
||||
|
module.error(settings.errors.key); |
||||
|
return false; |
||||
|
} |
||||
|
else if( !(settings.endpoint.message || settings.endpoint.authentication) ) { |
||||
|
module.error(settings.errors.endpoint); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// define pusher
|
||||
|
pusher = new Pusher(key); |
||||
|
Pusher.channel_auth_endpoint = settings.endpoint.authentication; |
||||
|
|
||||
|
module.channel = pusher.subscribe(channelName); |
||||
|
|
||||
|
module.channel.bind('pusher:subscription_succeeded', module.user.list.create); |
||||
|
module.channel.bind('pusher:subscription_error', module.error); |
||||
|
module.channel.bind('pusher:member_added', module.user.joined); |
||||
|
module.channel.bind('pusher:member_removed', module.user.left); |
||||
|
module.channel.bind('update_messages', module.message.receive); |
||||
|
|
||||
|
$.each(settings.customEvents, function(label, value) { |
||||
|
module.channel.bind(label, value); |
||||
|
}); |
||||
|
|
||||
|
// expandable with states
|
||||
|
if( $.fn.hoverClass !== undefined && $.fn.downClass !== undefined ) { |
||||
|
$expandButton |
||||
|
.hoverClass() |
||||
|
.downClass() |
||||
|
; |
||||
|
$userListButton |
||||
|
.hoverClass() |
||||
|
.downClass() |
||||
|
; |
||||
|
$messageButton |
||||
|
.hoverClass() |
||||
|
.downClass() |
||||
|
; |
||||
|
} |
||||
|
// bind module events
|
||||
|
$userListButton |
||||
|
.on('click.' + namespace, module.event.toggleUserList) |
||||
|
; |
||||
|
$expandButton |
||||
|
.on('click.' + namespace, module.event.toggleExpand) |
||||
|
; |
||||
|
$messageInput |
||||
|
.on('keydown.' + namespace, module.event.input.keydown) |
||||
|
.on('keyup.' + namespace, module.event.input.keyup) |
||||
|
; |
||||
|
$messageButton |
||||
|
.on('mouseenter.' + namespace, module.event.hover) |
||||
|
.on('mouseleave.' + namespace, module.event.hover) |
||||
|
.on('click.' + namespace, module.event.submit) |
||||
|
; |
||||
|
// scroll to bottom of chat log
|
||||
|
$log |
||||
|
.animate({ |
||||
|
scrollTop: $log.prop('scrollHeight') |
||||
|
}, 400) |
||||
|
; |
||||
|
$module |
||||
|
.data('module', module) |
||||
|
.addClass(className.loading) |
||||
|
; |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
// refresh module
|
||||
|
refresh: function() { |
||||
|
// reset width calculations
|
||||
|
$userListButton |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
module.width = { |
||||
|
log : $log.width(), |
||||
|
userList : $userList.outerWidth() |
||||
|
}; |
||||
|
if( $userListButton.hasClass(className.active) ) { |
||||
|
module.user.list.hide(); |
||||
|
} |
||||
|
$module.data('module', module); |
||||
|
}, |
||||
|
|
||||
|
user: { |
||||
|
|
||||
|
updateCount: function() { |
||||
|
if(settings.userCount) { |
||||
|
users = $module.data('users'); |
||||
|
count = 0; |
||||
|
$.each(users, function(index){ |
||||
|
count++; |
||||
|
}); |
||||
|
$userCount |
||||
|
.html( settings.templates.userCount(count) ) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// add user to user list
|
||||
|
joined: function(member) { |
||||
|
users = $module.data('users'); |
||||
|
if(member.id != 'anonymous' && users[ member.id ] === undefined ) { |
||||
|
users[ member.id ] = member.info; |
||||
|
if(settings.randomColor && member.info.color === undefined) { |
||||
|
member.info.color = settings.templates.color(member.id); |
||||
|
} |
||||
|
html = settings.templates.userList(member.info); |
||||
|
if(member.info.isAdmin) { |
||||
|
$(html) |
||||
|
.prependTo($userList) |
||||
|
.preview({ |
||||
|
type : 'user', |
||||
|
placement : 'left' |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$(html) |
||||
|
.appendTo($userList) |
||||
|
.preview({ |
||||
|
type : 'user', |
||||
|
placement : 'left' |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
if( $.fn.preview !== undefined ) { |
||||
|
$userList |
||||
|
.children() |
||||
|
.last() |
||||
|
.preview({ |
||||
|
type: 'user', |
||||
|
placement: 'left' |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
if(settings.partingMessages) { |
||||
|
$log |
||||
|
.append( settings.templates.joined(member.info) ) |
||||
|
; |
||||
|
module.message.scroll.test(); |
||||
|
} |
||||
|
module.user.updateCount(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// remove user from user list
|
||||
|
left: function(member) { |
||||
|
users = $module.data('users'); |
||||
|
if(member !== undefined && member.id !== 'anonymous') { |
||||
|
delete users[ member.id ]; |
||||
|
$module |
||||
|
.data('users', users) |
||||
|
; |
||||
|
$userList |
||||
|
.find('[data-id='+ member.id + ']') |
||||
|
.remove() |
||||
|
; |
||||
|
if(settings.partingMessages) { |
||||
|
$log |
||||
|
.append( settings.templates.left(member.info) ) |
||||
|
; |
||||
|
module.message.scroll.test(); |
||||
|
} |
||||
|
module.user.updateCount(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
list: { |
||||
|
|
||||
|
// receives list of members and generates user list
|
||||
|
create: function(members) { |
||||
|
users = {}; |
||||
|
members.each(function(member) { |
||||
|
if(member.id !== 'anonymous' && member.id !== 'undefined') { |
||||
|
if(settings.randomColor && member.info.color === undefined) { |
||||
|
member.info.color = settings.templates.color(member.id); |
||||
|
} |
||||
|
// sort list with admin first
|
||||
|
html = (member.info.isAdmin) |
||||
|
? settings.templates.userList(member.info) + html |
||||
|
: html + settings.templates.userList(member.info) |
||||
|
; |
||||
|
users[ member.id ] = member.info; |
||||
|
} |
||||
|
}); |
||||
|
$module |
||||
|
.data('users', users) |
||||
|
.data('user', users[members.me.id] ) |
||||
|
.removeClass(className.loading) |
||||
|
; |
||||
|
$userList |
||||
|
.html(html) |
||||
|
; |
||||
|
if( $.fn.preview !== undefined ) { |
||||
|
$userList |
||||
|
.children() |
||||
|
.preview({ |
||||
|
type: 'user', |
||||
|
placement: 'left' |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
module.user.updateCount(); |
||||
|
$.proxy(settings.onJoin, $userList.children())(); |
||||
|
}, |
||||
|
|
||||
|
// shows user list
|
||||
|
show: function() { |
||||
|
$log |
||||
|
.animate({ |
||||
|
width: (module.width.log - module.width.userList) |
||||
|
}, { |
||||
|
duration : settings.speed, |
||||
|
easing : settings.easing, |
||||
|
complete : module.message.scroll.move |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
// hides user list
|
||||
|
hide: function() { |
||||
|
$log |
||||
|
.stop() |
||||
|
.animate({ |
||||
|
width: (module.width.log) |
||||
|
}, { |
||||
|
duration : settings.speed, |
||||
|
easing : settings.easing, |
||||
|
complete : module.message.scroll.move |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
message: { |
||||
|
|
||||
|
// handles scrolling of chat log
|
||||
|
scroll: { |
||||
|
test: function() { |
||||
|
height = $log.prop('scrollHeight') - $log.height(); |
||||
|
if( Math.abs($log.scrollTop() - height) < settings.scrollArea) { |
||||
|
module.message.scroll.move(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
move: function() { |
||||
|
height = $log.prop('scrollHeight') - $log.height(); |
||||
|
$log |
||||
|
.scrollTop(height) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// sends chat message
|
||||
|
send: function(message) { |
||||
|
if( !module.utils.emptyString(message) ) { |
||||
|
$.api({ |
||||
|
url : settings.endpoint.message, |
||||
|
method : 'POST', |
||||
|
data : { |
||||
|
'chat_message': { |
||||
|
content : message, |
||||
|
timestamp : new Date().getTime() |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// receives chat response and processes
|
||||
|
receive: function(response) { |
||||
|
message = response.data; |
||||
|
users = $module.data('users'); |
||||
|
loggedInUser = $module.data('user'); |
||||
|
if(users[ message.userID] !== undefined) { |
||||
|
// logged in user's messages already pushed instantly
|
||||
|
if(loggedInUser === undefined || loggedInUser.id != message.userID) { |
||||
|
message.user = users[ message.userID ]; |
||||
|
module.message.display(message); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// displays message in chat log
|
||||
|
display: function(message) { |
||||
|
$log |
||||
|
.append( settings.templates.message(message) ) |
||||
|
; |
||||
|
module.message.scroll.test(); |
||||
|
$.proxy(settings.onMessage, $log.children().last() )(); |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
expand: function() { |
||||
|
$module |
||||
|
.addClass(className.expand) |
||||
|
; |
||||
|
$.proxy(settings.onExpand, $module )(); |
||||
|
module.refresh(); |
||||
|
}, |
||||
|
|
||||
|
contract: function() { |
||||
|
$module |
||||
|
.removeClass(className.expand) |
||||
|
; |
||||
|
$.proxy(settings.onContract, $module )(); |
||||
|
module.refresh(); |
||||
|
}, |
||||
|
|
||||
|
event: { |
||||
|
|
||||
|
input: { |
||||
|
|
||||
|
keydown: function(event) { |
||||
|
if(event.which == 13) { |
||||
|
$messageButton |
||||
|
.addClass(className.down) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
keyup: function(event) { |
||||
|
if(event.which == 13) { |
||||
|
$messageButton |
||||
|
.removeClass(className.down) |
||||
|
; |
||||
|
module.event.submit(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
// handles message form submit
|
||||
|
submit: function() { |
||||
|
var |
||||
|
message = $messageInput.val(), |
||||
|
loggedInUser = $module.data('user') |
||||
|
; |
||||
|
if(loggedInUser !== undefined && !module.utils.emptyString(message)) { |
||||
|
module.message.send(message); |
||||
|
// display immediately
|
||||
|
module.message.display({ |
||||
|
user: loggedInUser, |
||||
|
text: message |
||||
|
}); |
||||
|
module.message.scroll.move(); |
||||
|
$messageInput |
||||
|
.val('') |
||||
|
; |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// handles button click on expand button
|
||||
|
toggleExpand: function() { |
||||
|
if( !$module.hasClass(className.expand) ) { |
||||
|
$expandButton |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
module.expand(); |
||||
|
} |
||||
|
else { |
||||
|
$expandButton |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
module.contract(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// handles button click on user list button
|
||||
|
toggleUserList: function() { |
||||
|
if( !$log.is(':animated') ) { |
||||
|
if( !$userListButton.hasClass(className.active) ) { |
||||
|
$userListButton |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
module.user.list.show(); |
||||
|
} |
||||
|
else { |
||||
|
$userListButton |
||||
|
.removeClass('active') |
||||
|
; |
||||
|
module.user.list.hide(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
utils: { |
||||
|
|
||||
|
emptyString: function(string) { |
||||
|
if(typeof string == 'string') { |
||||
|
return (string.search(/\S/) == -1); |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
// standard methods
|
||||
|
debug: function(message) { |
||||
|
if(settings.debug) { |
||||
|
console.info(settings.moduleName + ': ' + message); |
||||
|
} |
||||
|
}, |
||||
|
error: function(errorMessage) { |
||||
|
console.warn(settings.moduleName + ': ' + errorMessage); |
||||
|
}, |
||||
|
invoke: function(methodName, context, methodArguments) { |
||||
|
var |
||||
|
method |
||||
|
; |
||||
|
methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 ); |
||||
|
if(typeof methodName == 'string' && instance !== undefined) { |
||||
|
methodName = methodName.split('.'); |
||||
|
$.each(methodName, function(index, name) { |
||||
|
if( $.isPlainObject( instance[name] ) ) { |
||||
|
instance = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
else if( $.isFunction( instance[name] ) ) { |
||||
|
method = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
module.error(settings.errors.method); |
||||
|
return false; |
||||
|
}); |
||||
|
} |
||||
|
return ( $.isFunction( method ) ) |
||||
|
? method.apply(context, methodArguments) |
||||
|
: false |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
if(instance !== undefined && moduleArguments) { |
||||
|
// simpler than invoke realizing to invoke itself (and losing scope due prototype.call()
|
||||
|
if(moduleArguments[0] == 'invoke') { |
||||
|
moduleArguments = Array.prototype.slice.call( moduleArguments, 1 ); |
||||
|
} |
||||
|
return module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) ); |
||||
|
} |
||||
|
// initializing
|
||||
|
module.initialize(); |
||||
|
}) |
||||
|
; |
||||
|
|
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
$.fn.chat.settings = { |
||||
|
|
||||
|
moduleName : 'Chat Module', |
||||
|
debug : false, |
||||
|
namespace : 'chat', |
||||
|
|
||||
|
onJoin : function(){}, |
||||
|
onMessage : function(){}, |
||||
|
onExpand : function(){}, |
||||
|
onContract : function(){}, |
||||
|
|
||||
|
customEvents : {}, |
||||
|
|
||||
|
partingMessages : false, |
||||
|
userCount : true, |
||||
|
|
||||
|
randomColor : true, |
||||
|
|
||||
|
speed : 300, |
||||
|
easing : 'easeOutQuint', |
||||
|
|
||||
|
// pixels from bottom of chat log that should trigger auto scroll to bottom
|
||||
|
scrollArea : 9999, |
||||
|
|
||||
|
endpoint : { |
||||
|
message : false, |
||||
|
authentication : false |
||||
|
}, |
||||
|
|
||||
|
errors: { |
||||
|
method : 'The method you called is not defined', |
||||
|
endpoint : 'Please define a message and authentication endpoint.', |
||||
|
key : 'You must specify a pusher key and channel.', |
||||
|
pusher : 'You must include the Pusher library.' |
||||
|
}, |
||||
|
|
||||
|
className : { |
||||
|
expand : 'expand', |
||||
|
active : 'active', |
||||
|
hover : 'hover', |
||||
|
down : 'down', |
||||
|
loading : 'loading' |
||||
|
}, |
||||
|
|
||||
|
selector : { |
||||
|
userCount : '.actions .message', |
||||
|
userListButton : '.actions .button.user-list', |
||||
|
expandButton : '.actions .button.expand', |
||||
|
room : '.room', |
||||
|
userList : '.room .user-list', |
||||
|
log : '.room .log', |
||||
|
message : '.room .log .message', |
||||
|
author : '.room log .message .author', |
||||
|
messageInput : '.talk input', |
||||
|
messageButton : '.talk .send.button' |
||||
|
}, |
||||
|
|
||||
|
templates: { |
||||
|
|
||||
|
userCount: function(number) { |
||||
|
return number + ' users in chat'; |
||||
|
}, |
||||
|
|
||||
|
color: function(userID) { |
||||
|
var |
||||
|
colors = [ |
||||
|
'#000000', |
||||
|
'#333333', |
||||
|
'#666666', |
||||
|
'#999999', |
||||
|
'#CC9999', |
||||
|
'#CC6666', |
||||
|
'#CC3333', |
||||
|
'#993333', |
||||
|
'#663333', |
||||
|
'#CC6633', |
||||
|
'#CC9966', |
||||
|
'#CC9933', |
||||
|
'#999966', |
||||
|
'#CCCC66', |
||||
|
'#99CC66', |
||||
|
'#669933', |
||||
|
'#669966', |
||||
|
'#33A3CC', |
||||
|
'#336633', |
||||
|
'#33CCCC', |
||||
|
'#339999', |
||||
|
'#336666', |
||||
|
'#336699', |
||||
|
'#6666CC', |
||||
|
'#9966CC', |
||||
|
'#333399', |
||||
|
'#663366', |
||||
|
'#996699', |
||||
|
'#993366', |
||||
|
'#CC6699' |
||||
|
] |
||||
|
; |
||||
|
return colors[ Math.floor( Math.random() * colors.length) ]; |
||||
|
}, |
||||
|
|
||||
|
message: function(message) { |
||||
|
var |
||||
|
html = '' |
||||
|
; |
||||
|
if(message.user.isAdmin) { |
||||
|
message.user.color = '#55356A'; |
||||
|
html += '<div class="admin message">'; |
||||
|
html += '<span class="quirky ui flag team"></span>'; |
||||
|
} |
||||
|
/* |
||||
|
else if(message.user.isPro) { |
||||
|
html += '<div class="indent message">'; |
||||
|
html += '<span class="quirky ui flag pro"></span>'; |
||||
|
} |
||||
|
*/ |
||||
|
else { |
||||
|
html += '<div class="message">'; |
||||
|
} |
||||
|
html += '<p>'; |
||||
|
if(message.user.color !== undefined) { |
||||
|
html += '<span class="author" style="color: ' + message.user.color + ';">' + message.user.name + '</span>: '; |
||||
|
} |
||||
|
else { |
||||
|
html += '<span class="author">' + message.user.name + '</span>: '; |
||||
|
} |
||||
|
html += '' |
||||
|
+ message.text |
||||
|
+ ' </p>' |
||||
|
+ '</div>' |
||||
|
; |
||||
|
return html; |
||||
|
}, |
||||
|
|
||||
|
joined: function(member) { |
||||
|
return (typeof member.name !== undefined) |
||||
|
? '<div class="status">' + member.name + ' has joined the chat.</div>' |
||||
|
: false |
||||
|
; |
||||
|
}, |
||||
|
left: function(member) { |
||||
|
return (typeof member.name !== undefined) |
||||
|
? '<div class="status">' + member.name + ' has left the chat.</div>' |
||||
|
: false |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
userList: function(member) { |
||||
|
var |
||||
|
html = '' |
||||
|
; |
||||
|
if(member.isAdmin) { |
||||
|
member.color = '#55356A'; |
||||
|
} |
||||
|
html += '' |
||||
|
+ '<div class="user" data-id="' + member.id + '">' |
||||
|
+ ' <div class="image">' |
||||
|
+ ' <img src="' + member.avatarURL + '">' |
||||
|
+ ' </div>' |
||||
|
; |
||||
|
if(member.color !== undefined) { |
||||
|
html += ' <p><a href="/users/' + member.id + '" target="_blank" style="color: ' + member.color + ';">' + member.name + '</a></p>'; |
||||
|
} |
||||
|
else { |
||||
|
html += ' <p><a href="/users/' + member.id + '" target="_blank">' + member.name + '</a></p>'; |
||||
|
} |
||||
|
html += '</div>'; |
||||
|
return html; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,216 @@ |
|||||
|
/* ****************************** |
||||
|
Semantic Module: Checkbox |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit March 25, 2013 |
||||
|
|
||||
|
Simple plug-in which maintains the state for ui checkbox |
||||
|
This can be done without javascript, only in instances |
||||
|
where each checkbox is assigned a unique ID. This provides a separate |
||||
|
programmatic option when that is not possible. |
||||
|
|
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ( $, window, document, undefined ) { |
||||
|
|
||||
|
$.fn.checkbox = function(parameters) { |
||||
|
var |
||||
|
$allModules = $(this), |
||||
|
|
||||
|
settings = $.extend(true, {}, $.fn.checkbox.settings, parameters), |
||||
|
// make arguments available
|
||||
|
query = arguments[0], |
||||
|
passedArguments = [].slice.call(arguments, 1), |
||||
|
invokedResponse |
||||
|
; |
||||
|
$allModules |
||||
|
.each(function() { |
||||
|
var |
||||
|
$module = $(this), |
||||
|
$input = $(this).find(settings.selector.input), |
||||
|
|
||||
|
selector = $module.selector || '', |
||||
|
element = this, |
||||
|
instance = $module.data('module-' + settings.namespace), |
||||
|
methodInvoked = (typeof query == 'string'), |
||||
|
|
||||
|
className = settings.className, |
||||
|
namespace = settings.namespace, |
||||
|
errors = settings.errors, |
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
initialize: function() { |
||||
|
if(settings.context && selector !== '') { |
||||
|
module.verbose('Initializing checkbox with delegated events', $module); |
||||
|
$(element, settings.context) |
||||
|
.on(selector, 'click.' + namespace, module.toggle) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
module.verbose('Initializing checkbox with bound events', $module); |
||||
|
$module |
||||
|
.on('click.' + namespace, module.toggle) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
destroy: function() { |
||||
|
module.verbose('Destroying previous module for', $module); |
||||
|
$module |
||||
|
.off(namespace) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
toggle: function() { |
||||
|
if( $input.prop('checked') === undefined || !$input.prop('checked') ) { |
||||
|
module.enable(); |
||||
|
} |
||||
|
else { |
||||
|
module.disable(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
enable: function() { |
||||
|
module.debug('Enabling checkbox'); |
||||
|
$module |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
$input |
||||
|
.prop('checked', true) |
||||
|
; |
||||
|
$.proxy(settings.onChange, $input.get())(); |
||||
|
$.proxy(settings.onEnable, $input.get())(); |
||||
|
}, |
||||
|
|
||||
|
disable: function() { |
||||
|
module.debug('Disabling checkbox'); |
||||
|
$module |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
$input |
||||
|
.prop('checked', false) |
||||
|
; |
||||
|
$.proxy(settings.onChange, $input.get())(); |
||||
|
$.proxy(settings.onDisable, $input.get())(); |
||||
|
}, |
||||
|
|
||||
|
/* standard module */ |
||||
|
setting: function(name, value) { |
||||
|
if(value === undefined) { |
||||
|
return settings[name]; |
||||
|
} |
||||
|
settings[name] = value; |
||||
|
}, |
||||
|
verbose: function() { |
||||
|
if(settings.verbose) { |
||||
|
module.debug.apply(this, arguments); |
||||
|
} |
||||
|
}, |
||||
|
debug: function() { |
||||
|
var |
||||
|
output = [], |
||||
|
message = settings.moduleName + ': ' + arguments[0], |
||||
|
variables = [].slice.call( arguments, 1 ), |
||||
|
log = console.info || console.log || function(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
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(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
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(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.checkbox.settings = { |
||||
|
|
||||
|
// module info
|
||||
|
moduleName : 'Checkbox Module', |
||||
|
verbose : false, |
||||
|
debug : true, |
||||
|
namespace : 'checkbox', |
||||
|
|
||||
|
// delegated event context
|
||||
|
context : false, |
||||
|
|
||||
|
onChange : function(){}, |
||||
|
onEnable : function(){}, |
||||
|
onDisable : function(){}, |
||||
|
|
||||
|
// errors
|
||||
|
errors : { |
||||
|
method : 'The method you called is not defined.' |
||||
|
}, |
||||
|
|
||||
|
selector : { |
||||
|
input : 'input' |
||||
|
}, |
||||
|
|
||||
|
className : { |
||||
|
active : 'active' |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,354 @@ |
|||||
|
/* ****************************** |
||||
|
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 ); |
@ -0,0 +1,350 @@ |
|||||
|
/* ****************************** |
||||
|
Nag |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit July 19, 2012 |
||||
|
|
||||
|
Simple fixed position nag |
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ($, window, document, undefined) { |
||||
|
|
||||
|
$.fn.nag = function(parameters) { |
||||
|
var |
||||
|
settings = $.extend(true, {}, $.fn.nag.settings, parameters), |
||||
|
// hoist arguments
|
||||
|
moduleArguments = arguments || false |
||||
|
; |
||||
|
$(this) |
||||
|
.each(function() { |
||||
|
var |
||||
|
$module = $(this), |
||||
|
$close = $module.find(settings.selector.close), |
||||
|
|
||||
|
$context = $(settings.context), |
||||
|
|
||||
|
instance = $module.data('module'), |
||||
|
className = settings.className, |
||||
|
|
||||
|
moduleOffset, |
||||
|
moduleHeight, |
||||
|
|
||||
|
contextWidth, |
||||
|
contextHeight, |
||||
|
contextOffset, |
||||
|
|
||||
|
yOffset, |
||||
|
yPosition, |
||||
|
|
||||
|
timer, |
||||
|
module, |
||||
|
|
||||
|
requestAnimationFrame = window.requestAnimationFrame |
||||
|
|| window.mozRequestAnimationFrame |
||||
|
|| window.webkitRequestAnimationFrame |
||||
|
|| window.msRequestAnimationFrame |
||||
|
|| function(callback) { setTimeout(callback, 0); } |
||||
|
; |
||||
|
module = { |
||||
|
|
||||
|
initialize: function() { |
||||
|
// calculate module offset once
|
||||
|
moduleOffset = $module.offset(); |
||||
|
moduleHeight = $module.outerHeight(); |
||||
|
contextWidth = $context.outerWidth(); |
||||
|
contextHeight = $context.outerHeight(); |
||||
|
contextOffset = $context.offset(); |
||||
|
|
||||
|
$module |
||||
|
.data('module', module) |
||||
|
; |
||||
|
$close |
||||
|
.on('mouseenter mouseleave', module.event.hover) |
||||
|
.on('click', module.dismiss) |
||||
|
; |
||||
|
// lets avoid javascript if we dont need to reposition
|
||||
|
if(settings.context == window && settings.position == 'fixed') { |
||||
|
$module |
||||
|
.addClass(className.fixed) |
||||
|
; |
||||
|
} |
||||
|
if(settings.sticky) { |
||||
|
// retrigger on scroll for absolute
|
||||
|
if(settings.position == 'absolute') { |
||||
|
$context |
||||
|
.on('scroll resize', module.event.scroll) |
||||
|
; |
||||
|
} |
||||
|
// fixed is always relative to window
|
||||
|
else { |
||||
|
$(window) |
||||
|
.on('scroll resize', module.event.scroll) |
||||
|
; |
||||
|
} |
||||
|
// fire once to position on init
|
||||
|
$.proxy(module.event.scroll, this)(); |
||||
|
} |
||||
|
if(settings.followLink) { |
||||
|
$module |
||||
|
.on('mouseenter mouseleave', module.event.hover) |
||||
|
.on('click', module.followLink) |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
if(settings.displayTime > 0) { |
||||
|
setTimeout(module.hide, settings.displayTime); |
||||
|
} |
||||
|
if(module.should.show()) { |
||||
|
if( !$module.is(':visible') ) { |
||||
|
module.show(); |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
module.hide(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
refresh: function() { |
||||
|
moduleOffset = $module.offset(); |
||||
|
moduleHeight = $module.outerHeight(); |
||||
|
contextWidth = $context.outerWidth(); |
||||
|
contextHeight = $context.outerHeight(); |
||||
|
contextOffset = $context.offset(); |
||||
|
}, |
||||
|
|
||||
|
show: function() { |
||||
|
if($.fn.popIn !== undefined) { |
||||
|
$module |
||||
|
.popIn(settings.duration) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$module |
||||
|
.fadeIn(settings.duration, settings.easing) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
hide: function() { |
||||
|
$module |
||||
|
.fadeOut(settings.duration, settings.easing) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
stick: function() { |
||||
|
module.refresh(); |
||||
|
|
||||
|
if(settings.position == 'fixed') { |
||||
|
var |
||||
|
windowScroll = $(window).prop('pageYOffset') || $(window).scrollTop(), |
||||
|
fixedOffset = ( $module.hasClass(className.bottom) ) |
||||
|
? contextOffset.top + (contextHeight - moduleHeight) - windowScroll |
||||
|
: contextOffset.top - windowScroll |
||||
|
; |
||||
|
$module |
||||
|
.css({ |
||||
|
position : 'fixed', |
||||
|
top : fixedOffset, |
||||
|
left : contextOffset.left, |
||||
|
width : contextWidth - settings.scrollBarWidth |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$module |
||||
|
.css({ |
||||
|
top : yPosition |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
unStick: function() { |
||||
|
$module |
||||
|
.css({ |
||||
|
top : '' |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
dismiss: function() { |
||||
|
if(settings.storageMethod) { |
||||
|
module.storage.set(settings.storedKey, settings.storedValue); |
||||
|
} |
||||
|
module.hide(); |
||||
|
}, |
||||
|
|
||||
|
should: { |
||||
|
show: function() { |
||||
|
if( module.storage.get(settings.storedKey) == settings.storedValue) { |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
}, |
||||
|
stick: function() { |
||||
|
yOffset = $context.prop('pageYOffset') || $context.scrollTop(); |
||||
|
yPosition = ( $module.hasClass(className.bottom) ) |
||||
|
? (contextHeight - $module.outerHeight() ) + yOffset |
||||
|
: yOffset |
||||
|
; |
||||
|
// absolute position calculated when y offset met
|
||||
|
if(yPosition > moduleOffset.top) { |
||||
|
return true; |
||||
|
} |
||||
|
else if(settings.position == 'fixed') { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
followLink: function() { |
||||
|
if($.fn.followLink !== undefined) { |
||||
|
$module |
||||
|
.followLink() |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
storage: { |
||||
|
|
||||
|
set: function(key, value) { |
||||
|
if(settings.storageMethod == 'local' && store !== undefined) { |
||||
|
store.set(key, value); |
||||
|
} |
||||
|
// store by cookie
|
||||
|
else if($.cookie !== undefined) { |
||||
|
$.cookie(key, value); |
||||
|
} |
||||
|
else { |
||||
|
module.error(settings.errors.noStorage); |
||||
|
} |
||||
|
}, |
||||
|
get: function(key) { |
||||
|
if(settings.storageMethod == 'local' && store !== undefined) { |
||||
|
return store.get(key); |
||||
|
} |
||||
|
// get by cookie
|
||||
|
else if($.cookie !== undefined) { |
||||
|
return $.cookie(key); |
||||
|
} |
||||
|
else { |
||||
|
module.error(settings.errors.noStorage); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
event: { |
||||
|
hover: function() { |
||||
|
$(this) |
||||
|
.toggleClass(className.hover) |
||||
|
; |
||||
|
}, |
||||
|
scroll: function() { |
||||
|
if(timer !== undefined) { |
||||
|
clearTimeout(timer); |
||||
|
} |
||||
|
timer = setTimeout(function() { |
||||
|
if(module.should.stick() ) { |
||||
|
requestAnimationFrame(module.stick); |
||||
|
} |
||||
|
else { |
||||
|
module.unStick(); |
||||
|
} |
||||
|
}, settings.lag); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
error: function(error) { |
||||
|
console.log('Nag Module:' + error); |
||||
|
}, |
||||
|
|
||||
|
// allows for dot notation method calls
|
||||
|
invoke: function(methodName, context, methodArguments) { |
||||
|
var |
||||
|
method |
||||
|
; |
||||
|
methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 ); |
||||
|
if(typeof methodName == 'string' && instance !== undefined) { |
||||
|
methodName = methodName.split('.'); |
||||
|
$.each(methodName, function(index, name) { |
||||
|
if( $.isPlainObject( instance[name] ) ) { |
||||
|
instance = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
else if( $.isFunction( instance[name] ) ) { |
||||
|
method = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
module.error(settings.errors.method); |
||||
|
return false; |
||||
|
}); |
||||
|
} |
||||
|
if ( $.isFunction( method ) ) { |
||||
|
return method.apply(context, methodArguments); |
||||
|
} |
||||
|
// return retrieved variable or chain
|
||||
|
return method; |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
if(instance !== undefined && moduleArguments) { |
||||
|
if(moduleArguments[0] == 'invoke') { |
||||
|
moduleArguments = Array.prototype.slice.call( moduleArguments, 1 ); |
||||
|
} |
||||
|
return module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) ); |
||||
|
} |
||||
|
module.initialize(); |
||||
|
|
||||
|
}) |
||||
|
; |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
$.fn.nag.settings = { |
||||
|
|
||||
|
// set to zero to manually dismiss, otherwise hides on its own
|
||||
|
displayTime : 0, |
||||
|
|
||||
|
// if there is a link to follow
|
||||
|
followLink : true, |
||||
|
|
||||
|
// method of stickyness
|
||||
|
position : 'fixed', |
||||
|
scrollBarWidth : 18, |
||||
|
|
||||
|
// type of storage to use
|
||||
|
storageMethod : 'cookie', |
||||
|
|
||||
|
// value to store in dismissed localstorage/cookie
|
||||
|
storedKey : 'nag', |
||||
|
storedValue : 'dismiss', |
||||
|
|
||||
|
// need to calculate stickyness on scroll
|
||||
|
sticky : true, |
||||
|
|
||||
|
// how often to check scroll event
|
||||
|
lag : 0, |
||||
|
|
||||
|
// context for scroll event
|
||||
|
context : window, |
||||
|
|
||||
|
errors: { |
||||
|
noStorage : 'Neither $.cookie or store is defined. A storage solution is required for storing state', |
||||
|
followLink : 'Follow link is set but the plugin is not included' |
||||
|
}, |
||||
|
|
||||
|
className : { |
||||
|
bottom : 'bottom', |
||||
|
hover : 'hover', |
||||
|
fixed : 'fixed' |
||||
|
}, |
||||
|
|
||||
|
selector : { |
||||
|
close: '.icon.close' |
||||
|
}, |
||||
|
|
||||
|
speed : 500, |
||||
|
easing : 'easeOutQuad' |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,590 @@ |
|||||
|
/* ****************************** |
||||
|
Tooltip / Popup |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit Sep 07, 2012 |
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ($, window, document, undefined) { |
||||
|
|
||||
|
$.fn.popup = function(parameters) { |
||||
|
var |
||||
|
settings = $.extend(true, {}, $.fn.popup.settings, parameters), |
||||
|
// make arguments available
|
||||
|
moduleArguments = arguments || false, |
||||
|
invokedResponse |
||||
|
; |
||||
|
$(this) |
||||
|
.each(function() { |
||||
|
var |
||||
|
$module = $(this), |
||||
|
$window = $(window), |
||||
|
$offsetParent = $module.offsetParent(), |
||||
|
$popup = (settings.inline) |
||||
|
? $module.next(settings.selector.popup) |
||||
|
: $window.children(settings.selector.popup).last(), |
||||
|
|
||||
|
timer, |
||||
|
recursionDepth = 0, |
||||
|
|
||||
|
instance = $module.data('module-' + settings.namespace), |
||||
|
methodInvoked = (instance !== undefined && typeof parameters == 'string'), |
||||
|
|
||||
|
selector = settings.selector, |
||||
|
className = settings.className, |
||||
|
errors = settings.errors, |
||||
|
metadata = settings.metadata, |
||||
|
namespace = settings.namespace, |
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
// binds events
|
||||
|
initialize: function() { |
||||
|
if(settings.event == 'hover') { |
||||
|
$module |
||||
|
.on('mouseenter.' + namespace, module.event.mouseenter) |
||||
|
.on('mouseleave.' + namespace, module.event.mouseleave) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$module |
||||
|
.on(settings.event + '.' + namespace, module.event[settings.event]) |
||||
|
; |
||||
|
} |
||||
|
$window |
||||
|
.on('resize.' + namespace, module.event.resize) |
||||
|
; |
||||
|
$module |
||||
|
.data('module-' + namespace, module) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
refresh: function() { |
||||
|
$popup = (settings.inline) |
||||
|
? $module.next(selector.popup) |
||||
|
: $window.children(selector.popup).last() |
||||
|
; |
||||
|
$offsetParent = $module.offsetParent(); |
||||
|
}, |
||||
|
|
||||
|
destroy: function() { |
||||
|
module.debug('Destroying existing popups'); |
||||
|
$module |
||||
|
.off('.' + namespace) |
||||
|
; |
||||
|
$popup |
||||
|
.remove() |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
event: { |
||||
|
mouseenter: function(event) { |
||||
|
var element = this; |
||||
|
timer = setTimeout(function() { |
||||
|
$.proxy(module.toggle, element)(); |
||||
|
if( $(element).hasClass(className.active) ) { |
||||
|
event.stopPropagation(); |
||||
|
} |
||||
|
}, settings.delay); |
||||
|
}, |
||||
|
mouseleave: function(event) { |
||||
|
clearTimeout(timer); |
||||
|
if( $module.is(':visible') ) { |
||||
|
module.hide(); |
||||
|
} |
||||
|
}, |
||||
|
click: function(event) { |
||||
|
$.proxy(module.toggle, this)(); |
||||
|
if( $(this).hasClass(className.active) ) { |
||||
|
event.stopPropagation(); |
||||
|
} |
||||
|
}, |
||||
|
resize: function() { |
||||
|
if( $popup.is(':visible') ) { |
||||
|
module.position(); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// generates popup html from metadata
|
||||
|
create: function() { |
||||
|
module.debug('Creating pop-up content'); |
||||
|
var |
||||
|
html = $module.data(metadata.html) || settings.html, |
||||
|
title = $module.data(metadata.title) || settings.title, |
||||
|
content = $module.data(metadata.content) || $module.attr('title') || settings.content |
||||
|
; |
||||
|
if(html || content || title) { |
||||
|
if(!html) { |
||||
|
html = settings.template({ |
||||
|
title : title, |
||||
|
content : content |
||||
|
}); |
||||
|
} |
||||
|
$popup = $('<div/>') |
||||
|
.addClass(className.popup) |
||||
|
.html(html) |
||||
|
; |
||||
|
if(settings.inline) { |
||||
|
$popup |
||||
|
.insertAfter($module) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$popup |
||||
|
.appendTo( $('body') ) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
module.error(errors.content); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
remove: function() { |
||||
|
$popup |
||||
|
.remove() |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
get: { |
||||
|
offstagePosition: function() { |
||||
|
var |
||||
|
boundary = { |
||||
|
top : $(window).scrollTop(), |
||||
|
bottom : $(window).scrollTop() + $(window).height(), |
||||
|
left : 0, |
||||
|
right : $(window).width() |
||||
|
}, |
||||
|
popup = { |
||||
|
width : $popup.outerWidth(), |
||||
|
height : $popup.outerHeight(), |
||||
|
position : $popup.offset() |
||||
|
}, |
||||
|
offstage = {}, |
||||
|
offstagePositions = [] |
||||
|
; |
||||
|
if(popup.position) { |
||||
|
offstage = { |
||||
|
top : (popup.position.top < boundary.top), |
||||
|
bottom : (popup.position.top + popup.height > boundary.bottom), |
||||
|
right : (popup.position.left + popup.width > boundary.right), |
||||
|
left : (popup.position.left < boundary.left) |
||||
|
}; |
||||
|
} |
||||
|
// return only boundaries that have been surpassed
|
||||
|
$.each(offstage, function(direction, isOffstage) { |
||||
|
if(isOffstage) { |
||||
|
offstagePositions.push(direction); |
||||
|
} |
||||
|
}); |
||||
|
return (offstagePositions.length > 0) |
||||
|
? offstagePositions.join(' ') |
||||
|
: false |
||||
|
; |
||||
|
}, |
||||
|
nextPosition: function(position) { |
||||
|
switch(position) { |
||||
|
case 'top left': |
||||
|
position = 'bottom left'; |
||||
|
break; |
||||
|
case 'bottom left': |
||||
|
position = 'top right'; |
||||
|
break; |
||||
|
case 'top right': |
||||
|
position = 'bottom right'; |
||||
|
break; |
||||
|
case 'bottom right': |
||||
|
position = 'top center'; |
||||
|
break; |
||||
|
case 'top center': |
||||
|
position = 'bottom center'; |
||||
|
break; |
||||
|
case 'bottom center': |
||||
|
position = 'right center'; |
||||
|
break; |
||||
|
case 'right center': |
||||
|
position = 'left center'; |
||||
|
break; |
||||
|
case 'left center': |
||||
|
position = 'top center'; |
||||
|
break; |
||||
|
} |
||||
|
return position; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// determines popup state
|
||||
|
toggle: function() { |
||||
|
$module = $(this); |
||||
|
module.debug('Toggling pop-up'); |
||||
|
// refresh state of module
|
||||
|
module.refresh(); |
||||
|
if($popup.size() === 0) { |
||||
|
module.create(); |
||||
|
} |
||||
|
if( !$module.hasClass(className.active) ) { |
||||
|
if( module.position() ) { |
||||
|
module.show(); |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
module.hide(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
position: function(position, arrowOffset) { |
||||
|
var |
||||
|
windowWidth = $(window).width(), |
||||
|
windowHeight = $(window).height(), |
||||
|
width = $module.outerWidth(), |
||||
|
height = $module.outerHeight(), |
||||
|
popupWidth = $popup.outerWidth(), |
||||
|
popupHeight = $popup.outerHeight(), |
||||
|
|
||||
|
offset = (settings.inline) |
||||
|
? $module.position() |
||||
|
: $module.offset(), |
||||
|
parentWidth = (settings.inline) |
||||
|
? $offsetParent.outerWidth() |
||||
|
: $window.outerWidth(), |
||||
|
parentHeight = (settings.inline) |
||||
|
? $offsetParent.outerHeight() |
||||
|
: $window.outerHeight(), |
||||
|
|
||||
|
positioning, |
||||
|
offstagePosition |
||||
|
; |
||||
|
position = position || $module.data(metadata.position) || settings.position; |
||||
|
arrowOffset = arrowOffset || $module.data(metadata.arrowOffset) || settings.arrowOffset; |
||||
|
module.debug('Calculating offset for position', position); |
||||
|
switch(position) { |
||||
|
case 'top left': |
||||
|
positioning = { |
||||
|
top : 'auto', |
||||
|
bottom : parentHeight - offset.top + settings.distanceAway, |
||||
|
left : offset.left + arrowOffset |
||||
|
}; |
||||
|
break; |
||||
|
case 'top center': |
||||
|
positioning = { |
||||
|
bottom : parentHeight - offset.top + settings.distanceAway, |
||||
|
left : offset.left + (width / 2) - (popupWidth / 2) + arrowOffset, |
||||
|
top : 'auto', |
||||
|
right : 'auto' |
||||
|
}; |
||||
|
break; |
||||
|
case 'top right': |
||||
|
positioning = { |
||||
|
bottom : parentHeight - offset.top + settings.distanceAway, |
||||
|
right : parentWidth - offset.left - width - arrowOffset, |
||||
|
top : 'auto', |
||||
|
left : 'auto' |
||||
|
}; |
||||
|
break; |
||||
|
case 'left center': |
||||
|
positioning = { |
||||
|
top : offset.top + (height / 2) - (popupHeight / 2), |
||||
|
right : parentWidth - offset.left + settings.distanceAway - arrowOffset, |
||||
|
left : 'auto', |
||||
|
bottom : 'auto' |
||||
|
}; |
||||
|
break; |
||||
|
case 'right center': |
||||
|
positioning = { |
||||
|
top : offset.top + (height / 2) - (popupHeight / 2), |
||||
|
left : offset.left + width + settings.distanceAway + arrowOffset, |
||||
|
bottom : 'auto', |
||||
|
right : 'auto' |
||||
|
}; |
||||
|
break; |
||||
|
case 'bottom left': |
||||
|
positioning = { |
||||
|
top : offset.top + height + settings.distanceAway, |
||||
|
left : offset.left + arrowOffset, |
||||
|
bottom : 'auto', |
||||
|
right : 'auto' |
||||
|
}; |
||||
|
break; |
||||
|
case 'bottom center': |
||||
|
positioning = { |
||||
|
top : offset.top + height + settings.distanceAway, |
||||
|
left : offset.left + (width / 2) - (popupWidth / 2) + arrowOffset, |
||||
|
bottom : 'auto', |
||||
|
right : 'auto' |
||||
|
}; |
||||
|
break; |
||||
|
case 'bottom right': |
||||
|
positioning = { |
||||
|
top : offset.top + height + settings.distanceAway, |
||||
|
right : parentWidth - offset.left - width - arrowOffset, |
||||
|
left : 'auto', |
||||
|
bottom : 'auto' |
||||
|
}; |
||||
|
break; |
||||
|
} |
||||
|
// true width on popup
|
||||
|
$.extend(positioning, { |
||||
|
width: $popup.width() |
||||
|
}); |
||||
|
// tentatively place on stage
|
||||
|
$popup |
||||
|
.removeAttr('style') |
||||
|
.removeClass('top right bottom left center') |
||||
|
.css(positioning) |
||||
|
.addClass(position) |
||||
|
.addClass(className.loading) |
||||
|
; |
||||
|
// check if is offstage
|
||||
|
offstagePosition = module.get.offstagePosition(); |
||||
|
// recursively find new positioning
|
||||
|
if(offstagePosition) { |
||||
|
module.debug('Element is outside boundaries ', offstagePosition); |
||||
|
if(recursionDepth < settings.maxRecursion) { |
||||
|
position = module.get.nextPosition(position); |
||||
|
recursionDepth++; |
||||
|
module.debug('Trying new position: ', position); |
||||
|
return module.position(position); |
||||
|
} |
||||
|
else { |
||||
|
module.error(errors.recursion); |
||||
|
recursionDepth = 0; |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
module.debug('Position is on stage', position); |
||||
|
recursionDepth = 0; |
||||
|
return true; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
show: function() { |
||||
|
module.debug('Showing pop-up'); |
||||
|
$(selector.popup) |
||||
|
.filter(':visible') |
||||
|
.stop() |
||||
|
.fadeOut(200) |
||||
|
.prev($module) |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
$module |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
$popup |
||||
|
.removeClass(className.loading) |
||||
|
; |
||||
|
if(settings.animation == 'pop' && $.fn.popIn !== undefined) { |
||||
|
$popup |
||||
|
.stop() |
||||
|
.popIn(settings.duration, settings.easing) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$popup |
||||
|
.stop() |
||||
|
.fadeIn(settings.duration, settings.easing) |
||||
|
; |
||||
|
} |
||||
|
if(settings.event == 'click' && settings.clicktoClose) { |
||||
|
module.debug('Binding popup close event'); |
||||
|
$(document) |
||||
|
.on('click.' + namespace, module.gracefully.hide) |
||||
|
; |
||||
|
} |
||||
|
$.proxy(settings.onShow, $popup)(); |
||||
|
}, |
||||
|
|
||||
|
hide: function() { |
||||
|
$module |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
if($popup.is(':visible') ) { |
||||
|
module.debug('Hiding pop-up'); |
||||
|
if(settings.animation == 'pop' && $.fn.popOut !== undefined) { |
||||
|
$popup |
||||
|
.stop() |
||||
|
.popOut(settings.duration, settings.easing, function() { |
||||
|
$popup.hide(); |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
$popup |
||||
|
.stop() |
||||
|
.fadeOut(settings.duration, settings.easing) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
if(settings.event == 'click' && settings.clicktoClose) { |
||||
|
$(document) |
||||
|
.off('click.' + namespace) |
||||
|
; |
||||
|
} |
||||
|
$.proxy(settings.onHide, $popup)(); |
||||
|
if(!settings.inline) { |
||||
|
module.remove(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
gracefully: { |
||||
|
hide: function(event) { |
||||
|
// don't close on clicks inside popup
|
||||
|
if( $(event.target).closest(selector.popup).size() === 0) { |
||||
|
module.hide(); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* 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(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) ); |
||||
|
} |
||||
|
// otherwise initialize
|
||||
|
else { |
||||
|
if(instance) { |
||||
|
module.destroy(); |
||||
|
} |
||||
|
module.initialize(); |
||||
|
} |
||||
|
}) |
||||
|
; |
||||
|
// chain or return queried method
|
||||
|
return (invokedResponse !== undefined) |
||||
|
? invokedResponse |
||||
|
: this |
||||
|
; |
||||
|
}; |
||||
|
|
||||
|
$.fn.popup.settings = { |
||||
|
|
||||
|
moduleName : 'Pop-up Module', |
||||
|
debug : true, |
||||
|
namespace : 'popup', |
||||
|
|
||||
|
onShow : function(){}, |
||||
|
onHide : function(){}, |
||||
|
|
||||
|
content : false, |
||||
|
html : false, |
||||
|
title : false, |
||||
|
|
||||
|
position : 'top center', |
||||
|
delay : 0, |
||||
|
inline : true, |
||||
|
|
||||
|
duration : 250, |
||||
|
easing : 'easeOutQuint', |
||||
|
animation : 'pop', |
||||
|
|
||||
|
errors: { |
||||
|
content : 'Warning: Your popup has no content specified', |
||||
|
method : 'The method you called is not defined.', |
||||
|
recursion : 'Popup attempted to reposition element to fit, but could not find an adequate position.' |
||||
|
}, |
||||
|
|
||||
|
distanceAway : 2, |
||||
|
arrowOffset : 0, |
||||
|
|
||||
|
maxRecursion : 10, |
||||
|
|
||||
|
event : 'hover', |
||||
|
clicktoClose : true, |
||||
|
|
||||
|
metadata: { |
||||
|
content : 'content', |
||||
|
html : 'html', |
||||
|
title : 'title', |
||||
|
position : 'position', |
||||
|
arrowOffset : 'arrowOffset' |
||||
|
}, |
||||
|
|
||||
|
className : { |
||||
|
popup : 'ui popup', |
||||
|
active : 'active', |
||||
|
loading : 'loading' |
||||
|
}, |
||||
|
|
||||
|
selector : { |
||||
|
popup : '.ui.popup' |
||||
|
}, |
||||
|
|
||||
|
template: function(text) { |
||||
|
var html = ''; |
||||
|
if(typeof text !== undefined) { |
||||
|
if(typeof text.title !== undefined && text.title) { |
||||
|
html += '<h2>' + text.title + '</h2>'; |
||||
|
} |
||||
|
if(typeof text.content !== undefined && text.content) { |
||||
|
html += '<div class="content">' + text.content + '</div>'; |
||||
|
} |
||||
|
} |
||||
|
return html; |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,670 @@ |
|||||
|
/* ****************************** |
||||
|
Search Prompt |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit July 19, 2012 |
||||
|
|
||||
|
Designed to be used as an autocomplete |
||||
|
or to deliver quick inline search results |
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ($, window, document, undefined) { |
||||
|
|
||||
|
$.fn.searchPrompt = function(source, parameters) { |
||||
|
var |
||||
|
settings = $.extend(true, {}, $.fn.searchPrompt.settings, parameters), |
||||
|
// make arguments available
|
||||
|
query = arguments[0], |
||||
|
passedArguments = [].slice.call(arguments, 1), |
||||
|
invokedResponse |
||||
|
; |
||||
|
$(this) |
||||
|
.each(function() { |
||||
|
var |
||||
|
$module = $(this), |
||||
|
$searchPrompt = $module.find(settings.selector.searchPrompt), |
||||
|
$searchButton = $module.find(settings.selector.searchButton), |
||||
|
$searchResults = $module.find(settings.selector.searchResults), |
||||
|
$result = $module.find(settings.selector.result), |
||||
|
$category = $module.find(settings.selector.category), |
||||
|
$emptyResult = $module.find(settings.selector.emptyResult), |
||||
|
$resultPage = $module.find(settings.selector.resultPage), |
||||
|
|
||||
|
element = this, |
||||
|
selector = $module.selector || '', |
||||
|
instance = $module.data('module-' + settings.namespace), |
||||
|
methodInvoked = (instance !== undefined && typeof query == 'string'), |
||||
|
|
||||
|
className = settings.className, |
||||
|
namespace = settings.namespace, |
||||
|
errors = settings.errors, |
||||
|
module |
||||
|
; |
||||
|
module = { |
||||
|
|
||||
|
initialize: function() { |
||||
|
var |
||||
|
searchPrompt = $searchPrompt[0], |
||||
|
inputEvent = (searchPrompt.oninput !== undefined) |
||||
|
? 'input' |
||||
|
: (searchPrompt.onpropertychange !== undefined) |
||||
|
? 'propertychange' |
||||
|
: 'keyup' |
||||
|
; |
||||
|
// attach events
|
||||
|
$searchPrompt |
||||
|
.on('focus.' + namespace, module.event.focus) |
||||
|
.on('blur.' + namespace, module.event.blur) |
||||
|
.on('keydown.' + namespace, module.handleKeyboard) |
||||
|
; |
||||
|
if(settings.automatic) { |
||||
|
$searchPrompt |
||||
|
.on(inputEvent + '.' + namespace, module.search.throttle) |
||||
|
; |
||||
|
} |
||||
|
$searchButton |
||||
|
.on('click.' + namespace, module.search.query) |
||||
|
; |
||||
|
$searchResults |
||||
|
.on('click.' + namespace, settings.selector.result, module.results.select) |
||||
|
; |
||||
|
$module |
||||
|
.data('module-' + namespace, module) |
||||
|
; |
||||
|
}, |
||||
|
event: { |
||||
|
focus: function() { |
||||
|
$module |
||||
|
.addClass(className.focus) |
||||
|
; |
||||
|
module.results.show(); |
||||
|
}, |
||||
|
blur: function() { |
||||
|
module.search.cancel(); |
||||
|
$module |
||||
|
.removeClass(className.focus) |
||||
|
; |
||||
|
module.results.hide(); |
||||
|
} |
||||
|
}, |
||||
|
handleKeyboard: function(event) { |
||||
|
var |
||||
|
// force latest jq dom
|
||||
|
$result = $module.find(settings.selector.result), |
||||
|
$category = $module.find(settings.selector.category), |
||||
|
keyCode = event.which, |
||||
|
keys = { |
||||
|
backspace : 8, |
||||
|
enter : 13, |
||||
|
escape : 27, |
||||
|
upArrow : 38, |
||||
|
downArrow : 40 |
||||
|
}, |
||||
|
activeClass = className.active, |
||||
|
currentIndex = $result.index( $result.filter('.' + activeClass) ), |
||||
|
resultSize = $result.size(), |
||||
|
newIndex |
||||
|
; |
||||
|
// search shortcuts
|
||||
|
if(keyCode == keys.escape) { |
||||
|
$searchPrompt |
||||
|
.trigger('blur') |
||||
|
; |
||||
|
} |
||||
|
// result shortcuts
|
||||
|
if($searchResults.filter(':visible').size() > 0) { |
||||
|
if(keyCode == keys.enter) { |
||||
|
if( $result.filter('.' + activeClass).exists() ) { |
||||
|
$.proxy(module.results.select, $result.filter('.' + activeClass) )(); |
||||
|
event.preventDefault(); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
else if(keyCode == keys.upArrow) { |
||||
|
newIndex = (currentIndex - 1 < 0) |
||||
|
? currentIndex |
||||
|
: currentIndex - 1 |
||||
|
; |
||||
|
$category |
||||
|
.removeClass(activeClass) |
||||
|
; |
||||
|
$result |
||||
|
.removeClass(activeClass) |
||||
|
.eq(newIndex) |
||||
|
.addClass(activeClass) |
||||
|
.closest($category) |
||||
|
.addClass(activeClass) |
||||
|
; |
||||
|
event.preventDefault(); |
||||
|
} |
||||
|
else if(keyCode == keys.downArrow) { |
||||
|
newIndex = (currentIndex + 1 >= resultSize) |
||||
|
? currentIndex |
||||
|
: currentIndex + 1 |
||||
|
; |
||||
|
$category |
||||
|
.removeClass(activeClass) |
||||
|
; |
||||
|
$result |
||||
|
.removeClass(activeClass) |
||||
|
.eq(newIndex) |
||||
|
.addClass(activeClass) |
||||
|
.closest($category) |
||||
|
.addClass(activeClass) |
||||
|
; |
||||
|
event.preventDefault(); |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
// query shortcuts
|
||||
|
if(keyCode == keys.enter) { |
||||
|
module.search.query(); |
||||
|
$searchButton |
||||
|
.addClass(className.down) |
||||
|
; |
||||
|
$searchPrompt |
||||
|
.one('keyup', function(){ |
||||
|
$searchButton |
||||
|
.removeClass(className.down) |
||||
|
; |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
search: { |
||||
|
cancel: function() { |
||||
|
var |
||||
|
xhr = $module.data('xhr') || false |
||||
|
; |
||||
|
if( xhr && xhr.state() != 'resolved') { |
||||
|
xhr.abort(); |
||||
|
} |
||||
|
}, |
||||
|
throttle: function(event) { |
||||
|
var |
||||
|
searchTerm = $searchPrompt.val(), |
||||
|
numCharacters = searchTerm.length, |
||||
|
timer |
||||
|
; |
||||
|
clearTimeout($module.data('timer')); |
||||
|
if(numCharacters >= settings.minCharacters) { |
||||
|
timer = setTimeout(module.search.query, settings.searchThrottle); |
||||
|
$module |
||||
|
.data('timer', timer) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
module.results.hide(); |
||||
|
} |
||||
|
}, |
||||
|
query: function() { |
||||
|
var |
||||
|
searchTerm = $searchPrompt.val(), |
||||
|
cachedHTML = module.search.cache.read(searchTerm) |
||||
|
; |
||||
|
if(cachedHTML) { |
||||
|
module.debug("Reading result for '" + searchTerm + "' from cache"); |
||||
|
module.results.add(cachedHTML); |
||||
|
} |
||||
|
else { |
||||
|
module.debug("Querying for '" + searchTerm + "'"); |
||||
|
if(typeof source == 'object') { |
||||
|
module.search.local(searchTerm); |
||||
|
} |
||||
|
else { |
||||
|
module.search.remote(searchTerm); |
||||
|
} |
||||
|
$.proxy(settings.onSearchQuery, $module)(searchTerm); |
||||
|
} |
||||
|
}, |
||||
|
local: function(searchTerm) { |
||||
|
var |
||||
|
searchResults = [], |
||||
|
fullTextResults = [], |
||||
|
searchFields = $.isArray(settings.searchFields) |
||||
|
? settings.searchFields |
||||
|
: [settings.searchFields], |
||||
|
|
||||
|
searchRegExp = new RegExp('(?:\s|^)' + searchTerm, 'i'), |
||||
|
fullTextRegExp = new RegExp(searchTerm, 'i'), |
||||
|
searchHTML |
||||
|
; |
||||
|
$module |
||||
|
.addClass(className.loading) |
||||
|
; |
||||
|
// iterate through search fields in array order
|
||||
|
$.each(searchFields, function(index, field) { |
||||
|
$.each(source, function(label, thing) { |
||||
|
if(typeof thing[field] == 'string' && ($.inArray(thing, searchResults) == -1) && ($.inArray(thing, fullTextResults) == -1) ) { |
||||
|
if( searchRegExp.test( thing[field] ) ) { |
||||
|
searchResults.push(thing); |
||||
|
} |
||||
|
else if( fullTextRegExp.test( thing[field] ) ) { |
||||
|
fullTextResults.push(thing); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
searchHTML = module.results.generate({ |
||||
|
results: $.merge(searchResults, fullTextResults) |
||||
|
}); |
||||
|
$module |
||||
|
.removeClass(className.loading) |
||||
|
; |
||||
|
module.search.cache.write(searchTerm, searchHTML); |
||||
|
module.results.add(searchHTML); |
||||
|
}, |
||||
|
remote: function(searchTerm) { |
||||
|
var |
||||
|
xhr = ($module.data('xhr') !== undefined) |
||||
|
? $module.data('xhr') |
||||
|
: false, |
||||
|
apiSettings = { |
||||
|
stateContext : $module, |
||||
|
url : source, |
||||
|
urlData: { query: searchTerm }, |
||||
|
success : function(response) { |
||||
|
searchHTML = module.results.generate(response); |
||||
|
module.search.cache.write(searchTerm, searchHTML); |
||||
|
module.results.add(searchHTML); |
||||
|
}, |
||||
|
failure : module.error |
||||
|
}, |
||||
|
searchHTML |
||||
|
; |
||||
|
// api attaches xhr event to context, use this to prevent overlapping queries
|
||||
|
if( xhr && xhr.state() != 'resolved') { |
||||
|
xhr.abort(); |
||||
|
} |
||||
|
$.extend(true, apiSettings, settings.apiSettings); |
||||
|
$.api(apiSettings); |
||||
|
}, |
||||
|
|
||||
|
cache: { |
||||
|
read: function(name) { |
||||
|
var |
||||
|
cache = $module.data('cache') |
||||
|
; |
||||
|
return (settings.cache && (typeof cache == 'object') && (cache[name] !== undefined) ) |
||||
|
? cache[name] |
||||
|
: false |
||||
|
; |
||||
|
}, |
||||
|
write: function(name, value) { |
||||
|
var |
||||
|
cache = ($module.data('cache') !== undefined) |
||||
|
? $module.data('cache') |
||||
|
: {} |
||||
|
; |
||||
|
cache[name] = value; |
||||
|
$module |
||||
|
.data('cache', cache) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
results: { |
||||
|
generate: function(response) { |
||||
|
module.debug('Generating html from response', response); |
||||
|
var |
||||
|
template = settings.templates[settings.type], |
||||
|
html = '' |
||||
|
; |
||||
|
if(($.isPlainObject(response.results) && !$.isEmptyObject(response.results)) || ($.isArray(response.results) && response.results.length > 0) ) { |
||||
|
if(settings.maxResults > 0) { |
||||
|
response.results = $.makeArray(response.results).slice(0, settings.maxResults); |
||||
|
} |
||||
|
if(response.results.length > 0) { |
||||
|
if($.isFunction(template)) { |
||||
|
html = template(response); |
||||
|
} |
||||
|
else { |
||||
|
module.error(errors.noTemplate, false); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
html = module.message(errors.noResults, 'empty'); |
||||
|
} |
||||
|
$.proxy(settings.onSearchResults, $module)(response); |
||||
|
return html; |
||||
|
}, |
||||
|
add: function(html) { |
||||
|
if(settings.onResultsAdd == 'default' || $.proxy(settings.onResultsAdd, $searchResults)(html) == 'default') { |
||||
|
$searchResults |
||||
|
.html(html) |
||||
|
; |
||||
|
} |
||||
|
module.results.show(); |
||||
|
}, |
||||
|
show: function() { |
||||
|
if( ($searchResults.filter(':visible').size() === 0) && ($searchPrompt.filter(':focus').size() > 0) && $searchResults.html() !== '') { |
||||
|
$searchResults |
||||
|
.stop() |
||||
|
.fadeIn(200) |
||||
|
; |
||||
|
$.proxy(settings.onResultsOpen, $searchResults)(); |
||||
|
} |
||||
|
}, |
||||
|
hide: function() { |
||||
|
if($searchResults.filter(':visible').size() > 0) { |
||||
|
$searchResults |
||||
|
.stop() |
||||
|
.fadeOut(200) |
||||
|
; |
||||
|
$.proxy(settings.onResultsClose, $searchResults)(); |
||||
|
} |
||||
|
}, |
||||
|
followLink: function() { |
||||
|
|
||||
|
}, |
||||
|
select: function(event) { |
||||
|
module.debug('Search result selected'); |
||||
|
var |
||||
|
$result = $(this), |
||||
|
$title = $result.find('.title'), |
||||
|
title = $title.html() |
||||
|
; |
||||
|
if(settings.onSelect == 'default' || $.proxy(settings.onSelect, this)(event) == 'default') { |
||||
|
var |
||||
|
$link = $result.find('a[href]').eq(0), |
||||
|
href = $link.attr('href'), |
||||
|
target = $link.attr('target') |
||||
|
; |
||||
|
try { |
||||
|
module.results.hide(); |
||||
|
$searchPrompt |
||||
|
.val(title) |
||||
|
; |
||||
|
if(target == '_blank' || event.ctrlKey) { |
||||
|
window.open(href); |
||||
|
} |
||||
|
else { |
||||
|
window.location.href = (href); |
||||
|
} |
||||
|
} |
||||
|
catch(error) {} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* 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(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
if(settings.debug) { |
||||
|
output.push(message); |
||||
|
log.apply(console, output.concat(variables) ); |
||||
|
} |
||||
|
}, |
||||
|
// displays mesage visibly in search results
|
||||
|
message: function(text, type) { |
||||
|
type = type || 'standard'; |
||||
|
module.results.add( settings.templates.message(text, type) ); |
||||
|
return settings.templates.message(text, type); |
||||
|
}, |
||||
|
// update view with error message
|
||||
|
error: function(errorMessage, escalate) { |
||||
|
// show user error message
|
||||
|
escalate = (escalate !== undefined) |
||||
|
? escalate |
||||
|
: true |
||||
|
; |
||||
|
console.warn(settings.moduleName + ': ' + errorMessage); |
||||
|
if(escalate && errorMessage !== undefined) { |
||||
|
module.message(errorMessage, 'error'); |
||||
|
} |
||||
|
}, |
||||
|
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(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, element, passedArguments); |
||||
|
} |
||||
|
// otherwise initialize
|
||||
|
else { |
||||
|
module.initialize(); |
||||
|
} |
||||
|
}) |
||||
|
; |
||||
|
// chain or return queried method
|
||||
|
return (invokedResponse !== undefined) |
||||
|
? invokedResponse |
||||
|
: this |
||||
|
; |
||||
|
}; |
||||
|
|
||||
|
$.fn.searchPrompt.settings = { |
||||
|
|
||||
|
moduleName : 'Search Module', |
||||
|
debug : true, |
||||
|
namespace : 'search', |
||||
|
|
||||
|
// onSelect default action is defined in module
|
||||
|
onSelect : 'default', |
||||
|
onResultsAdd : 'default', |
||||
|
|
||||
|
onSearchQuery : function(){}, |
||||
|
onSearchResults : function(response){}, |
||||
|
|
||||
|
onResultsOpen : function(){}, |
||||
|
onResultsClose : function(){}, |
||||
|
|
||||
|
automatic : 'true', |
||||
|
type : 'simple', |
||||
|
minCharacters : 3, |
||||
|
searchThrottle : 300, |
||||
|
maxResults : 7, |
||||
|
cache : true, |
||||
|
|
||||
|
searchFields : ['title', 'description'], |
||||
|
|
||||
|
// api config
|
||||
|
apiSettings: { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
className: { |
||||
|
active : 'active', |
||||
|
down : 'down', |
||||
|
focus : 'focus', |
||||
|
empty : 'empty', |
||||
|
loading : 'loading' |
||||
|
}, |
||||
|
|
||||
|
errors : { |
||||
|
noResults : 'Your search returned no results', |
||||
|
logging : 'Error in debug logging, exiting.', |
||||
|
noTemplate : 'A valid template name was not specified.', |
||||
|
serverError : 'There was an issue with querying the server.', |
||||
|
method : 'The method you called is not defined.' |
||||
|
}, |
||||
|
|
||||
|
selector : { |
||||
|
searchPrompt : '.prompt', |
||||
|
searchButton : '.search.button', |
||||
|
searchResults : '.results', |
||||
|
|
||||
|
category : '.category', |
||||
|
result : '.result', |
||||
|
|
||||
|
emptyResult : '.results .message', |
||||
|
resultPage : '.results .page' |
||||
|
}, |
||||
|
|
||||
|
templates: { |
||||
|
message: function(message, type) { |
||||
|
var |
||||
|
html = '' |
||||
|
; |
||||
|
if(message !== undefined && type !== undefined) { |
||||
|
html += '' |
||||
|
+ '<div class="message ' + type +'">' |
||||
|
+ '<div class="text">' |
||||
|
; |
||||
|
// message type
|
||||
|
if(type == 'empty') { |
||||
|
html += '' |
||||
|
+ '<h2>No Results</h2>' |
||||
|
+ '<p>' + message + '</p>' |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
html += ' <div class="text">' + message + '</div>'; |
||||
|
} |
||||
|
html += '</div>'; |
||||
|
} |
||||
|
return html; |
||||
|
}, |
||||
|
categories: function(response) { |
||||
|
var |
||||
|
html = '' |
||||
|
; |
||||
|
if(response.results !== undefined) { |
||||
|
// each category
|
||||
|
$.each(response.results, function(index, category) { |
||||
|
if(category.results !== undefined && category.results.length > 0) { |
||||
|
html += '' |
||||
|
+ '<div class="category">' |
||||
|
+ '<div class="name">' + category.name + '</div>' |
||||
|
+ '<ul>' |
||||
|
; |
||||
|
// each item inside category
|
||||
|
$.each(category.results, function(index, result) { |
||||
|
html += '<li class="result">'; |
||||
|
html += '<a href="' + result.url + '"></a>'; |
||||
|
if(result.image !== undefined) { |
||||
|
html+= '' |
||||
|
+ '<div class="image">' |
||||
|
+ ' <img src="' + result.image + '">' |
||||
|
+ '</div>' |
||||
|
; |
||||
|
} |
||||
|
html += (result.image !== undefined) |
||||
|
? '<div class="indented info">' |
||||
|
: '<div class="info">' |
||||
|
; |
||||
|
if(result.price !== undefined) { |
||||
|
html+= '<div class="price">' + result.price + '</div>'; |
||||
|
} |
||||
|
if(result.title !== undefined) { |
||||
|
html+= '<div class="title">' + result.title + '</div>'; |
||||
|
} |
||||
|
if(result.description !== undefined) { |
||||
|
html+= '<div class="description">' + result.description + '</div>'; |
||||
|
} |
||||
|
html += '' |
||||
|
+ '</div>' |
||||
|
+ '</li>' |
||||
|
; |
||||
|
}); |
||||
|
html += '' |
||||
|
+ '</ul>' |
||||
|
+ '</div>' |
||||
|
; |
||||
|
} |
||||
|
}); |
||||
|
if(response.resultPage) { |
||||
|
html += '' |
||||
|
+ '<a href="' + response.resultPage.url + '" class="result-page">' |
||||
|
+ response.resultPage.text |
||||
|
+ '</a>'; |
||||
|
} |
||||
|
return html; |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
simple: function(response) { |
||||
|
var |
||||
|
html = '' |
||||
|
; |
||||
|
if(response.results !== undefined) { |
||||
|
html += '<ul>'; |
||||
|
// each result
|
||||
|
$.each(response.results, function(index, result) { |
||||
|
html += '<li class="result">'; |
||||
|
|
||||
|
if(result.url !== undefined) { |
||||
|
html += '<a href="' + result.url + '"></a>'; |
||||
|
} |
||||
|
if(result.image !== undefined) { |
||||
|
html+= '' |
||||
|
+ '<div class="image">' |
||||
|
+ ' <img src="' + result.image + '">' |
||||
|
+ '</div>' |
||||
|
; |
||||
|
} |
||||
|
html += (result.image !== undefined) |
||||
|
? '<div class="indented info">' |
||||
|
: '<div class="info">' |
||||
|
; |
||||
|
if(result.price !== undefined) { |
||||
|
html+= '<div class="price">' + result.price + '</div>'; |
||||
|
} |
||||
|
if(result.title !== undefined) { |
||||
|
html+= '<div class="title">' + result.title + '</div>'; |
||||
|
} |
||||
|
if(result.description !== undefined) { |
||||
|
html+= '<div class="description">' + result.description + '</div>'; |
||||
|
} |
||||
|
html += '' |
||||
|
+ '</div>' |
||||
|
+ '</li>' |
||||
|
; |
||||
|
}); |
||||
|
html += '</ul>'; |
||||
|
|
||||
|
if(response.resultPage) { |
||||
|
html += '' |
||||
|
+ '<a href="' + response.resultPage.url + '" class="result-page">' |
||||
|
+ response.resultPage.text |
||||
|
+ '</a>'; |
||||
|
} |
||||
|
return html; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,640 @@ |
|||||
|
/* ******************************************************************************************* |
||||
|
|
||||
|
Shape - A 3D Animation Plugin |
||||
|
Version 0.1 |
||||
|
(built using Semantic module spec) |
||||
|
|
||||
|
Author : Jack Lukic |
||||
|
Last revision : April 2013 |
||||
|
|
||||
|
********************************************************************************************* */ |
||||
|
|
||||
|
;(function ( $, window, document, undefined ) { |
||||
|
|
||||
|
$.fn.shape = function(parameters) { |
||||
|
var |
||||
|
$allModules = $(this), |
||||
|
|
||||
|
settings = $.extend(true, {}, $.fn.shape.settings, parameters), |
||||
|
|
||||
|
// define namespaces for modules
|
||||
|
eventNamespace = '.' + settings.namespace, |
||||
|
moduleNamespace = 'module-' + settings.namespace, |
||||
|
|
||||
|
// allow methods to be queried directly
|
||||
|
query = arguments[0], |
||||
|
queryArguments = [].slice.call(arguments, 1), |
||||
|
methodInvoked = (typeof query == 'string'), |
||||
|
invokedResponse |
||||
|
; |
||||
|
|
||||
|
$allModules |
||||
|
.each(function() { |
||||
|
var |
||||
|
// selector cache
|
||||
|
$module = $(this), |
||||
|
$shape = $module.find(settings.selector.shape), |
||||
|
$side = $module.find(settings.selector.side), |
||||
|
|
||||
|
// private variables
|
||||
|
$activeSide, |
||||
|
$nextSide, |
||||
|
endTransition = 'transitionend msTransitionEnd oTransitionEnd', |
||||
|
|
||||
|
// standard module
|
||||
|
selector = $module.selector || '', |
||||
|
element = this, |
||||
|
instance = $module.data(moduleNamespace), |
||||
|
|
||||
|
// internal aliases
|
||||
|
namespace = settings.namespace, |
||||
|
error = settings.error, |
||||
|
className = settings.className, |
||||
|
|
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
initialize: function() { |
||||
|
module.verbose('Initializing module for', element); |
||||
|
module.set.defaultSide(); |
||||
|
instance = module; |
||||
|
$module |
||||
|
.data(moduleNamespace, instance) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
destroy: function() { |
||||
|
module.verbose('Destroying previous module for', element); |
||||
|
$module |
||||
|
.removeData(moduleNamespace) |
||||
|
.off(eventNamespace) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
refresh: function() { |
||||
|
module.verbose('Refreshing selector cache for', element); |
||||
|
$module = $(element); |
||||
|
$shape = $(this).find(settings.selector.shape); |
||||
|
$side = $(this).find(settings.selector.side); |
||||
|
}, |
||||
|
|
||||
|
repaint: function() { |
||||
|
module.verbose('Forcing repaint event'); |
||||
|
var |
||||
|
shape = $shape.get(0) || document.createElement('div'), |
||||
|
fakeAssignment = shape.offsetWidth |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
animate: function(propertyObject, callback) { |
||||
|
module.verbose('Animating box with properties', propertyObject); |
||||
|
callback = callback || function(event) { |
||||
|
module.reset(); |
||||
|
module.set.active(); |
||||
|
$.proxy(settings.onChange, $nextSide)(); |
||||
|
event.stopImmediatePropagation(); |
||||
|
}; |
||||
|
if(settings.useCSS) { |
||||
|
module.verbose('Starting CSS animation'); |
||||
|
$module |
||||
|
.addClass(className.animating) |
||||
|
; |
||||
|
module.set.stageSize(); |
||||
|
module.repaint(); |
||||
|
$module |
||||
|
.addClass(className.css) |
||||
|
; |
||||
|
$activeSide |
||||
|
.addClass(className.hidden) |
||||
|
; |
||||
|
$shape |
||||
|
.css(propertyObject) |
||||
|
.one(endTransition, callback) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
// not yet supported until .animate() is extended to allow RotateX/Y
|
||||
|
module.verbose('Starting javascript animation'); |
||||
|
$module |
||||
|
.addClass(className.animating) |
||||
|
.removeClass(className.css) |
||||
|
; |
||||
|
module.set.stageSize(); |
||||
|
module.repaint(); |
||||
|
$activeSide |
||||
|
.animate({ |
||||
|
opacity: 0 |
||||
|
}, settings.duration, settings.easing) |
||||
|
; |
||||
|
$shape |
||||
|
.animate(propertyObject, settings.duration, settings.easing, callback) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
queue: function(method) { |
||||
|
module.debug('Queueing animation of', method); |
||||
|
$shape |
||||
|
.one(endTransition, function() { |
||||
|
module.debug('Executing queued animation'); |
||||
|
$module.shape(method); |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
reset: function() { |
||||
|
module.verbose('Animating states reset'); |
||||
|
$module |
||||
|
.removeClass(className.css) |
||||
|
.removeClass(className.animating) |
||||
|
.removeAttr('style') |
||||
|
; |
||||
|
$shape |
||||
|
.removeAttr('style') |
||||
|
; |
||||
|
$side |
||||
|
.removeAttr('style') |
||||
|
.removeClass(className.hidden) |
||||
|
; |
||||
|
$nextSide |
||||
|
.removeClass(className.animating) |
||||
|
.removeAttr('style') |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
is: { |
||||
|
|
||||
|
animating: function() { |
||||
|
return $module.hasClass(className.animating); |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
get: { |
||||
|
|
||||
|
nextSide: function() { |
||||
|
return ( $activeSide.next(settings.selector.side).size() > 0 ) |
||||
|
? $activeSide.next(settings.selector.side) |
||||
|
: $module.find(settings.selector.side).first() |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
set: { |
||||
|
|
||||
|
defaultSide: function() { |
||||
|
$activeSide = $module.find('.' + settings.className.active); |
||||
|
$nextSide = ( $activeSide.next(settings.selector.side).size() > 0 ) |
||||
|
? $activeSide.next(settings.selector.side) |
||||
|
: $module.find(settings.selector.side).first() |
||||
|
; |
||||
|
module.verbose('Active side set to', $activeSide); |
||||
|
module.verbose('Next side set to', $nextSide); |
||||
|
}, |
||||
|
|
||||
|
stageSize: function() { |
||||
|
var |
||||
|
stage = { |
||||
|
width : $nextSide.outerWidth(), |
||||
|
height : $nextSide.outerHeight() |
||||
|
} |
||||
|
; |
||||
|
module.verbose('Resizing stage to fit new content', stage); |
||||
|
$module |
||||
|
.css({ |
||||
|
width : stage.width, |
||||
|
height : stage.height |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
nextSide: function(selector) { |
||||
|
$nextSide = $module.find(selector); |
||||
|
if($nextSide.size() === 0) { |
||||
|
module.error(error.side); |
||||
|
} |
||||
|
module.verbose('Next side manually set to', $nextSide); |
||||
|
}, |
||||
|
|
||||
|
active: function() { |
||||
|
module.verbose('Setting new side to active', $nextSide); |
||||
|
$side |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
$nextSide |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
module.set.defaultSide(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
flip: { |
||||
|
|
||||
|
up: function() { |
||||
|
module.debug('Flipping up', $nextSide); |
||||
|
if( !module.is.animating() ) { |
||||
|
module.stage.above(); |
||||
|
module.animate( module.getTransform.up() ); |
||||
|
} |
||||
|
else { |
||||
|
module.queue('flip.up'); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
down: function() { |
||||
|
module.debug('Flipping down', $nextSide); |
||||
|
if( !module.is.animating() ) { |
||||
|
module.stage.below(); |
||||
|
module.animate( module.getTransform.down() ); |
||||
|
} |
||||
|
else { |
||||
|
module.queue('flip.down'); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
left: function() { |
||||
|
module.debug('Flipping left', $nextSide); |
||||
|
if( !module.is.animating() ) { |
||||
|
module.stage.left(); |
||||
|
module.animate(module.getTransform.left() ); |
||||
|
} |
||||
|
else { |
||||
|
module.queue('flip.left'); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
right: function() { |
||||
|
module.debug('Flipping right', $nextSide); |
||||
|
if( !module.is.animating() ) { |
||||
|
module.stage.right(); |
||||
|
module.animate(module.getTransform.right() ); |
||||
|
} |
||||
|
else { |
||||
|
module.queue('flip.right'); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
over: function() { |
||||
|
module.debug('Flipping over', $nextSide); |
||||
|
if( !module.is.animating() ) { |
||||
|
module.stage.behind(); |
||||
|
module.animate(module.getTransform.behind() ); |
||||
|
} |
||||
|
else { |
||||
|
module.queue('flip.over'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
getTransform: { |
||||
|
|
||||
|
up: function() { |
||||
|
var |
||||
|
translate = { |
||||
|
y: -(($activeSide.outerHeight() - $nextSide.outerHeight()) / 2), |
||||
|
z: -($activeSide.outerHeight() / 2) |
||||
|
} |
||||
|
; |
||||
|
return { |
||||
|
transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(-90deg)' |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
down: function() { |
||||
|
var |
||||
|
translate = { |
||||
|
y: -(($activeSide.outerHeight() - $nextSide.outerHeight()) / 2), |
||||
|
z: -($activeSide.outerHeight() / 2) |
||||
|
} |
||||
|
; |
||||
|
return { |
||||
|
transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(90deg)' |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
left: function() { |
||||
|
var |
||||
|
translate = { |
||||
|
x : -(($activeSide.outerWidth() - $nextSide.outerWidth()) / 2), |
||||
|
z : -($activeSide.outerWidth() / 2) |
||||
|
} |
||||
|
; |
||||
|
return { |
||||
|
transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(90deg)' |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
right: function() { |
||||
|
var |
||||
|
translate = { |
||||
|
x : -(($activeSide.outerWidth() - $nextSide.outerWidth()) / 2), |
||||
|
z : -($activeSide.outerWidth() / 2) |
||||
|
} |
||||
|
; |
||||
|
return { |
||||
|
transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(-90deg)' |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
behind: function() { |
||||
|
var |
||||
|
translate = { |
||||
|
x : -(($activeSide.outerWidth() - $nextSide.outerWidth()) / 2) |
||||
|
} |
||||
|
; |
||||
|
return { |
||||
|
transform: 'translateX(' + translate.x + 'px) rotateY(180deg)' |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
stage: { |
||||
|
|
||||
|
above: function() { |
||||
|
var |
||||
|
box = { |
||||
|
origin : (($activeSide.outerHeight() - $nextSide.outerHeight()) / 2), |
||||
|
depth : { |
||||
|
active : ($nextSide.outerHeight() / 2), |
||||
|
next : ($activeSide.outerHeight() / 2) |
||||
|
} |
||||
|
} |
||||
|
; |
||||
|
module.verbose('Setting the initial animation position as above', $nextSide, box); |
||||
|
$activeSide |
||||
|
.css({ |
||||
|
'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
||||
|
}) |
||||
|
; |
||||
|
$nextSide |
||||
|
.addClass(className.animating) |
||||
|
.css({ |
||||
|
'display' : 'block', |
||||
|
'top' : box.origin + 'px', |
||||
|
'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px)' |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
below: function() { |
||||
|
var |
||||
|
box = { |
||||
|
origin : (($activeSide.outerHeight() - $nextSide.outerHeight()) / 2), |
||||
|
depth : { |
||||
|
active : ($nextSide.outerHeight() / 2), |
||||
|
next : ($activeSide.outerHeight() / 2) |
||||
|
} |
||||
|
} |
||||
|
; |
||||
|
module.verbose('Setting the initial animation position as below', $nextSide, box); |
||||
|
$activeSide |
||||
|
.css({ |
||||
|
'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
||||
|
}) |
||||
|
; |
||||
|
$nextSide |
||||
|
.addClass(className.animating) |
||||
|
.css({ |
||||
|
'display' : 'block', |
||||
|
'top' : box.origin + 'px', |
||||
|
'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px)' |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
left: function() { |
||||
|
var |
||||
|
box = { |
||||
|
origin : ( ( $activeSide.outerWidth() - $nextSide.outerWidth() ) / 2), |
||||
|
depth : { |
||||
|
active : ($nextSide.outerWidth() / 2), |
||||
|
next : ($activeSide.outerWidth() / 2) |
||||
|
} |
||||
|
} |
||||
|
; |
||||
|
module.verbose('Setting the initial animation position as left', $nextSide, box); |
||||
|
$activeSide |
||||
|
.css({ |
||||
|
'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
||||
|
}) |
||||
|
; |
||||
|
$nextSide |
||||
|
.addClass(className.animating) |
||||
|
.css({ |
||||
|
'display' : 'block', |
||||
|
'left' : box.origin + 'px', |
||||
|
'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px)' |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
right: function() { |
||||
|
var |
||||
|
box = { |
||||
|
origin : ( ( $activeSide.outerWidth() - $nextSide.outerWidth() ) / 2), |
||||
|
depth : { |
||||
|
active : ($nextSide.outerWidth() / 2), |
||||
|
next : ($activeSide.outerWidth() / 2) |
||||
|
} |
||||
|
} |
||||
|
; |
||||
|
module.verbose('Setting the initial animation position as left', $nextSide, box); |
||||
|
$activeSide |
||||
|
.css({ |
||||
|
'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' |
||||
|
}) |
||||
|
; |
||||
|
$nextSide |
||||
|
.addClass(className.animating) |
||||
|
.css({ |
||||
|
'display' : 'block', |
||||
|
'left' : box.origin + 'px', |
||||
|
'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px)' |
||||
|
}) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
behind: function() { |
||||
|
var |
||||
|
box = { |
||||
|
origin : ( ( $activeSide.outerWidth() - $nextSide.outerWidth() ) / 2), |
||||
|
depth : { |
||||
|
active : ($nextSide.outerWidth() / 2), |
||||
|
next : ($activeSide.outerWidth() / 2) |
||||
|
} |
||||
|
} |
||||
|
; |
||||
|
module.verbose('Setting the initial animation position as behind', $nextSide, box); |
||||
|
$activeSide |
||||
|
.css({ |
||||
|
'transform' : 'rotateY(0deg)' |
||||
|
}) |
||||
|
; |
||||
|
$nextSide |
||||
|
.addClass(className.animating) |
||||
|
.css({ |
||||
|
'display' : 'block', |
||||
|
'left' : box.origin + 'px', |
||||
|
'transform' : 'rotateY(-180deg)' |
||||
|
}) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* standard module */ |
||||
|
setting: function(name, value) { |
||||
|
if( $.isPlainObject(name) ) { |
||||
|
$.extend(true, settings, name); |
||||
|
} |
||||
|
else if(value === undefined) { |
||||
|
return settings[name]; |
||||
|
} |
||||
|
else { |
||||
|
settings[name] = value; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
verbose: function() { |
||||
|
if(settings.verbose) { |
||||
|
module.debug.apply(this, arguments); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
debug: function() { |
||||
|
var |
||||
|
output = [], |
||||
|
message = settings.moduleName + ': ' + arguments[0], |
||||
|
variables = [].slice.call( arguments, 1 ), |
||||
|
log = console.info || console.log || function(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
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(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
if(settings.debug) { |
||||
|
output.push(errorMessage); |
||||
|
output.concat(variables); |
||||
|
log.apply(console, output.concat(variables) ); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
invoke: function(query, passedArguments, context) { |
||||
|
var |
||||
|
maxDepth, |
||||
|
found |
||||
|
; |
||||
|
passedArguments = passedArguments || queryArguments || [].slice.call( arguments, 2 ); |
||||
|
context = element || context; |
||||
|
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(error.method); |
||||
|
return false; |
||||
|
}); |
||||
|
} |
||||
|
if ( $.isFunction( found ) ) { |
||||
|
module.verbose('Executing invoked function', found); |
||||
|
return found.apply(context, passedArguments); |
||||
|
} |
||||
|
// return retrieved variable or chain
|
||||
|
return found || false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// check for invoking internal method
|
||||
|
if(methodInvoked) { |
||||
|
if(instance === undefined) { |
||||
|
module.initialize(); |
||||
|
} |
||||
|
invokedResponse = module.invoke(query); |
||||
|
} |
||||
|
// otherwise initialize
|
||||
|
else { |
||||
|
if(instance !== undefined) { |
||||
|
module.destroy(); |
||||
|
} |
||||
|
module.initialize(); |
||||
|
} |
||||
|
}) |
||||
|
; |
||||
|
// chain or return queried method
|
||||
|
return (invokedResponse) |
||||
|
? invokedResponse |
||||
|
: this |
||||
|
; |
||||
|
}; |
||||
|
|
||||
|
$.fn.shape.settings = { |
||||
|
|
||||
|
// module info
|
||||
|
moduleName : 'Shape Module', |
||||
|
|
||||
|
// debug content outputted to console
|
||||
|
debug : true, |
||||
|
|
||||
|
// verbose debug output
|
||||
|
verbose : true, |
||||
|
|
||||
|
// event namespace
|
||||
|
namespace : 'shape', |
||||
|
|
||||
|
// callback occurs on side change
|
||||
|
beforeChange : function() {}, |
||||
|
onChange : function() {}, |
||||
|
|
||||
|
// use css animation (currently only true is supported)
|
||||
|
useCSS : true, |
||||
|
|
||||
|
// animation duration (useful only with future js animations)
|
||||
|
duration : 1000, |
||||
|
easing : 'easeInOutQuad', |
||||
|
|
||||
|
// possible errors
|
||||
|
error: { |
||||
|
side : 'You tried to switch to a side that does not exist.', |
||||
|
method : 'The method you called is not defined' |
||||
|
}, |
||||
|
|
||||
|
// classnames used
|
||||
|
className : { |
||||
|
css : 'css', |
||||
|
animating : 'animating', |
||||
|
hidden : 'hidden', |
||||
|
active : 'active' |
||||
|
}, |
||||
|
|
||||
|
// selectors used
|
||||
|
selector : { |
||||
|
shape : '.shape', |
||||
|
side : '.side' |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,180 @@ |
|||||
|
/* ****************************** |
||||
|
Star Review |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit Sep 04, 2012 |
||||
|
|
||||
|
Simple rating module |
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ($, window, document, undefined) { |
||||
|
|
||||
|
$.fn.starReview = function(parameters) { |
||||
|
var |
||||
|
settings = $.extend(true, {}, $.fn.starReview.settings, parameters), |
||||
|
// hoist arguments
|
||||
|
moduleArguments = arguments || false |
||||
|
; |
||||
|
$(this) |
||||
|
.each(function() { |
||||
|
var |
||||
|
$module = $(this), |
||||
|
$star = $module.find(settings.selector.star), |
||||
|
|
||||
|
className = settings.className, |
||||
|
namespace = settings.namespace, |
||||
|
instance = $module.data('module'), |
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
settings: settings, |
||||
|
|
||||
|
initialize: function() { |
||||
|
if(settings.rateable) { |
||||
|
// expandable with states
|
||||
|
if($.fn.state !== undefined) { |
||||
|
$module |
||||
|
.state() |
||||
|
; |
||||
|
$star |
||||
|
.state() |
||||
|
; |
||||
|
} |
||||
|
$star |
||||
|
.bind('mouseenter.' + namespace, module.event.mouseenter) |
||||
|
.bind('mouseleave.' + namespace, module.event.mouseleave) |
||||
|
.bind('click.' + namespace, module.event.click) |
||||
|
; |
||||
|
} |
||||
|
$module |
||||
|
.addClass(className.initialize) |
||||
|
.data('module', module) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
setRating: function(rating) { |
||||
|
var |
||||
|
$activeStar = $star.eq(rating - 1) |
||||
|
; |
||||
|
$module |
||||
|
.removeClass(className.hover) |
||||
|
; |
||||
|
$star |
||||
|
.removeClass(className.hover) |
||||
|
; |
||||
|
$activeStar |
||||
|
.nextAll() |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
$activeStar |
||||
|
.addClass(className.active) |
||||
|
.prevAll() |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
$.proxy(settings.onRate, $module)(); |
||||
|
}, |
||||
|
|
||||
|
event: { |
||||
|
mouseenter: function() { |
||||
|
var |
||||
|
$activeStar = $(this) |
||||
|
; |
||||
|
$activeStar |
||||
|
.nextAll() |
||||
|
.removeClass(className.hover) |
||||
|
; |
||||
|
$module |
||||
|
.addClass(className.hover) |
||||
|
; |
||||
|
$activeStar |
||||
|
.addClass(className.hover) |
||||
|
.prevAll() |
||||
|
.addClass(className.hover) |
||||
|
; |
||||
|
}, |
||||
|
mouseleave: function() { |
||||
|
$star |
||||
|
.removeClass(className.hover) |
||||
|
; |
||||
|
}, |
||||
|
click: function() { |
||||
|
var |
||||
|
$activeStar = $(this) |
||||
|
; |
||||
|
module.setRating( $star.index($activeStar) + 1); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// handle error logging
|
||||
|
error: function(errorMessage) { |
||||
|
console.warn(settings.moduleName + ': ' + errorMessage); |
||||
|
}, |
||||
|
|
||||
|
// allows for dot notation method calls
|
||||
|
invoke: function(methodName, context, methodArguments) { |
||||
|
var |
||||
|
method |
||||
|
; |
||||
|
methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 ); |
||||
|
if(typeof methodName == 'string' && instance !== undefined) { |
||||
|
methodName = methodName.split('.'); |
||||
|
$.each(methodName, function(index, name) { |
||||
|
if( $.isPlainObject( instance[name] ) ) { |
||||
|
instance = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
else if( $.isFunction( instance[name] ) ) { |
||||
|
method = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
module.error(settings.errors.method); |
||||
|
return false; |
||||
|
}); |
||||
|
} |
||||
|
return ( $.isFunction( method ) ) |
||||
|
? method.apply(context, methodArguments) |
||||
|
: false |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
if(instance !== undefined && moduleArguments) { |
||||
|
// simpler than invoke realizing to invoke itself (and losing scope due prototype.call()
|
||||
|
if(moduleArguments[0] == 'invoke') { |
||||
|
moduleArguments = Array.prototype.slice.call( moduleArguments, 1 ); |
||||
|
} |
||||
|
return module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) ); |
||||
|
} |
||||
|
// initializing
|
||||
|
module.initialize(); |
||||
|
}) |
||||
|
; |
||||
|
|
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
$.fn.starReview.settings = { |
||||
|
|
||||
|
moduleName : 'Star Module', |
||||
|
namespace : 'star', |
||||
|
|
||||
|
rateable : true, |
||||
|
onRate : function(){}, |
||||
|
|
||||
|
className : { |
||||
|
initialize : 'initialize', |
||||
|
loading : 'loading', |
||||
|
active : 'active', |
||||
|
hover : 'hover', |
||||
|
down : 'down' |
||||
|
}, |
||||
|
|
||||
|
selector : { |
||||
|
star : 'i' |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,523 @@ |
|||||
|
/* ****************************** |
||||
|
Module - Simple Tab Navigation |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit Aug 15, 2012 |
||||
|
|
||||
|
History based tab navigation |
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ($, window, document, undefined) { |
||||
|
|
||||
|
$.fn.tabNavigation = function(parameters) { |
||||
|
|
||||
|
var |
||||
|
settings = $.extend(true, {}, $.fn.tabNavigation.settings, parameters), |
||||
|
|
||||
|
$tabNavigation = $(this), |
||||
|
$tabs = $(settings.context).find(settings.selector.tabs), |
||||
|
|
||||
|
firstLoad = true, |
||||
|
cache = {}, |
||||
|
recursionDepth = 0, |
||||
|
|
||||
|
activeTabPath, |
||||
|
parameterArray, |
||||
|
historyEvent, |
||||
|
|
||||
|
className = settings.className, |
||||
|
metadata = settings.metadata, |
||||
|
namespace = settings.namespace, |
||||
|
errors = settings.errors, |
||||
|
|
||||
|
instance = $tabNavigation.data('module'), |
||||
|
|
||||
|
query = arguments[0], |
||||
|
methodInvoked = (instance !== undefined && typeof query == 'string'), |
||||
|
passedArguments = [].slice.call(arguments, 1), |
||||
|
|
||||
|
module, |
||||
|
invokedResponse |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
initialize: function() { |
||||
|
module.debug('Initializing Tabs', $tabNavigation); |
||||
|
// attach history events
|
||||
|
if(settings.history && settings.path !== false) { |
||||
|
if( $.address !== undefined ) { |
||||
|
module.verbose('Address library found adding state change event'); |
||||
|
$.address |
||||
|
.state(settings.path) |
||||
|
.change(module.event.history.change) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
module.error(errors.state); |
||||
|
} |
||||
|
} |
||||
|
// attach events if navigation wasn't set to window
|
||||
|
if( !$.isWindow( $tabNavigation.get(0) ) ) { |
||||
|
$tabNavigation |
||||
|
.on('click.' + namespace, module.event.click) |
||||
|
; |
||||
|
} |
||||
|
$tabNavigation |
||||
|
.data('module', module) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
destroy: function() { |
||||
|
module.debug('Destroying tabs', $tabNavigation); |
||||
|
$tabNavigation |
||||
|
.off('.' + namespace) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
event: { |
||||
|
click: function() { |
||||
|
module.debug('Navigation clicked'); |
||||
|
var |
||||
|
tabPath = $(this).data(metadata.tab) |
||||
|
; |
||||
|
if(tabPath !== undefined) { |
||||
|
if(tabPath !== activeTabPath) { |
||||
|
if(settings.history) { |
||||
|
$.address.value(tabPath); |
||||
|
} |
||||
|
else { |
||||
|
module.change(tabPath); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
module.debug('No tab specified'); |
||||
|
} |
||||
|
}, |
||||
|
history: { |
||||
|
change: function(event) { |
||||
|
var |
||||
|
tabPath = event.pathNames.join('/') || module.get.initialPath(), |
||||
|
pageTitle = settings.templates.determineTitle(tabPath) || false |
||||
|
; |
||||
|
module.debug('History change event', tabPath, event); |
||||
|
historyEvent = event; |
||||
|
if(tabPath !== undefined) { |
||||
|
module.change(tabPath); |
||||
|
} |
||||
|
if(pageTitle) { |
||||
|
$.address.title(pageTitle); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
refresh: function() { |
||||
|
if(activeTabPath) { |
||||
|
module.debug('Refreshing tab', activeTabPath); |
||||
|
module.change(activeTabPath); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
cache: { |
||||
|
read: function(tabPath) { |
||||
|
return (tabPath !== undefined) |
||||
|
? cache[tabPath] |
||||
|
: cache |
||||
|
; |
||||
|
}, |
||||
|
add: function(tabPath, content) { |
||||
|
tabPath = tabPath || activeTabPath; |
||||
|
module.debug('Adding cached content for', tabPath); |
||||
|
cache[tabPath] = content; |
||||
|
}, |
||||
|
remove: function(tabPath) { |
||||
|
tabPath = tabPath || activeTabPath; |
||||
|
module.debug('Removing cached content for', tabPath); |
||||
|
delete cache[tabPath]; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
change: function(tabPath) { |
||||
|
var |
||||
|
pathArray = module.get.defaultPathArray(tabPath) |
||||
|
; |
||||
|
module.deactivate.all(); |
||||
|
$.each(pathArray, function(index, tab) { |
||||
|
var |
||||
|
currentPathArray = pathArray.slice(0, index + 1), |
||||
|
currentPath = module.utils.arrayToPath(currentPathArray), |
||||
|
|
||||
|
isLastTab = (module.utils.last(pathArray) == currentPath), |
||||
|
isTab = module.is.tab(currentPath), |
||||
|
isParam = !(isTab), |
||||
|
|
||||
|
pushStateAvailable = (window.history && window.history.pushState), |
||||
|
shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad), |
||||
|
remoteContent = $.isPlainObject(settings.apiSettings), |
||||
|
|
||||
|
$tab = module.get.tabElement(currentPath) |
||||
|
; |
||||
|
module.verbose('Looking for tab', tab); |
||||
|
if(isParam) { |
||||
|
module.verbose('Tab is not found, assuming it is a parameter', tab); |
||||
|
return true; |
||||
|
} |
||||
|
else if(isTab) { |
||||
|
// scope up
|
||||
|
module.verbose('Tab was found', tab); |
||||
|
activeTabPath = currentPath; |
||||
|
parameterArray = module.utils.filterArray(pathArray, currentPathArray); |
||||
|
if(isLastTab && remoteContent) { |
||||
|
if(!shouldIgnoreLoad) { |
||||
|
module.activate.navigation(currentPath); |
||||
|
module.content.fetch(currentPath, settings.onTabLoad); |
||||
|
} |
||||
|
else { |
||||
|
module.debug('Ignoring remote content on first tab load', currentPath); |
||||
|
firstLoad = false; |
||||
|
cache[tabPath] = $tab.html(); |
||||
|
module.activate.all(currentPath); |
||||
|
$.proxy(settings.onTabInit, $tab)(currentPath, parameterArray, historyEvent); |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
module.debug('Opened tab', currentPath); |
||||
|
module.activate.all(currentPath); |
||||
|
$.proxy(settings.onTabLoad, $tab)(currentPath, parameterArray, historyEvent); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
content: { |
||||
|
|
||||
|
fetch: function(tabPath) { |
||||
|
var |
||||
|
$tab = module.get.tabElement(tabPath), |
||||
|
cachedContent = cache[tabPath] || false, |
||||
|
apiSettings = { |
||||
|
dataType : 'html', |
||||
|
stateContext : $tab, |
||||
|
success : function(response) { |
||||
|
cache[tabPath] = response; |
||||
|
module.content.update(tabPath, response); |
||||
|
if(tabPath == activeTabPath) { |
||||
|
module.debug('Content loaded', tabPath); |
||||
|
module.activate.tab(tabPath); |
||||
|
} |
||||
|
else { |
||||
|
module.debug('Content loaded in background', tabPath); |
||||
|
} |
||||
|
$.proxy(settings.onTabInit, $tab)(tabPath, parameterArray, historyEvent); |
||||
|
}, |
||||
|
urlData: { tab: tabPath } |
||||
|
}, |
||||
|
request = $tab.data(metadata.promise) || false, |
||||
|
existingRequest = ( request && request.state() === 'pending' ) |
||||
|
; |
||||
|
if(settings.cache && cachedContent) { |
||||
|
module.debug('Showing existing content', tabPath); |
||||
|
// module.content.update(tabPath, cachedContent);
|
||||
|
module.activate.tab(tabPath); |
||||
|
$.proxy(settings.onTabLoad, $tab)(tabPath, parameterArray, historyEvent); |
||||
|
} |
||||
|
else if(existingRequest) { |
||||
|
module.debug('Content is already loading', tabPath); |
||||
|
$tab |
||||
|
.addClass(className.loading) |
||||
|
; |
||||
|
} |
||||
|
else if($.api !== undefined) { |
||||
|
module.debug('Retrieving content', tabPath); |
||||
|
$.api( $.extend(true, {}, settings.apiSettings, apiSettings) ); |
||||
|
} |
||||
|
else { |
||||
|
module.error(errors.api); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
update: function(tabPath, html) { |
||||
|
module.debug('Updating html for', tabPath); |
||||
|
var |
||||
|
$tab = module.get.tabElement(tabPath) |
||||
|
; |
||||
|
$tab |
||||
|
.html(html) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
activate: { |
||||
|
all: function(tabPath) { |
||||
|
module.activate.tab(tabPath); |
||||
|
module.activate.navigation(tabPath); |
||||
|
}, |
||||
|
tab: function(tabPath) { |
||||
|
var |
||||
|
$tab = module.get.tabElement(tabPath) |
||||
|
; |
||||
|
module.verbose('Showing tab content for', $tab); |
||||
|
$tab.addClass(className.active); |
||||
|
}, |
||||
|
navigation: function(tabPath) { |
||||
|
var |
||||
|
$nav = module.get.navElement(tabPath) |
||||
|
; |
||||
|
module.verbose('Activating tab navigation for', $nav); |
||||
|
$nav.addClass(className.active); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
deactivate: { |
||||
|
all: function() { |
||||
|
module.deactivate.navigation(); |
||||
|
module.deactivate.tabs(); |
||||
|
}, |
||||
|
navigation: function() { |
||||
|
$tabNavigation |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
}, |
||||
|
tabs: function() { |
||||
|
$tabs |
||||
|
.removeClass(className.active + ' ' + className.loading) |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
is: { |
||||
|
tab: function(tabName) { |
||||
|
return ( module.get.tabElement(tabName).size() > 0 ); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
get: { |
||||
|
initialPath: function() { |
||||
|
return $tabNavigation.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab); |
||||
|
}, |
||||
|
// adds default tabs to tab path
|
||||
|
defaultPathArray: function(tabPath) { |
||||
|
return module.utils.pathToArray( module.get.defaultPath(tabPath) ); |
||||
|
}, |
||||
|
defaultPath: function(tabPath) { |
||||
|
var |
||||
|
$defaultNav = $tabNavigation.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0), |
||||
|
defaultTab = $defaultNav.data(metadata.tab) || false |
||||
|
; |
||||
|
if( defaultTab ) { |
||||
|
module.debug('Found default tab', defaultTab); |
||||
|
if(recursionDepth < settings.maxDepth) { |
||||
|
recursionDepth++; |
||||
|
return module.get.defaultPath(defaultTab); |
||||
|
} |
||||
|
module.error(errors.recursion); |
||||
|
} |
||||
|
recursionDepth = 0; |
||||
|
return tabPath; |
||||
|
}, |
||||
|
navElement: function(tabPath) { |
||||
|
tabPath = tabPath || activeTabPath; |
||||
|
return $tabNavigation.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); |
||||
|
}, |
||||
|
tabElement: function(tabPath) { |
||||
|
var |
||||
|
$fullPathTab, |
||||
|
$simplePathTab, |
||||
|
tabPathArray, |
||||
|
lastTab |
||||
|
; |
||||
|
tabPath = tabPath || activeTabPath; |
||||
|
tabPathArray = module.utils.pathToArray(tabPath); |
||||
|
lastTab = module.utils.last(tabPathArray); |
||||
|
$fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]'); |
||||
|
$simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); |
||||
|
return ($fullPathTab.size() > 0) |
||||
|
? $fullPathTab |
||||
|
: $simplePathTab |
||||
|
; |
||||
|
}, |
||||
|
tab: function() { |
||||
|
return activeTabPath; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
utils: { |
||||
|
filterArray: function(keepArray, removeArray) { |
||||
|
return $.grep(keepArray, function(keepValue) { |
||||
|
return ( $.inArray(keepValue, removeArray) == -1); |
||||
|
}); |
||||
|
}, |
||||
|
last: function(array) { |
||||
|
return $.isArray(array) |
||||
|
? array[ array.length - 1] |
||||
|
: false |
||||
|
; |
||||
|
}, |
||||
|
pathToArray: function(pathName) { |
||||
|
if(pathName === undefined) { |
||||
|
pathName = activeTabPath; |
||||
|
} |
||||
|
return typeof pathName == 'string' |
||||
|
? pathName.split('/') |
||||
|
: [pathName] |
||||
|
; |
||||
|
}, |
||||
|
arrayToPath: function(pathArray) { |
||||
|
return $.isArray(pathArray) |
||||
|
? pathArray.join('/') |
||||
|
: false |
||||
|
; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* standard module */ |
||||
|
setting: function(name, value) { |
||||
|
if(value === undefined) { |
||||
|
return settings[name]; |
||||
|
} |
||||
|
settings[name] = value; |
||||
|
}, |
||||
|
verbose: function() { |
||||
|
if(settings.verbose) { |
||||
|
module.debug.apply(this, arguments); |
||||
|
} |
||||
|
}, |
||||
|
debug: function() { |
||||
|
var |
||||
|
output = [], |
||||
|
message = settings.moduleName + ': ' + arguments[0], |
||||
|
variables = [].slice.call( arguments, 1 ), |
||||
|
log = console.info || console.log || function(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
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(){} |
||||
|
; |
||||
|
log = Function.prototype.bind.call(log, console); |
||||
|
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(); |
||||
|
} |
||||
|
|
||||
|
return (invokedResponse !== undefined) |
||||
|
? invokedResponse |
||||
|
: this |
||||
|
; |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
// shortcut for tabbed content with no defined navigation
|
||||
|
$.tabNavigation = function(settings) { |
||||
|
$(window).tabNavigation(settings); |
||||
|
}; |
||||
|
|
||||
|
$.fn.tabNavigation.settings = { |
||||
|
|
||||
|
moduleName : 'Tab Module', |
||||
|
verbose : false, |
||||
|
debug : true, |
||||
|
namespace : 'tab', |
||||
|
|
||||
|
// only called first time a tab's content is loaded (when remote source)
|
||||
|
onTabInit : function(tabPath, parameterArray, historyEvent) {}, |
||||
|
// called on every load
|
||||
|
onTabLoad : function(tabPath, parameterArray, historyEvent) {}, |
||||
|
|
||||
|
templates: { |
||||
|
determineTitle: function(tabArray) {} |
||||
|
}, |
||||
|
|
||||
|
history : false, |
||||
|
path : false, |
||||
|
|
||||
|
context : 'body', |
||||
|
|
||||
|
// max depth a tab can be nested
|
||||
|
maxDepth : 25, |
||||
|
// dont load content on first load
|
||||
|
ignoreFirstLoad : true, |
||||
|
// load tab content new every tab click
|
||||
|
alwaysRefresh : false, |
||||
|
// cache the content requests to pull locally
|
||||
|
cache : true, |
||||
|
// settings for api call
|
||||
|
apiSettings : false, |
||||
|
|
||||
|
errors: { |
||||
|
api : 'You attempted to load content without API module', |
||||
|
noContent : 'The tab you specified is missing a content url.', |
||||
|
method : 'The method you called is not defined', |
||||
|
state : 'The state library has not been initialized', |
||||
|
missingTab : 'Missing tab: ', |
||||
|
recursion : 'Max recursive depth reached' |
||||
|
}, |
||||
|
|
||||
|
metadata : { |
||||
|
tab : 'tab', |
||||
|
loaded : 'loaded', |
||||
|
promise: 'promise' |
||||
|
}, |
||||
|
|
||||
|
className : { |
||||
|
loading : 'loading', |
||||
|
active : 'active' |
||||
|
}, |
||||
|
|
||||
|
selector : { |
||||
|
tabs : '.tab' |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
@ -0,0 +1,391 @@ |
|||||
|
/* ****************************** |
||||
|
Module - Video Component |
||||
|
Author: Jack Lukic |
||||
|
Notes: First Commit June 30, 2012 |
||||
|
|
||||
|
This is a video playlist and video embed plugin which helps |
||||
|
provide helpers for adding embed code for vimeo and youtube and |
||||
|
abstracting event handlers for each library |
||||
|
|
||||
|
****************************** */ |
||||
|
|
||||
|
;(function ($, window, document, undefined) { |
||||
|
|
||||
|
$.fn.video = function(parameters) { |
||||
|
|
||||
|
var |
||||
|
settings = $.extend(true, {}, $.fn.video.settings, parameters), |
||||
|
// make arguments available
|
||||
|
moduleArguments = arguments || false, |
||||
|
invokedResponse |
||||
|
; |
||||
|
|
||||
|
$(this) |
||||
|
.each(function() { |
||||
|
var |
||||
|
$module = $(this), |
||||
|
$placeholder = $module.find(settings.selector.placeholder), |
||||
|
$playButton = $module.find(settings.selector.playButton), |
||||
|
$embed = $module.find(settings.selector.embed), |
||||
|
|
||||
|
element = this, |
||||
|
instance = $module.data('module-' + settings.namespace), |
||||
|
methodInvoked = (typeof parameters == 'string'), |
||||
|
|
||||
|
namespace = settings.namespace, |
||||
|
metadata = settings.metadata, |
||||
|
className = settings.className, |
||||
|
|
||||
|
module |
||||
|
; |
||||
|
|
||||
|
module = { |
||||
|
|
||||
|
initialize: function() { |
||||
|
module.debug('Initializing video'); |
||||
|
$placeholder |
||||
|
.off('.video') |
||||
|
.on('click.' + namespace, module.play) |
||||
|
; |
||||
|
$playButton |
||||
|
.off('.video') |
||||
|
.on('click.' + namespace, module.play) |
||||
|
; |
||||
|
$module |
||||
|
.data('module-' + namespace, module) |
||||
|
; |
||||
|
}, |
||||
|
|
||||
|
// sets new video
|
||||
|
change: function(source, flv) { |
||||
|
module.debug('Changing video to ', flv); |
||||
|
$module |
||||
|
.data(metadata.source, source) |
||||
|
.data(metadata.flv, flv) |
||||
|
; |
||||
|
settings.onChange(); |
||||
|
}, |
||||
|
|
||||
|
// clears video embed
|
||||
|
reset: function() { |
||||
|
module.debug('Clearing video embed and showing placeholder'); |
||||
|
$module |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
$embed |
||||
|
.html(' ') |
||||
|
; |
||||
|
$placeholder |
||||
|
.show() |
||||
|
; |
||||
|
settings.onReset(); |
||||
|
}, |
||||
|
|
||||
|
// plays current video
|
||||
|
play: function() { |
||||
|
module.debug('Playing video'); |
||||
|
var |
||||
|
source = $module.data(metadata.source), |
||||
|
flv = $module.data(metadata.flv) |
||||
|
; |
||||
|
$embed |
||||
|
.html( module.generate.html(source, flv) ) |
||||
|
; |
||||
|
$module |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
settings.onPlay(); |
||||
|
}, |
||||
|
|
||||
|
generate: { |
||||
|
// generates iframe html
|
||||
|
html: function(source, flv) { |
||||
|
module.debug('Generating embed html'); |
||||
|
var |
||||
|
width = (settings.width == 'auto') |
||||
|
? $module.width() |
||||
|
: settings.width, |
||||
|
height = (settings.height == 'auto') |
||||
|
? $module.height() |
||||
|
: settings.height, |
||||
|
html |
||||
|
; |
||||
|
if(source == 'vimeo') { |
||||
|
html = '' |
||||
|
+ '<iframe src="http://player.vimeo.com/video/' + flv + '?=' + module.generate.url(source) + '"' |
||||
|
+ ' width="' + width + '" height="' + height + '"' |
||||
|
+ ' frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>' |
||||
|
; |
||||
|
} |
||||
|
else if(source == 'youtube') { |
||||
|
html = '' |
||||
|
+ '<iframe src="http://www.youtube.com/embed/' + flv + '?=' + module.generate.url(source) + '"' |
||||
|
+ ' width="' + width + '" height="' + height + '"' |
||||
|
+ ' frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>' |
||||
|
; |
||||
|
} |
||||
|
return html; |
||||
|
}, |
||||
|
|
||||
|
// generate url parameters
|
||||
|
url: function(source) { |
||||
|
var |
||||
|
api = (settings.api) |
||||
|
? 1 |
||||
|
: 0, |
||||
|
autoplay = (settings.autoplay) |
||||
|
? 1 |
||||
|
: 0, |
||||
|
hd = (settings.hd) |
||||
|
? 1 |
||||
|
: 0, |
||||
|
showUI = (settings.showUI) |
||||
|
? 1 |
||||
|
: 0, |
||||
|
// opposite used for some params
|
||||
|
hideUI = !(settings.showUI) |
||||
|
? 1 |
||||
|
: 0, |
||||
|
url = '' |
||||
|
; |
||||
|
if(source == 'vimeo') { |
||||
|
url = '' |
||||
|
+ 'api=' + api |
||||
|
+ '&title=' + showUI |
||||
|
+ '&byline=' + showUI |
||||
|
+ '&portrait=' + showUI |
||||
|
+ '&autoplay=' + autoplay |
||||
|
; |
||||
|
if(settings.color) { |
||||
|
url += '&color=' + settings.color; |
||||
|
} |
||||
|
} |
||||
|
else if(source == 'youtube') { |
||||
|
url = '' |
||||
|
+ 'enablejsapi=' + api |
||||
|
+ '&autoplay=' + autoplay |
||||
|
+ '&autohide=' + hideUI |
||||
|
+ '&hq=' + hd |
||||
|
+ '&modestbranding=1' |
||||
|
; |
||||
|
if(settings.color) { |
||||
|
url += '&color=' + settings.color; |
||||
|
} |
||||
|
} |
||||
|
return url; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* standard module */ |
||||
|
debug: function(message, variableName) { |
||||
|
if(settings.debug) { |
||||
|
if(variableName !== undefined) { |
||||
|
console.info(settings.moduleName + ': ' + message, variableName); |
||||
|
} |
||||
|
else { |
||||
|
console.info(settings.moduleName + ': ' + message); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
error: function(errorMessage) { |
||||
|
console.warn(settings.moduleName + ': ' + errorMessage); |
||||
|
}, |
||||
|
invoke: function(methodName, context, methodArguments) { |
||||
|
var |
||||
|
method |
||||
|
; |
||||
|
methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 ); |
||||
|
if(typeof methodName == 'string' && instance !== undefined) { |
||||
|
methodName = methodName.split('.'); |
||||
|
$.each(methodName, function(index, name) { |
||||
|
if( $.isPlainObject( instance[name] ) ) { |
||||
|
instance = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
else if( $.isFunction( instance[name] ) ) { |
||||
|
method = instance[name]; |
||||
|
return true; |
||||
|
} |
||||
|
module.error(settings.errors.method); |
||||
|
return false; |
||||
|
}); |
||||
|
} |
||||
|
if ( $.isFunction( method ) ) { |
||||
|
return method.apply(context, methodArguments); |
||||
|
} |
||||
|
// return retrieved variable or chain
|
||||
|
return method; |
||||
|
} |
||||
|
}; |
||||
|
// check for invoking internal method
|
||||
|
if(methodInvoked) { |
||||
|
invokedResponse = module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) ); |
||||
|
} |
||||
|
// otherwise initialize
|
||||
|
else { |
||||
|
if(instance) { |
||||
|
module.destroy(); |
||||
|
} |
||||
|
module.initialize(); |
||||
|
} |
||||
|
|
||||
|
}) |
||||
|
; |
||||
|
// chain or return queried method
|
||||
|
return (invokedResponse !== undefined) |
||||
|
? invokedResponse |
||||
|
: this |
||||
|
; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
$.fn.videoPlaylist = function(video, parameters) { |
||||
|
var |
||||
|
$allModules = $(this), |
||||
|
$video = $(video), |
||||
|
$iframe = $video.find('.embed iframe'), |
||||
|
|
||||
|
settings = $.extend({}, $.fn.videoPlaylist.settings, parameters, true) |
||||
|
; |
||||
|
$allModules |
||||
|
.each(function() { |
||||
|
var |
||||
|
$element = $(this), |
||||
|
|
||||
|
metadata = settings.metadata, |
||||
|
namespace = settings.namespace, |
||||
|
className = settings.className, |
||||
|
|
||||
|
module = { |
||||
|
initialize: function() { |
||||
|
$element |
||||
|
.on('click.' + namespace , module.changeVideo) |
||||
|
; |
||||
|
}, |
||||
|
changeVideo: function() { |
||||
|
var |
||||
|
flv = $element.data(metadata.flv) || false, |
||||
|
source = $element.data(metadata.source) || false, |
||||
|
placeholder = $element.data(metadata.placeholder) || false |
||||
|
; |
||||
|
if(flv && source) { |
||||
|
$video |
||||
|
.data(metadata.source, source) |
||||
|
.data(metadata.flv, flv) |
||||
|
; |
||||
|
if(settings.showPlaceholder) { |
||||
|
$video |
||||
|
.removeClass(className.active) |
||||
|
.find($.fn.video.selector.placeholder) |
||||
|
.attr('src', placeholder) |
||||
|
; |
||||
|
} |
||||
|
else { |
||||
|
try { |
||||
|
$video |
||||
|
.video('play') |
||||
|
; |
||||
|
} |
||||
|
catch(error) { |
||||
|
console.warn('Video Playlist Module: ' + settings.error.init); |
||||
|
} |
||||
|
} |
||||
|
$allModules |
||||
|
.removeClass(className.active) |
||||
|
; |
||||
|
$element |
||||
|
.addClass(className.active) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
; |
||||
|
module.initialize(); |
||||
|
}) |
||||
|
; |
||||
|
|
||||
|
if(settings.playFirst) { |
||||
|
$allModules |
||||
|
.eq(0) |
||||
|
.trigger('click') |
||||
|
; |
||||
|
// we all like a good hack
|
||||
|
if($iframe.size() > 0) { |
||||
|
$iframe |
||||
|
.attr('src', $iframe.attr('src').replace('autoplay=1', 'autoplay=0') ) |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
$.fn.video.settings = { |
||||
|
|
||||
|
moduleName : 'Video', |
||||
|
namespace : 'video', |
||||
|
debug : false, |
||||
|
|
||||
|
metadata : { |
||||
|
source : 'source', |
||||
|
flv : 'flv' |
||||
|
}, |
||||
|
|
||||
|
onPlay : function(){}, |
||||
|
onReset : function(){}, |
||||
|
onChange : function(){}, |
||||
|
|
||||
|
// callbacks not coded yet (needs to use jsapi)
|
||||
|
play : function() {}, |
||||
|
pause : function() {}, |
||||
|
stop : function() {}, |
||||
|
|
||||
|
width : 'auto', |
||||
|
height : 'auto', |
||||
|
|
||||
|
autoplay : false, |
||||
|
color : '#442359', |
||||
|
hd : true, |
||||
|
showUI : false, |
||||
|
api : true, |
||||
|
|
||||
|
errors : { |
||||
|
method : 'The method you called is not defined' |
||||
|
}, |
||||
|
|
||||
|
className : { |
||||
|
active : 'active' |
||||
|
}, |
||||
|
|
||||
|
selector : { |
||||
|
embed : '.embed', |
||||
|
placeholder : '.placeholder', |
||||
|
playButton : '.play' |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
$.fn.videoPlaylist.settings = { |
||||
|
moduleName : 'Video Playlist', |
||||
|
namespace : 'videoPlaylist', |
||||
|
|
||||
|
source : 'vimeo', |
||||
|
showPlaceholder : false, |
||||
|
playFirst : true, |
||||
|
|
||||
|
metadata: { |
||||
|
flv : 'flv', |
||||
|
source : 'source', |
||||
|
placeholder : 'placeholder' |
||||
|
}, |
||||
|
|
||||
|
errors: { |
||||
|
init : 'The video player you specified was not yet initialized' |
||||
|
}, |
||||
|
|
||||
|
className : { |
||||
|
active : 'active' |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
})( jQuery, window , document ); |
Loading…
Reference in new issue