/* * Snap.js * * Copyright 2013, Jacob Kelley - http://jakiestfu.com/ * Released under the MIT Licence * http://opensource.org/licenses/MIT * * Github: http://github.com/jakiestfu/Snap.js/ * Version: 1.9.2 */ /*jslint browser: true*/ /*global define, module, ender*/ (function(win, doc) { 'use strict'; var Snap = Snap || function(userOpts) { var settings = { element: null, dragger: null, disable: 'none', addBodyClasses: true, hyperextensible: true, resistance: 0.5, flickThreshold: 50, transitionSpeed: 0.3, easing: 'ease', maxPosition: 266, minPosition: -266, tapToClose: true, touchToDrag: true, slideIntent: 40, // degrees minDragDistance: 5 }, cache = { simpleStates: { opening: null, towards: null, hyperExtending: null, halfway: null, flick: null, translation: { absolute: 0, relative: 0, sinceDirectionChange: 0, percentage: 0 } } }, eventList = {}, utils = { hasTouch: (doc.ontouchstart === null), eventType: function(action) { var eventTypes = { down: (utils.hasTouch ? 'touchstart' : 'mousedown'), move: (utils.hasTouch ? 'touchmove' : 'mousemove'), up: (utils.hasTouch ? 'touchend' : 'mouseup'), out: (utils.hasTouch ? 'touchcancel' : 'mouseout') }; return eventTypes[action]; }, page: function(t, e){ return (utils.hasTouch && e.touches.length && e.touches[0]) ? e.touches[0]['page'+t] : e['page'+t]; }, klass: { has: function(el, name){ return (el.className).indexOf(name) !== -1; }, add: function(el, name){ if(!utils.klass.has(el, name) && settings.addBodyClasses){ el.className += " "+name; } }, remove: function(el, name){ if(settings.addBodyClasses){ el.className = (el.className).replace(name, "").replace(/^\s+|\s+$/g, ''); } } }, dispatchEvent: function(type) { if (typeof eventList[type] === 'function') { return eventList[type].call(); } }, vendor: function(){ var tmp = doc.createElement("div"), prefixes = 'webkit Moz O ms'.split(' '), i; for (i in prefixes) { if (typeof tmp.style[prefixes[i] + 'Transition'] !== 'undefined') { return prefixes[i]; } } }, transitionCallback: function(){ return (cache.vendor==='Moz' || cache.vendor==='ms') ? 'transitionend' : cache.vendor+'TransitionEnd'; }, canTransform: function(){ return typeof settings.element.style[cache.vendor+'Transform'] !== 'undefined'; }, deepExtend: function(destination, source) { var property; for (property in source) { if (source[property] && source[property].constructor && source[property].constructor === Object) { destination[property] = destination[property] || {}; utils.deepExtend(destination[property], source[property]); } else { destination[property] = source[property]; } } return destination; }, angleOfDrag: function(x, y) { var degrees, theta; // Calc Theta theta = Math.atan2(-(cache.startDragY - y), (cache.startDragX - x)); if (theta < 0) { theta += 2 * Math.PI; } // Calc Degrees degrees = Math.floor(theta * (180 / Math.PI) - 180); if (degrees < 0 && degrees > -180) { degrees = 360 - Math.abs(degrees); } return Math.abs(degrees); }, events: { addEvent: function addEvent(element, eventName, func) { if (element.addEventListener) { return element.addEventListener(eventName, func, false); } else if (element.attachEvent) { return element.attachEvent("on" + eventName, func); } }, removeEvent: function addEvent(element, eventName, func) { if (element.addEventListener) { return element.removeEventListener(eventName, func, false); } else if (element.attachEvent) { return element.detachEvent("on" + eventName, func); } }, prevent: function(e) { if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } } }, parentUntil: function(el, attr) { var isStr = typeof attr === 'string'; while (el.parentNode) { if (isStr && el.getAttribute && el.getAttribute(attr)){ return el; } else if(!isStr && el === attr){ return el; } el = el.parentNode; } return null; } }, action = { translate: { get: { matrix: function(index) { if( !utils.canTransform() ){ return parseInt(settings.element.style.left, 10); } else { var matrix = win.getComputedStyle(settings.element)[cache.vendor+'Transform'].match(/\((.*)\)/), ieOffset = 8; if (matrix) { matrix = matrix[1].split(','); if(matrix.length===16){ index+=ieOffset; } return parseInt(matrix[index], 10); } return 0; } } }, easeCallback: function(){ settings.element.style[cache.vendor+'Transition'] = ''; cache.translation = action.translate.get.matrix(4); cache.easing = false; clearInterval(cache.animatingInterval); if(cache.easingTo===0){ utils.klass.remove(doc.body, 'paneljs-right'); utils.klass.remove(doc.body, 'paneljs-left'); } utils.dispatchEvent('animated'); utils.events.removeEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback); }, easeTo: function(n) { if( !utils.canTransform() ){ cache.translation = n; action.translate.x(n); } else { cache.easing = true; cache.easingTo = n; settings.element.style[cache.vendor+'Transition'] = 'all ' + settings.transitionSpeed + 's ' + settings.easing; cache.animatingInterval = setInterval(function() { utils.dispatchEvent('animating'); }, 1); utils.events.addEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback); action.translate.x(n); } if(n===0){ settings.element.style[cache.vendor+'Transform'] = ''; } }, x: function(n) { if( (settings.disable==='left' && n>0) || (settings.disable==='right' && n<0) ){ return; } if( !settings.hyperextensible ){ if( n===settings.maxPosition || n>settings.maxPosition ){ n=settings.maxPosition; } else if( n===settings.minPosition || n 0, translateTo = whileDragX, diff; // Shown no intent already if((cache.intentChecked && !cache.hasIntent)){ return; } if(settings.addBodyClasses){ if((absoluteTranslation)>0){ utils.klass.add(doc.body, 'paneljs-left'); utils.klass.remove(doc.body, 'paneljs-right'); } else if((absoluteTranslation)<0){ utils.klass.add(doc.body, 'paneljs-right'); utils.klass.remove(doc.body, 'paneljs-left'); } } if (cache.hasIntent === false || cache.hasIntent === null) { var deg = utils.angleOfDrag(thePageX, thePageY), inRightRange = (deg >= 0 && deg <= settings.slideIntent) || (deg <= 360 && deg > (360 - settings.slideIntent)), inLeftRange = (deg >= 180 && deg <= (180 + settings.slideIntent)) || (deg <= 180 && deg >= (180 - settings.slideIntent)); if (!inLeftRange && !inRightRange) { cache.hasIntent = false; } else { cache.hasIntent = true; } cache.intentChecked = true; } if ( (settings.minDragDistance>=Math.abs(thePageX-cache.startDragX)) || // Has user met minimum drag distance? (cache.hasIntent === false) ) { return; } utils.events.prevent(e); utils.dispatchEvent('drag'); cache.dragWatchers.current = thePageX; // Determine which direction we are going if (cache.dragWatchers.last > thePageX) { if (cache.dragWatchers.state !== 'left') { cache.dragWatchers.state = 'left'; cache.dragWatchers.hold = thePageX; } cache.dragWatchers.last = thePageX; } else if (cache.dragWatchers.last < thePageX) { if (cache.dragWatchers.state !== 'right') { cache.dragWatchers.state = 'right'; cache.dragWatchers.hold = thePageX; } cache.dragWatchers.last = thePageX; } if (openingLeft) { // Pulling too far to the right if (settings.maxPosition < absoluteTranslation) { diff = (absoluteTranslation - settings.maxPosition) * settings.resistance; translateTo = whileDragX - diff; } cache.simpleStates = { opening: 'left', towards: cache.dragWatchers.state, hyperExtending: settings.maxPosition < absoluteTranslation, halfway: absoluteTranslation > (settings.maxPosition / 2), flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold, translation: { absolute: absoluteTranslation, relative: whileDragX, sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold), percentage: (absoluteTranslation/settings.maxPosition)*100 } }; } else { // Pulling too far to the left if (settings.minPosition > absoluteTranslation) { diff = (absoluteTranslation - settings.minPosition) * settings.resistance; translateTo = whileDragX - diff; } cache.simpleStates = { opening: 'right', towards: cache.dragWatchers.state, hyperExtending: settings.minPosition > absoluteTranslation, halfway: absoluteTranslation < (settings.minPosition / 2), flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold, translation: { absolute: absoluteTranslation, relative: whileDragX, sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold), percentage: (absoluteTranslation/settings.minPosition)*100 } }; } action.translate.x(translateTo + translated); } }, endDrag: function(e) { if (cache.isDragging) { utils.dispatchEvent('end'); var translated = action.translate.get.matrix(4); // Tap Close if (cache.dragWatchers.current === 0 && translated !== 0 && settings.tapToClose) { utils.dispatchEvent('close'); utils.events.prevent(e); action.translate.easeTo(0); cache.isDragging = false; cache.startDragX = 0; return; } // Revealing Left if (cache.simpleStates.opening === 'left') { // Halfway, Flicking, or Too Far Out if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) { if (cache.simpleStates.flick && cache.simpleStates.towards === 'left') { // Flicking Closed action.translate.easeTo(0); } else if ( (cache.simpleStates.flick && cache.simpleStates.towards === 'right') || // Flicking Open OR (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending ) { action.translate.easeTo(settings.maxPosition); // Open Left } } else { action.translate.easeTo(0); // Close Left } // Revealing Right } else if (cache.simpleStates.opening === 'right') { // Halfway, Flicking, or Too Far Out if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) { if (cache.simpleStates.flick && cache.simpleStates.towards === 'right') { // Flicking Closed action.translate.easeTo(0); } else if ( (cache.simpleStates.flick && cache.simpleStates.towards === 'left') || // Flicking Open OR (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending ) { action.translate.easeTo(settings.minPosition); // Open Right } } else { action.translate.easeTo(0); // Close Right } } cache.isDragging = false; cache.startDragX = utils.page('X', e); } } } }, init = function(opts) { if (opts.element) { utils.deepExtend(settings, opts); cache.vendor = utils.vendor(); action.drag.listen(); } }; /* * Public */ this.open = function(side) { utils.dispatchEvent('open'); utils.klass.remove(doc.body, 'paneljs-expand-left'); utils.klass.remove(doc.body, 'paneljs-expand-right'); if (side === 'left') { cache.simpleStates.opening = 'left'; cache.simpleStates.towards = 'right'; utils.klass.add(doc.body, 'paneljs-left'); utils.klass.remove(doc.body, 'paneljs-right'); action.translate.easeTo(settings.maxPosition); } else if (side === 'right') { cache.simpleStates.opening = 'right'; cache.simpleStates.towards = 'left'; utils.klass.remove(doc.body, 'paneljs-left'); utils.klass.add(doc.body, 'paneljs-right'); action.translate.easeTo(settings.minPosition); } }; this.close = function() { utils.dispatchEvent('close'); action.translate.easeTo(0); }; this.expand = function(side){ var to = win.innerWidth || doc.documentElement.clientWidth; if(side==='left'){ utils.dispatchEvent('expandLeft'); utils.klass.add(doc.body, 'paneljs-expand-left'); utils.klass.remove(doc.body, 'paneljs-expand-right'); } else { utils.dispatchEvent('expandRight'); utils.klass.add(doc.body, 'paneljs-expand-right'); utils.klass.remove(doc.body, 'paneljs-expand-left'); to *= -1; } action.translate.easeTo(to); }; this.on = function(evt, fn) { eventList[evt] = fn; return this; }; this.off = function(evt) { if (eventList[evt]) { eventList[evt] = false; } }; this.enable = function() { utils.dispatchEvent('enable'); action.drag.listen(); }; this.disable = function() { utils.dispatchEvent('disable'); action.drag.stopListening(); }; this.settings = function(opts){ utils.deepExtend(settings, opts); }; this.state = function() { var state, fromLeft = action.translate.get.matrix(4); if (fromLeft === settings.maxPosition) { state = 'left'; } else if (fromLeft === settings.minPosition) { state = 'right'; } else { state = 'closed'; } return { state: state, info: cache.simpleStates }; }; init(userOpts); }; if ((typeof module !== 'undefined') && module.exports) { module.exports = Snap; } if (typeof ender === 'undefined') { this.Snap = Snap; } if ((typeof define === "function") && define.amd) { define("snap", [], function() { return Snap; }); } }).call(this, window, document); // Generated by CoffeeScript 1.6.3 (function($, window) { "use strict"; var Panel; Panel = (function() { Panel.DEFAULTS = { element: null, dragger: null, disable: 'right', addBodyClasses: true, hyperextensible: true, resistance: 0.5, flickThreshold: 50, transitionSpeed: 0.3, easing: 'ease', maxPosition: 266, minPosition: -266, tapToClose: true, touchToDrag: false, slideIntent: 40, minDragDistance: 5 }; function Panel(el, options) { this.options = $.extend(options, { element: el }); this.menu = $($('[data-toggle="panel"]').data('target')); this.append_menu_to_panel(); this.snapper = new Snap(this.options); } Panel.prototype.apply_ios_devices_fix = function() { if (navigator.userAgent.match(/(iPad|iPhone|iPod)/g)) { return $('.panel-content').css({ 'overflow': 'visible' }); } }; Panel.prototype.append_menu_to_panel = function() { return $('.panel-left').html(this.menu.html()); }; Panel.prototype.toggle = function() { $('.panel').css('display', 'block'); if (this.snapper.state().state === "left") { return this.snapper.close(); } else { return this.snapper.open('left'); } }; return Panel; })(); $.fn.panel = function(option) { return this.each(function() { var $this, data, options; $this = $(this); data = $this.data('Panel'); options = $.extend({}, Panel.DEFAULTS, $this.data(), typeof option === 'object' && option); if (!data) { $this.data('Panel', (data = new Panel(this, options))); } if (typeof option === 'string') { return data[option](); } }); }; $(document).on('click', '[data-toggle="panel"]', function(e) { e.preventDefault(); return $('.panel-content').panel('toggle'); }); return $(document).ready(function() { return $('.panel-content').panel('apply_ios_devices_fix'); }); })(window.jQuery, window); /** * Toolbar.js * * @fileoverview jQuery plugin that creates tooltip style toolbars. * @link http://paulkinzett.github.com/toolbar/ * @author Paul Kinzett (http://kinzett.co.nz/) * @version 1.0.4 * @requires jQuery 1.7+ * * @license jQuery Toolbar Plugin v1.0.4 * http://paulkinzett.github.com/toolbar/ * Copyright 2013 Paul Kinzett (http://kinzett.co.nz/) * Released under the MIT license. * */ if ( typeof Object.create !== 'function' ) { Object.create = function( obj ) { function F() {} F.prototype = obj; return new F(); }; } (function( $, window, document, undefined ) { var ToolBar = { init: function( options, elem ) { var self = this; self.elem = elem; self.$elem = $( elem ); self.options = $.extend( {}, $.fn.toolbar.options, options ); self.toolbar = $('
') .addClass('tool-'+self.options.position) .addClass('tool-rounded') .append('
') .append('
') .appendTo('body') .css('opacity', 0) .hide(); self.toolbar_arrow = self.toolbar.find('.arrow'); self.initializeToolbar(); }, initializeToolbar: function() { var self = this; self.populateContent(); self.setTrigger(); self.toolbarWidth = self.toolbar.width(); }, setTrigger: function() { var self = this; self.$elem.on('click', function(event) { event.preventDefault(); if(self.$elem.hasClass('pressed')) { self.hide(); } else { self.show(); } }); if (self.options.hideOnClick) { $('html').on("click.toolbar", function ( event ) { if (event.target != self.elem && self.$elem.has(event.target).length === 0 && self.toolbar.has(event.target).length === 0 && self.toolbar.is(":visible")) { self.hide(); } }); } $(window).resize(function( event ) { event.stopPropagation(); if ( self.toolbar.is(":visible") ) { self.toolbarCss = self.getCoordinates(self.options.position, 20); self.collisionDetection(); self.toolbar.css( self.toolbarCss ); self.toolbar_arrow.css( self.arrowCss ); } }); }, populateContent: function() { var self = this; var location = self.toolbar.find('.tool-items'); var content = $(self.options.content).clone( true ).find('a').addClass('tool-item gradient'); location.html(content); location.find('.tool-item').on('click', function(event) { event.preventDefault(); self.$elem.trigger('toolbarItemClick', this); }); }, calculatePosition: function() { var self = this; self.arrowCss = {}; self.toolbarCss = self.getCoordinates(self.options.position, 0); self.toolbarCss.position = 'absolute'; self.toolbarCss.zIndex = self.options.zIndex; self.collisionDetection(); self.toolbar.css(self.toolbarCss); self.toolbar_arrow.css(self.arrowCss); }, getCoordinates: function( position, adjustment ) { var self = this; self.coordinates = self.$elem.offset(); if (self.options.adjustment && self.options.adjustment[self.options.position]) { adjustment = self.options.adjustment[self.options.position]; } switch(self.options.position) { case 'top': return { left: self.coordinates.left-(self.toolbar.width()/2)+(self.$elem.outerWidth()/2), top: self.coordinates.top-self.$elem.height()-adjustment, right: 'auto' }; case 'left': return { left: self.coordinates.left-(self.toolbar.width()/2)-(self.$elem.width()/2)-adjustment, top: self.coordinates.top-(self.toolbar.height()/2)+(self.$elem.outerHeight()/2), right: 'auto' }; case 'right': return { left: self.coordinates.left+(self.toolbar.width()/2)+(self.$elem.width()/3)+adjustment, top: self.coordinates.top-(self.toolbar.height()/2)+(self.$elem.outerHeight()/2), right: 'auto' }; case 'bottom': return { left: self.coordinates.left-(self.toolbar.width()/2)+(self.$elem.outerWidth()/2), top: self.coordinates.top+self.$elem.height()+adjustment, right: 'auto' }; } }, collisionDetection: function() { var self = this; var edgeOffset = 20; if(self.options.position == 'top' || self.options.position == 'bottom') { self.arrowCss = {left: '50%', right: '50%'}; if( self.toolbarCss.left < edgeOffset ) { self.toolbarCss.left = edgeOffset; self.arrowCss.left = self.$elem.offset().left + self.$elem.width()/2-(edgeOffset); } else if(($(window).width() - (self.toolbarCss.left + self.toolbarWidth)) < edgeOffset) { self.toolbarCss.right = edgeOffset; self.toolbarCss.left = 'auto'; self.arrowCss.left = 'auto'; self.arrowCss.right = ($(window).width()-self.$elem.offset().left)-(self.$elem.width()/2)-(edgeOffset)-5; } } }, show: function() { var self = this; var animation = {'opacity': 1}; self.$elem.addClass('pressed'); self.calculatePosition(); switch(self.options.position) { case 'top': animation.top = '-=20'; break; case 'left': animation.left = '-=20'; break; case 'right': animation.left = '+=20'; break; case 'bottom': animation.top = '+=20'; break; } self.toolbar.show().animate(animation, 200 ); self.$elem.trigger('toolbarShown'); }, hide: function() { var self = this; var animation = {'opacity': 0}; self.$elem.removeClass('pressed'); switch(self.options.position) { case 'top': animation.top = '+=20'; break; case 'left': animation.left = '+=20'; break; case 'right': animation.left = '-=20'; break; case 'bottom': animation.top = '-=20'; break; } self.toolbar.animate(animation, 200, function() { self.toolbar.hide(); }); self.$elem.trigger('toolbarHidden'); }, getToolbarElement: function () { return this.toolbar.find('.tool-items'); } }; $.fn.toolbar = function( options ) { if ($.isPlainObject( options )) { return this.each(function() { var toolbarObj = Object.create( ToolBar ); toolbarObj.init( options, this ); $(this).data('toolbarObj', toolbarObj); }); } else if ( typeof options === 'string' && options.indexOf('_') !== 0 ) { var toolbarObj = $(this).data('toolbarObj'); var method = toolbarObj[options]; return method.apply(toolbarObj, $.makeArray(arguments).slice(1)); } }; $.fn.toolbar.options = { content: '#myContent', position: 'top', hideOnClick: false, zIndex: 120 }; }) ( jQuery, window, document ); // Generated by CoffeeScript 1.6.3 $(document).ready(function() { return $('[data-furatto="toolbar"]').each(function() { return $(this).toolbar({ content: $(this).data('content'), position: $(this).data('position') || 'top', hideOnClick: true }); }); }); /* Rainbow v1.2 rainbowco.de | included languages: generic, shell, javascript, html, css */ window.Rainbow=function(){function q(a){var b,c=a.getAttribute&&a.getAttribute("data-language")||0;if(!c){a=a.attributes;for(b=0;b=f[d][c])delete f[d][c],delete j[d][c];if(a>=c&&ac&&b'+b+""}function s(a,b,c,i){var e=a.exec(c);if(e){++t;!b.name&&"string"==typeof b.matches[0]&&(b.name=b.matches[0],delete b.matches[0]);var k=e[0],g=e.index,u=e[0].length+g,h=function(){function e(){s(a,b,c,i)}t%100>0?e():setTimeout(e,0)};if(C(g,u))h();else{var m=v(b.matches),l=function(a,c,i){if(a>=c.length)i(k);else{var d=e[c[a]];if(d){var g=b.matches[c[a]],f=g.language,h=g.name&&g.matches? g.matches:g,j=function(b,d,g){var f;f=0;var h;for(h=1;h/g,">").replace(/&(?![\w\#]+;)/g,"&"),b,c)}function o(a,b,c){if(b
' , trigger: 'hover focus' , title: '' , delay: 0 , html: false , container: false } /* TOOLTIP NO CONFLICT * =================== */ $.fn.tooltip.noConflict = function () { $.fn.tooltip = old return this } }(window.jQuery); /*! * pickadate.js v3.1.1, 2013/06/28 * By Amsul, http://amsul.ca * Hosted on http://amsul.github.io/pickadate.js * Licensed under MIT */ /*jshint debug: true, devel: true, browser: true, asi: true, unused: true, boss: true, eqnull: true */ // Create a global scope. window.Picker = (function( $, $document, undefined ) { /** * The picker constructor that creates a blank picker. */ function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) { // If there’s no element, return the picker constructor. if ( !ELEMENT ) return PickerConstructor var // The state of the picker. STATE = { id: Math.abs( ~~( Math.random() * 1e9 ) ) }, // Merge the defaults and options passed. SETTINGS = COMPONENT ? $.extend( true, {}, COMPONENT.defaults, OPTIONS ) : OPTIONS || {}, // Merge the default classes with the settings classes. CLASSES = $.extend( {}, PickerConstructor.klasses(), SETTINGS.klass ), // The element node wrapper into a jQuery object. $ELEMENT = $( ELEMENT ), // Pseudo picker constructor. PickerInstance = function() { return this.start() }, // The picker prototype. P = PickerInstance.prototype = { constructor: PickerInstance, $node: $ELEMENT, /** * Initialize everything */ start: function() { // If it’s already started, do nothing. if ( STATE && STATE.start ) return P // Update the picker states. STATE.methods = {} STATE.start = true STATE.open = false STATE.type = ELEMENT.type // Confirm focus state, save original type, convert into text input // to remove UA stylings, and set as readonly to prevent keyboard popup. ELEMENT.autofocus = ELEMENT == document.activeElement ELEMENT.type = 'text' ELEMENT.readOnly = true // Create a new picker component with the settings. P.component = new COMPONENT( P, SETTINGS ) // Create the picker root with a new wrapped holder and bind the events. P.$root = $( PickerConstructor._.node( 'div', createWrappedComponent(), CLASSES.picker ) ).on({ // When something within the root is focused, stop from bubbling // to the doc and remove the “focused” state from the root. focusin: function( event ) { P.$root.removeClass( CLASSES.focused ) event.stopPropagation() }, // If the event is not on the root holder, stop it from bubbling to the doc. mousedown: function( event ) { if ( event.target != P.$root.children()[ 0 ] ) { event.stopPropagation() } }, // When something within the root holder is clicked, handle the various event. click: function( event ) { var target = event.target, $target = target.attributes.length ? $( target ) : $( target ).closest( '[data-pick]' ), targetData = $target.data() // If the event is not on the root holder itself, handle the clicks within. if ( target != P.$root.children()[ 0 ] ) { // Stop it from propagating to the doc. event.stopPropagation() // If nothing inside is actively focused, re-focus the element. if ( !P.$root.find( document.activeElement ).length ) { ELEMENT.focus() } // If something is superficially changed, update the `highlight` based on the `nav`. if ( targetData.nav && !$target.hasClass( CLASSES.navDisabled ) ) { P.set( 'highlight', P.component.item.highlight, { nav: targetData.nav } ) } // If something is picked, set `select` then close with focus. else if ( PickerConstructor._.isInteger( targetData.pick ) && !$target.hasClass( CLASSES.disabled ) ) { P.set( 'select', targetData.pick ).close( true ) } // If a “clear” button is pressed, empty the values and close with focus. else if ( targetData.clear ) { P.clear().close( true ) } } } }) //P.$root // If there’s a format for the hidden input element, create the element // using the name of the original input plus suffix. Otherwise set it to null. // If the element has a value, use either the `data-value` or `value`. P._hidden = SETTINGS.formatSubmit ? $( '' )[ 0 ] : undefined // Add the class and bind the events on the element. $ELEMENT.addClass( CLASSES.input ). // On focus/click, open the picker and adjust the root “focused” state. on( 'focus.P' + STATE.id + ' click.P' + STATE.id, focusToOpen ). // If the value changes, update the hidden input with the correct format. on( 'change.P' + STATE.id, function() { if ( P._hidden ) { P._hidden.value = ELEMENT.value ? PickerConstructor._.trigger( P.component.formats.toString, P.component, [ SETTINGS.formatSubmit, P.component.item.select ] ) : '' } }). // Handle keyboard event based on the picker being opened or not. on( 'keydown.P' + STATE.id, function( event ) { var keycode = event.keyCode, // Check if one of the delete keys was pressed. isKeycodeDelete = /^(8|46)$/.test( keycode ) // For some reason IE clears the input value on “escape”. if ( keycode == 27 ) { P.close() return false } // Check if `space` or `delete` was pressed or the picker is closed with a key movement. if ( keycode == 32 || isKeycodeDelete || !STATE.open && P.component.key[ keycode ] ) { // Prevent it from moving the page and bubbling to doc. event.preventDefault() event.stopPropagation() // If `delete` was pressed, clear the values and close the picker. // Otherwise open the picker. if ( isKeycodeDelete ) { P.clear().close() } else { P.open() } } }). // If there’s a `data-value`, update the value of the element. val( $ELEMENT.data( 'value' ) ? PickerConstructor._.trigger( P.component.formats.toString, P.component, [ SETTINGS.format, P.component.item.select ] ) : ELEMENT.value ). // Insert the root and hidden input after the element. after( P.$root, P._hidden ). // Store the picker data by component name. data( NAME, P ) // Bind the default component and settings events. P.on({ start: P.component.onStart, render: P.component.onRender, stop: P.component.onStop, open: P.component.onOpen, close: P.component.onClose, set: P.component.onSet }).on({ start: SETTINGS.onStart, render: SETTINGS.onRender, stop: SETTINGS.onStop, open: SETTINGS.onOpen, close: SETTINGS.onClose, set: SETTINGS.onSet }) // If the element has autofocus, open the picker. if ( ELEMENT.autofocus ) { P.open() } // Trigger queued the “start” and “render” events. return P.trigger( 'start' ).trigger( 'render' ) }, //start /** * Render a new picker within the root */ render: function() { // Insert a new component holder in the root. P.$root.html( createWrappedComponent() ) // Trigger the queued “render” events. return P.trigger( 'render' ) }, //render /** * Destroy everything */ stop: function() { // If it’s already stopped, do nothing. if ( !STATE.start ) return P // Then close the picker. P.close() // Remove the hidden field. if ( P._hidden ) { P._hidden.parentNode.removeChild( P._hidden ) } // Remove the root. P.$root.remove() // Remove the input class, unbind the events, and remove the stored data. $ELEMENT.removeClass( CLASSES.input ).off( '.P' + STATE.id ).removeData( NAME ) // Restore the element state ELEMENT.type = STATE.type ELEMENT.readOnly = false // Trigger the queued “stop” events. P.trigger( 'stop' ) // Reset the picker states. STATE.methods = {} STATE.start = false return P }, //stop /* * Open up the picker */ open: function( dontGiveFocus ) { // If it’s already open, do nothing. if ( STATE.open ) return P // Add the “active” class. $ELEMENT.addClass( CLASSES.active ) // Add the “opened” class to the picker root. P.$root.addClass( CLASSES.opened ) // If we have to give focus, bind the element and doc events. if ( dontGiveFocus !== false ) { // Set it as open. STATE.open = true // Pass focus to the element’s jQuery object. $ELEMENT.focus() // Bind the document events. $document.on( 'click.P' + STATE.id + ' focusin.P' + STATE.id, function( event ) { // If the target of the event is not the element, close the picker picker. // * Don’t worry about clicks or focusins on the root because those don’t bubble up. // Also, for Firefox, a click on an `option` element bubbles up directly // to the doc. So make sure the target wasn't the doc. if ( event.target != ELEMENT && event.target != document ) P.close() }).on( 'keydown.P' + STATE.id, function( event ) { var // Get the keycode. keycode = event.keyCode, // Translate that to a selection change. keycodeToMove = P.component.key[ keycode ], // Grab the target. target = event.target // On escape, close the picker and give focus. if ( keycode == 27 ) { P.close( true ) } // Check if there is a key movement or “enter” keypress on the element. else if ( target == ELEMENT && ( keycodeToMove || keycode == 13 ) ) { // Prevent the default action to stop page movement. event.preventDefault() // Trigger the key movement action. if ( keycodeToMove ) { PickerConstructor._.trigger( P.component.key.go, P, [ keycodeToMove ] ) } // On “enter”, if the highlighted item isn’t disabled, set the value and close. else if ( !P.$root.find( '.' + CLASSES.highlighted ).hasClass( CLASSES.disabled ) ) { P.set( 'select', P.component.item.highlight ).close() } } // If the target is within the root and “enter” is pressed, // prevent the default action and trigger a click on the target instead. else if ( P.$root.find( target ).length && keycode == 13 ) { event.preventDefault() target.click() } }) } // Trigger the queued “open” events. return P.trigger( 'open' ) }, //open /** * Close the picker */ close: function( giveFocus ) { // If we need to give focus, do it before changing states. if ( giveFocus ) { // ....ah yes! It would’ve been incomplete without a crazy workaround for IE :| // The focus is triggered *after* the close has completed - causing it // to open again. So unbind and rebind the event at the next tick. $ELEMENT.off( 'focus.P' + STATE.id ).focus() setTimeout( function() { $ELEMENT.on( 'focus.P' + STATE.id, focusToOpen ) }, 0 ) } // Remove the “active” class. $ELEMENT.removeClass( CLASSES.active ) // Remove the “opened” and “focused” class from the picker root. P.$root.removeClass( CLASSES.opened + ' ' + CLASSES.focused ) // If it’s open, update the state. if ( STATE.open ) { // Set it as closed. STATE.open = false // Unbind the document events. $document.off( '.P' + STATE.id ) } // Trigger the queued “close” events. return P.trigger( 'close' ) }, //close /** * Clear the values */ clear: function() { return P.set( 'clear' ) }, //clear /** * Set something */ set: function( thing, value, options ) { var thingItem, thingValue, thingIsObject = PickerConstructor._.isObject( thing ), thingObject = thingIsObject ? thing : {} if ( thing ) { // If the thing isn’t an object, make it one. if ( !thingIsObject ) { thingObject[ thing ] = value } // Go through the things of items to set. for ( thingItem in thingObject ) { // Grab the value of the thing. thingValue = thingObject[ thingItem ] // First, if the item exists and there’s a value, set it. if ( P.component.item[ thingItem ] ) { P.component.set( thingItem, thingValue, options || {} ) } // Then, check to update the element value and broadcast a change. if ( thingItem == 'select' || thingItem == 'clear' ) { $ELEMENT.val( thingItem == 'clear' ? '' : PickerConstructor._.trigger( P.component.formats.toString, P.component, [ SETTINGS.format, P.component.get( thingItem ) ] ) ).trigger( 'change' ) } } // Render a new picker. P.render() } // Trigger queued “set” events and pass the `thingObject`. return P.trigger( 'set', thingObject ) }, //set /** * Get something */ get: function( thing, format ) { // Make sure there’s something to get. thing = thing || 'value' // If a picker state exists, return that. if ( STATE[ thing ] != null ) { return STATE[ thing ] } // Return the value, if that. if ( thing == 'value' ) { return ELEMENT.value } // Check if a component item exists, return that. if ( P.component.item[ thing ] ) { if ( typeof format == 'string' ) { return PickerConstructor._.trigger( P.component.formats.toString, P.component, [ format, P.component.get( thing ) ] ) } return P.component.get( thing ) } }, //get /** * Bind events on the things. */ on: function( thing, method ) { var thingName, thingMethod, thingIsObject = PickerConstructor._.isObject( thing ), thingObject = thingIsObject ? thing : {} if ( thing ) { // If the thing isn’t an object, make it one. if ( !thingIsObject ) { thingObject[ thing ] = method } // Go through the things to bind to. for ( thingName in thingObject ) { // Grab the method of the thing. thingMethod = thingObject[ thingName ] // Make sure the thing methods collection exists. STATE.methods[ thingName ] = STATE.methods[ thingName ] || [] // Add the method to the relative method collection. STATE.methods[ thingName ].push( thingMethod ) } } return P }, //on /** * Fire off method events. */ trigger: function( name, data ) { var methodList = STATE.methods[ name ] if ( methodList ) { methodList.map( function( method ) { PickerConstructor._.trigger( method, P, [ data ] ) }) } return P } //trigger } //PickerInstance.prototype /** * Wrap the picker holder components together. */ function createWrappedComponent() { // Create a picker wrapper holder return PickerConstructor._.node( 'div', // Create a picker wrapper node PickerConstructor._.node( 'div', // Create a picker frame PickerConstructor._.node( 'div', // Create a picker box node PickerConstructor._.node( 'div', // Create the components nodes. P.component.nodes( STATE.open ), // The picker box class CLASSES.box ), // Picker wrap class CLASSES.wrap ), // Picker frame class CLASSES.frame ), // Picker holder class CLASSES.holder ) //endreturn } //createWrappedComponent // Separated for IE function focusToOpen( event ) { // Stop the event from propagating to the doc. event.stopPropagation() // If it’s a focus event, add the “focused” class to the root. if ( event.type == 'focus' ) P.$root.addClass( CLASSES.focused ) // And then finally open the picker. P.open() } // Return a new picker instance. return new PickerInstance() } //PickerConstructor /** * The default classes and prefix to use for the HTML classes. */ PickerConstructor.klasses = function( prefix ) { prefix = prefix || 'picker' return { picker: prefix, opened: prefix + '--opened', focused: prefix + '--focused', input: prefix + '__input', active: prefix + '__input--active', holder: prefix + '__holder', frame: prefix + '__frame', wrap: prefix + '__wrap', box: prefix + '__box' } } //PickerConstructor.klasses /** * PickerConstructor helper methods. */ PickerConstructor._ = { /** * Create a group of nodes. Expects: * ` { min: {Integer}, max: {Integer}, i: {Integer}, node: {String}, item: {Function} } * ` */ group: function( groupObject ) { var // Scope for the looped object loopObjectScope, // Create the nodes list nodesList = '', // The counter starts from the `min` counter = PickerConstructor._.trigger( groupObject.min, groupObject ) // Loop from the `min` to `max`, incrementing by `i` for ( ; counter <= PickerConstructor._.trigger( groupObject.max, groupObject, [ counter ] ); counter += groupObject.i ) { // Trigger the `item` function within scope of the object loopObjectScope = PickerConstructor._.trigger( groupObject.item, groupObject, [ counter ] ) // Splice the subgroup and create nodes out of the sub nodes nodesList += PickerConstructor._.node( groupObject.node, loopObjectScope[ 0 ], // the node loopObjectScope[ 1 ], // the classes loopObjectScope[ 2 ] // the attributes ) } // Return the list of nodes return nodesList }, //group /** * Create a dom node string */ node: function( wrapper, item, klass, attribute ) { // If the item is false-y, just return an empty string if ( !item ) return '' // If the item is an array, do a join item = Array.isArray( item ) ? item.join( '' ) : item // Check for the class klass = klass ? ' class="' + klass + '"' : '' // Check for any attributes attribute = attribute ? ' ' + attribute : '' // Return the wrapped item return '<' + wrapper + klass + attribute + '>' + item + '' }, //node /** * Lead numbers below 10 with a zero. */ lead: function( number ) { return ( number < 10 ? '0': '' ) + number }, /** * Trigger a function otherwise return the value. */ trigger: function( callback, scope, args ) { return typeof callback == 'function' ? callback.apply( scope, args || [] ) : callback }, /** * If the second character is a digit, length is 2 otherwise 1. */ digits: function( string ) { return ( /\d/ ).test( string[ 1 ] ) ? 2 : 1 }, /** * Tell if something is an object. */ isObject: function( value ) { return {}.toString.call( value ).indexOf( 'Object' ) > -1 }, /** * Tell if something is a date object. */ isDate: function( value ) { return {}.toString.call( value ).indexOf( 'Date' ) > -1 && this.isInteger( value.getDate() ) }, /** * Tell if something is an integer. */ isInteger: function( value ) { return {}.toString.call( value ).indexOf( 'Number' ) > -1 && value % 1 === 0 } } //PickerConstructor._ /** * Extend the picker with a component and defaults. */ PickerConstructor.extend = function( name, Component ) { // Extend jQuery. $.fn[ name ] = function( options, action ) { // Grab the component data. var componentData = this.data( name ) // If the picker is requested, return the data object. if ( options == 'picker' ) { return componentData } // If the component data exists and `options` is a string, carry out the action. if ( componentData && typeof options == 'string' ) { PickerConstructor._.trigger( componentData[ options ], componentData, [ action ] ) return this } // Otherwise go through each matched element and if the component // doesn’t exist, create a new picker using `this` element // and merging the defaults and options with a deep copy. return this.each( function() { var $this = $( this ) if ( !$this.data( name ) ) { new PickerConstructor( this, name, Component, options ) } }) } // Set the defaults. $.fn[ name ].defaults = Component.defaults } //PickerConstructor.extend // Return the picker constructor. return PickerConstructor // Close the global scope. })( jQuery, jQuery( document ) ); /*! * Date picker for pickadate.js v3.1.1 * http://amsul.github.io/pickadate.js/date.htm */ /*jshint debug: true, devel: true, browser: true, asi: true, unused: true, boss: true */ // Create a new scope. (function() { /** * Globals and constants */ var DAYS_IN_WEEK = 7, WEEKS_IN_CALENDAR = 6 /** * The date picker constructor */ function DatePicker( picker, settings ) { var calendar = this, elementValue = picker.$node[ 0 ].value, elementDataValue = picker.$node.data( 'value' ), valueString = elementDataValue || elementValue, formatString = elementDataValue ? settings.formatSubmit : settings.format calendar.settings = settings // The queue of methods that will be used to build item objects. calendar.queue = { min: 'measure create', max: 'measure create', now: 'now create', select: 'parse create validate', highlight: 'navigate create validate', view: 'create validate viewset', disable: 'flipItem', enable: 'flipItem' } // The component's item object. calendar.item = {} calendar.item.disable = ( settings.disable || [] ).slice( 0 ) calendar.item.enable = -(function( collectionDisabled ) { return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1 })( calendar.item.disable ) calendar. set( 'min', settings.min ). set( 'max', settings.max ). set( 'now' ). // Setting the `select` also sets the `highlight` and `view`. set( 'select', // Use the value provided or default to selecting “today”. valueString || calendar.item.now, { // Use the appropriate format. format: formatString, // Set user-provided month data as true when there is a // “mm” or “m” used in the relative format string. data: (function( formatArray ) { return valueString && ( formatArray.indexOf( 'mm' ) > -1 || formatArray.indexOf( 'm' ) > -1 ) })( calendar.formats.toArray( formatString ) ) } ) // The keycode to movement mapping. calendar.key = { 40: 7, // Down 38: -7, // Up 39: 1, // Right 37: -1, // Left go: function( timeChange ) { calendar.set( 'highlight', [ calendar.item.highlight.year, calendar.item.highlight.month, calendar.item.highlight.date + timeChange ], { interval: timeChange } ) this.render() } } // Bind some picker events. picker. on( 'render', function() { picker.$root.find( '.' + settings.klass.selectMonth ).on( 'change', function() { picker.set( 'highlight', [ picker.get( 'view' ).year, this.value, picker.get( 'highlight' ).date ] ) picker.$root.find( '.' + settings.klass.selectMonth ).focus() }) picker.$root.find( '.' + settings.klass.selectYear ).on( 'change', function() { picker.set( 'highlight', [ this.value, picker.get( 'view' ).month, picker.get( 'highlight' ).date ] ) picker.$root.find( '.' + settings.klass.selectYear ).focus() }) }). on( 'open', function() { picker.$root.find( 'button, select' ).attr( 'disabled', false ) }). on( 'close', function() { picker.$root.find( 'button, select' ).attr( 'disabled', true ) }) } //DatePicker /** * Set a datepicker item object. */ DatePicker.prototype.set = function( type, value, options ) { var calendar = this // Go through the queue of methods, and invoke the function. Update this // as the time unit, and set the final resultant as this item type. // * In the case of `enable`, keep the queue but set `disable` instead. // And in the case of `flip`, keep the queue but set `enable` instead. calendar.item[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = calendar.queue[ type ].split( ' ' ).map( function( method ) { return value = calendar[ method ]( type, value, options ) }).pop() // Check if we need to cascade through more updates. if ( type == 'select' ) { calendar.set( 'highlight', calendar.item.select, options ) } else if ( type == 'highlight' ) { calendar.set( 'view', calendar.item.highlight, options ) } else if ( ( type == 'flip' || type == 'min' || type == 'max' || type == 'disable' || type == 'enable' ) && calendar.item.select && calendar.item.highlight ) { calendar. set( 'select', calendar.item.select, options ). set( 'highlight', calendar.item.highlight, options ) } return calendar } //DatePicker.prototype.set /** * Get a datepicker item object. */ DatePicker.prototype.get = function( type ) { return this.item[ type ] } //DatePicker.prototype.get /** * Create a picker date object. */ DatePicker.prototype.create = function( type, value, options ) { var isInfiniteValue, calendar = this // If there’s no value, use the type as the value. value = value === undefined ? type : value // If it’s infinity, update the value. if ( value == -Infinity || value == Infinity ) { isInfiniteValue = value } // If it’s an object, use the native date object. else if ( Picker._.isObject( value ) && Picker._.isInteger( value.pick ) ) { value = value.obj } // If it’s an array, convert it into a date and make sure // that it’s a valid date – otherwise default to today. else if ( Array.isArray( value ) ) { value = new Date( value[ 0 ], value[ 1 ], value[ 2 ] ) value = Picker._.isDate( value ) ? value : calendar.create().obj } // If it’s a number or date object, make a normalized date. else if ( Picker._.isInteger( value ) || Picker._.isDate( value ) ) { value = calendar.normalize( new Date( value ), options ) } // If it’s a literal true or any other case, set it to now. else /*if ( value === true )*/ { value = calendar.now( type, value, options ) } // Return the compiled object. return { year: isInfiniteValue || value.getFullYear(), month: isInfiniteValue || value.getMonth(), date: isInfiniteValue || value.getDate(), day: isInfiniteValue || value.getDay(), obj: isInfiniteValue || value, pick: isInfiniteValue || value.getTime() } } //DatePicker.prototype.create /** * Get the date today. */ DatePicker.prototype.now = function( type, value, options ) { value = new Date() if ( options && options.rel ) { value.setDate( value.getDate() + options.rel ) } return this.normalize( value, options ) } //DatePicker.prototype.now /** * Navigate to next/prev month. */ DatePicker.prototype.navigate = function( type, value, options ) { if ( Picker._.isObject( value ) ) { var targetDateObject = new Date( value.year, value.month + ( options && options.nav ? options.nav : 0 ), 1 ), year = targetDateObject.getFullYear(), month = targetDateObject.getMonth(), date = value.date // Make sure the date is valid and if the month we’re going to doesn’t have enough // days, keep decreasing the date until we reach the month’s last date. while ( Picker._.isDate( targetDateObject ) && new Date( year, month, date ).getMonth() !== month ) { date -= 1 } value = [ year, month, date ] } return value } //DatePicker.prototype.navigate /** * Normalize a date by setting the hours to midnight. */ DatePicker.prototype.normalize = function( value/*, options*/ ) { value.setHours( 0, 0, 0, 0 ) return value } /** * Measure the range of dates. */ DatePicker.prototype.measure = function( type, value/*, options*/ ) { var calendar = this // If it's anything false-y, remove the limits. if ( !value ) { value = type == 'min' ? -Infinity : Infinity } // If it's an integer, get a date relative to today. else if ( Picker._.isInteger( value ) ) { value = calendar.now( type, value, { rel: value } ) } return value } ///DatePicker.prototype.measure /** * Create a viewset object based on navigation. */ DatePicker.prototype.viewset = function( type, dateObject/*, options*/ ) { return this.create([ dateObject.year, dateObject.month, 1 ]) } /** * Validate a date as enabled and shift if needed. */ DatePicker.prototype.validate = function( type, dateObject, options ) { var calendar = this, // Keep a reference to the original date. originalDateObject = dateObject, // Make sure we have an interval. interval = options && options.interval ? options.interval : 1, // Check if the calendar enabled dates are inverted. isInverted = calendar.item.enable === -1, // Check if we have any enabled dates after/before now. hasEnabledBeforeTarget, hasEnabledAfterTarget, // The min & max limits. minLimitObject = calendar.item.min, maxLimitObject = calendar.item.max, // Check if we’ve reached the limit during shifting. reachedMin, reachedMax, // Check if the calendar is inverted and at least one weekday is enabled. hasEnabledWeekdays = isInverted && calendar.item.disable.filter( function( value ) { // If there’s a date, check where it is relative to the target. if ( Array.isArray( value ) ) { var dateTime = calendar.create( value ).pick if ( dateTime < dateObject.pick ) hasEnabledBeforeTarget = true else if ( dateTime > dateObject.pick ) hasEnabledAfterTarget = true } // Return only integers for enabled weekdays. return Picker._.isInteger( value ) }).length // Cases to validate for: // [1] Not inverted and date disabled. // [2] Inverted and some dates enabled. // [3] Out of range. // // Cases to **not** validate for: // • Not inverted and date enabled. // • Inverted and all dates disabled. // • Navigating months. // • ..and anything else. if ( /* 1 */ ( !isInverted && calendar.disabled( dateObject ) ) || /* 2 */ ( isInverted && calendar.disabled( dateObject ) && ( hasEnabledWeekdays || hasEnabledBeforeTarget || hasEnabledAfterTarget ) ) || /* 3 */ ( dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick ) ) { // When inverted, flip the direction if there aren’t any enabled weekdays // and there are no enabled dates in the direction of the interval. if ( isInverted && !hasEnabledWeekdays && ( ( !hasEnabledAfterTarget && interval > 0 ) || ( !hasEnabledBeforeTarget && interval < 0 ) ) ) { interval *= -1 } // Keep looping until we reach an enabled date. while ( calendar.disabled( dateObject ) ) { // If we’ve looped into the next/prev month, return to the original date and flatten the interval. if ( Math.abs( interval ) > 1 && ( dateObject.month < originalDateObject.month || dateObject.month > originalDateObject.month ) ) { dateObject = originalDateObject interval = Math.abs( interval ) / interval } // If we’ve reached the min/max limit, reverse the direction and flatten the interval. if ( dateObject.pick <= minLimitObject.pick ) { reachedMin = true interval = 1 } else if ( dateObject.pick >= maxLimitObject.pick ) { reachedMax = true interval = -1 } // If we’ve reached both limits, just break out of the loop. if ( reachedMin && reachedMax ) { break } // Finally, create the shifted date using the interval and keep looping. dateObject = calendar.create([ dateObject.year, dateObject.month, dateObject.date + interval ]) } } //endif // Return the date object settled on. return dateObject } //DatePicker.prototype.validate /** * Check if an object is disabled. */ DatePicker.prototype.disabled = function( dateObject ) { var calendar = this, // Filter through the disabled dates to check if this is one. isDisabledDate = calendar.item.disable.filter( function( dateToDisable ) { // If the date is a number, match the weekday with 0index and `firstDay` check. if ( Picker._.isInteger( dateToDisable ) ) { return dateObject.day === ( calendar.settings.firstDay ? dateToDisable : dateToDisable - 1 ) % 7 } // If it's an array, create the object and match the exact date. if ( Array.isArray( dateToDisable ) ) { return dateObject.pick === calendar.create( dateToDisable ).pick } }).length // It’s disabled beyond the min/max limits. If within the limits, check the // calendar “enabled” flag is flipped and respectively flip the condition. return dateObject.pick < calendar.item.min.pick || dateObject.pick > calendar.item.max.pick || calendar.item.enable === -1 ? !isDisabledDate : isDisabledDate } //DatePicker.prototype.disabled /** * Parse a string into a usable type. */ DatePicker.prototype.parse = function( type, value, options ) { var calendar = this, parsingObject = {} if ( !value || Picker._.isInteger( value ) || Array.isArray( value ) || Picker._.isDate( value ) || Picker._.isObject( value ) && Picker._.isInteger( value.pick ) ) { return value } // We need a `.format` to parse the value. if ( !( options && options.format ) ) { // should probably default to the default format. throw "Need a formatting option to parse this.." } // Convert the format into an array and then map through it. calendar.formats.toArray( options.format ).map( function( label ) { var // Grab the formatting label. formattingLabel = calendar.formats[ label ], // The format length is from the formatting label function or the // label length without the escaping exclamation (!) mark. formatLength = formattingLabel ? Picker._.trigger( formattingLabel, calendar, [ value, parsingObject ] ) : label.replace( /^!/, '' ).length // If there's a format label, split the value up to the format length. // Then add it to the parsing object with appropriate label. if ( formattingLabel ) { parsingObject[ label ] = value.substr( 0, formatLength ) } // Update the value as the substring from format length to end. value = value.substr( formatLength ) }) // If it’s parsing a user provided month value, compensate for month 0index. return [ parsingObject.yyyy || parsingObject.yy, +( parsingObject.mm || parsingObject.m ) - ( options.data ? 1 : 0 ), parsingObject.dd || parsingObject.d ] } //DatePicker.prototype.parse /** * Various formats to display the object in. */ DatePicker.prototype.formats = (function() { // Return the length of the first word in a collection. function getWordLengthFromCollection( string, collection, dateObject ) { // Grab the first word from the string. var word = string.match( /\w+/ )[ 0 ] // If there's no month index, add it to the date object if ( !dateObject.mm && !dateObject.m ) { dateObject.m = collection.indexOf( word ) } // Return the length of the word. return word.length } // Get the length of the first word in a string. function getFirstWordLength( string ) { return string.match( /\w+/ )[ 0 ].length } return { d: function( string, dateObject ) { // If there's string, then get the digits length. // Otherwise return the selected date. return string ? Picker._.digits( string ) : dateObject.date }, dd: function( string, dateObject ) { // If there's a string, then the length is always 2. // Otherwise return the selected date with a leading zero. return string ? 2 : Picker._.lead( dateObject.date ) }, ddd: function( string, dateObject ) { // If there's a string, then get the length of the first word. // Otherwise return the short selected weekday. return string ? getFirstWordLength( string ) : this.settings.weekdaysShort[ dateObject.day ] }, dddd: function( string, dateObject ) { // If there's a string, then get the length of the first word. // Otherwise return the full selected weekday. return string ? getFirstWordLength( string ) : this.settings.weekdaysFull[ dateObject.day ] }, m: function( string, dateObject ) { // If there's a string, then get the length of the digits // Otherwise return the selected month with 0index compensation. return string ? Picker._.digits( string ) : dateObject.month + 1 }, mm: function( string, dateObject ) { // If there's a string, then the length is always 2. // Otherwise return the selected month with 0index and leading zero. return string ? 2 : Picker._.lead( dateObject.month + 1 ) }, mmm: function( string, dateObject ) { var collection = this.settings.monthsShort // If there's a string, get length of the relevant month from the short // months collection. Otherwise return the selected month from that collection. return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ] }, mmmm: function( string, dateObject ) { var collection = this.settings.monthsFull // If there's a string, get length of the relevant month from the full // months collection. Otherwise return the selected month from that collection. return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ] }, yy: function( string, dateObject ) { // If there's a string, then the length is always 2. // Otherwise return the selected year by slicing out the first 2 digits. return string ? 2 : ( '' + dateObject.year ).slice( 2 ) }, yyyy: function( string, dateObject ) { // If there's a string, then the length is always 4. // Otherwise return the selected year. return string ? 4 : dateObject.year }, // Create an array by splitting the formatting string passed. toArray: function( formatString ) { return formatString.split( /(d{1,4}|m{1,4}|y{4}|yy|!.)/g ) }, // Format an object into a string using the formatting options. toString: function ( formatString, itemObject ) { var calendar = this return calendar.formats.toArray( formatString ).map( function( label ) { return Picker._.trigger( calendar.formats[ label ], calendar, [ 0, itemObject ] ) || label.replace( /^!/, '' ) }).join( '' ) } } })() //DatePicker.prototype.formats /** * Flip an item as enabled or disabled. */ DatePicker.prototype.flipItem = function( type, value/*, options*/ ) { var calendar = this, collection = calendar.item.disable, isInverted = calendar.item.enable === -1 // Flip the enabled and disabled dates. if ( value == 'flip' ) { calendar.item.enable = isInverted ? 1 : -1 } // Check if we have to add/remove from collection. else if ( !isInverted && type == 'enable' || isInverted && type == 'disable' ) { collection = calendar.removeDisabled( collection, value ) } else if ( !isInverted && type == 'disable' || isInverted && type == 'enable' ) { collection = calendar.addDisabled( collection, value ) } return collection } //DatePicker.prototype.flipItem /** * Add an item to the disabled collection. */ DatePicker.prototype.addDisabled = function( collection, item ) { var calendar = this item.map( function( timeUnit ) { if ( !calendar.filterDisabled( collection, timeUnit ).length ) { collection.push( timeUnit ) } }) return collection } //DatePicker.prototype.addDisabled /** * Remove an item from the disabled collection. */ DatePicker.prototype.removeDisabled = function( collection, item ) { var calendar = this item.map( function( timeUnit ) { collection = calendar.filterDisabled( collection, timeUnit, 1 ) }) return collection } //DatePicker.prototype.removeDisabled /** * Filter through the disabled collection to find a time unit. */ DatePicker.prototype.filterDisabled = function( collection, timeUnit, isRemoving ) { var timeIsArray = Array.isArray( timeUnit ) return collection.filter( function( disabledTimeUnit ) { var isMatch = !timeIsArray && timeUnit === disabledTimeUnit || timeIsArray && Array.isArray( disabledTimeUnit ) && timeUnit.toString() === disabledTimeUnit.toString() return isRemoving ? !isMatch : isMatch }) } //DatePicker.prototype.filterDisabled /** * Create a string for the nodes in the picker. */ DatePicker.prototype.nodes = function( isOpen ) { var calendar = this, settings = calendar.settings, nowObject = calendar.item.now, selectedObject = calendar.item.select, highlightedObject = calendar.item.highlight, viewsetObject = calendar.item.view, disabledCollection = calendar.item.disable, minLimitObject = calendar.item.min, maxLimitObject = calendar.item.max, // Create the calendar table head using a copy of weekday labels collection. // * We do a copy so we don't mutate the original array. tableHead = (function( collection ) { // If the first day should be Monday, move Sunday to the end. if ( settings.firstDay ) { collection.push( collection.shift() ) } // Create and return the table head group. return Picker._.node( 'thead', Picker._.group({ min: 0, max: DAYS_IN_WEEK - 1, i: 1, node: 'th', item: function( counter ) { return [ collection[ counter ], settings.klass.weekdays ] } }) ) //endreturn })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysShort ).slice( 0 ) ), //tableHead // Create the nav for next/prev month. createMonthNav = function( next ) { // Otherwise, return the created month tag. return Picker._.node( 'div', ' ', settings.klass[ 'nav' + ( next ? 'Next' : 'Prev' ) ] + ( // If the focused month is outside the range, disabled the button. ( next && viewsetObject.year >= maxLimitObject.year && viewsetObject.month >= maxLimitObject.month ) || ( !next && viewsetObject.year <= minLimitObject.year && viewsetObject.month <= minLimitObject.month ) ? ' ' + settings.klass.navDisabled : '' ), 'data-nav=' + ( next || -1 ) ) //endreturn }, //createMonthNav // Create the month label. createMonthLabel = function( monthsCollection ) { // If there are months to select, add a dropdown menu. if ( settings.selectMonths ) { return Picker._.node( 'select', Picker._.group({ min: 0, max: 11, i: 1, node: 'option', item: function( loopedMonth ) { return [ // The looped month and no classes. monthsCollection[ loopedMonth ], 0, // Set the value and selected index. 'value=' + loopedMonth + ( viewsetObject.month == loopedMonth ? ' selected' : '' ) + ( ( ( viewsetObject.year == minLimitObject.year && loopedMonth < minLimitObject.month ) || ( viewsetObject.year == maxLimitObject.year && loopedMonth > maxLimitObject.month ) ) ? ' disabled' : '' ) ] } }), settings.klass.selectMonth, isOpen ? '' : 'disabled' ) } // If there's a need for a month selector return Picker._.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month ) }, //createMonthLabel // Create the year label. createYearLabel = function() { var focusedYear = viewsetObject.year, // If years selector is set to a literal "true", set it to 5. Otherwise // divide in half to get half before and half after focused year. numberYears = settings.selectYears === true ? 5 : ~~( settings.selectYears / 2 ) // If there are years to select, add a dropdown menu. if ( numberYears ) { var minYear = minLimitObject.year, maxYear = maxLimitObject.year, lowestYear = focusedYear - numberYears, highestYear = focusedYear + numberYears // If the min year is greater than the lowest year, increase the highest year // by the difference and set the lowest year to the min year. if ( minYear > lowestYear ) { highestYear += minYear - lowestYear lowestYear = minYear } // If the max year is less than the highest year, decrease the lowest year // by the lower of the two: available and needed years. Then set the // highest year to the max year. if ( maxYear < highestYear ) { var availableYears = lowestYear - minYear, neededYears = highestYear - maxYear lowestYear -= availableYears > neededYears ? neededYears : availableYears highestYear = maxYear } return Picker._.node( 'select', Picker._.group({ min: lowestYear, max: highestYear, i: 1, node: 'option', item: function( loopedYear ) { return [ // The looped year and no classes. loopedYear, 0, // Set the value and selected index. 'value=' + loopedYear + ( focusedYear == loopedYear ? ' selected' : '' ) ] } }), settings.klass.selectYear, isOpen ? '' : 'disabled' ) } // Otherwise just return the year focused return Picker._.node( 'div', focusedYear, settings.klass.year ) } //createYearLabel // Create and return the entire calendar. return Picker._.node( 'div', createMonthNav() + createMonthNav( 1 ) + createMonthLabel( settings.showMonthsShort ? settings.monthsShort : settings.monthsFull ) + createYearLabel(), settings.klass.header ) + Picker._.node( 'table', tableHead + Picker._.node( 'tbody', Picker._.group({ min: 0, max: WEEKS_IN_CALENDAR - 1, i: 1, node: 'tr', item: function( rowCounter ) { // If Monday is the first day and the month starts on Sunday, shift the date back a week. var shiftDateBy = settings.firstDay && calendar.create([ viewsetObject.year, viewsetObject.month, 1 ]).day === 0 ? -7 : 0 return [ Picker._.group({ min: DAYS_IN_WEEK * rowCounter - viewsetObject.day + shiftDateBy + 1, // Add 1 for weekday 0index max: function() { return this.min + DAYS_IN_WEEK - 1 }, i: 1, node: 'td', item: function( targetDate ) { // Convert the time date from a relative date to a target date. targetDate = calendar.create([ viewsetObject.year, viewsetObject.month, targetDate + ( settings.firstDay ? 1 : 0 ) ]) return [ Picker._.node( 'div', targetDate.date, (function( klasses ) { // Add the `infocus` or `outfocus` classes based on month in view. klasses.push( viewsetObject.month == targetDate.month ? settings.klass.infocus : settings.klass.outfocus ) // Add the `today` class if needed. if ( nowObject.pick == targetDate.pick ) { klasses.push( settings.klass.now ) } // Add the `selected` class if something's selected and the time matches. if ( selectedObject && selectedObject.pick == targetDate.pick ) { klasses.push( settings.klass.selected ) } // Add the `highlighted` class if something's highlighted and the time matches. if ( highlightedObject && highlightedObject.pick == targetDate.pick ) { klasses.push( settings.klass.highlighted ) } // Add the `disabled` class if something's disabled and the object matches. if ( disabledCollection && calendar.disabled( targetDate ) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick ) { klasses.push( settings.klass.disabled ) } return klasses.join( ' ' ) })([ settings.klass.day ]), 'data-pick=' + targetDate.pick ) ] //endreturn } }) ] //endreturn } }) ), settings.klass.table ) + Picker._.node( 'div', Picker._.node( 'button', settings.today, settings.klass.buttonToday, 'data-pick=' + nowObject.pick + ( isOpen ? '' : ' disabled' ) ) + Picker._.node( 'button', settings.clear, settings.klass.buttonClear, 'data-clear=1' + ( isOpen ? '' : ' disabled' ) ), settings.klass.footer ) //endreturn } //DatePicker.prototype.nodes /** * The date picker defaults. */ DatePicker.defaults = (function( prefix ) { return { // Months and weekdays monthsFull: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ], weekdaysFull: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ], weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ], // Today and clear today: 'Today', clear: 'Clear', // The format to show on the `input` element format: 'd mmmm, yyyy', // Classes klass: { table: prefix + 'table', header: prefix + 'header', navPrev: prefix + 'nav--prev', navNext: prefix + 'nav--next', navDisabled: prefix + 'nav--disabled', month: prefix + 'month', year: prefix + 'year', selectMonth: prefix + 'select--month', selectYear: prefix + 'select--year', weekdays: prefix + 'weekday', day: prefix + 'day', disabled: prefix + 'day--disabled', selected: prefix + 'day--selected', highlighted: prefix + 'day--highlighted', now: prefix + 'day--today', infocus: prefix + 'day--infocus', outfocus: prefix + 'day--outfocus', footer: prefix + 'footer', buttonClear: prefix + 'button--clear', buttonToday: prefix + 'button--today' } } })( Picker.klasses().picker + '__' ) /** * Extend the picker to add the date picker. */ Picker.extend( 'pickadate', DatePicker ) // Close the scope. })(); /*jshint asi: true, unused: true, boss: true, loopfunc: true, eqnull: true */ /*! * Legacy browser support */ // isArray support if ( !Array.isArray ) { Array.isArray = function( value ) { return {}.toString.call( value ) == '[object Array]' } } // Map array support if ( ![].map ) { Array.prototype.map = function ( callback, self ) { var array = this, len = array.length, newArray = new Array( len ) for ( var i = 0; i < len; i++ ) { if ( i in array ) { newArray[ i ] = callback.call( self, array[ i ], i, array ) } } return newArray } } // Filter array support if ( ![].filter ) { Array.prototype.filter = function( callback ) { if ( this == null ) throw new TypeError() var t = Object( this ), len = t.length >>> 0 if ( typeof callback != 'function' ) throw new TypeError() var newArray = [], thisp = arguments[ 1 ] for ( var i = 0; i < len; i++ ) { if ( i in t ) { var val = t[ i ] if ( callback.call( thisp, val, i, t ) ) newArray.push( val ) } } return newArray } } // Index of array support if ( ![].indexOf ) { Array.prototype.indexOf = function( searchElement ) { if ( this == null ) throw new TypeError() var t = Object( this ), len = t.length >>> 0 if ( len === 0 ) return -1 var n = 0 if ( arguments.length > 1 ) { n = Number( arguments[ 1 ] ) if ( n != n ) { n = 0 } else if ( n !== 0 && n != Infinity && n != -Infinity ) { n = ( n > 0 || -1 ) * Math.floor( Math.abs( n ) ) } } if ( n >= len ) return -1 var k = n >= 0 ? n : Math.max( len - Math.abs( n ), 0 ) for ( ; k < len; k++ ) { if ( k in t && t[ k ] === searchElement ) return k } return -1 } } /*! * Cross-Browser Split 1.1.1 * Copyright 2007-2012 Steven Levithan * Available under the MIT License * http://blog.stevenlevithan.com/archives/cross-browser-split */ var nativeSplit = String.prototype.split, compliantExecNpcg = /()??/.exec('')[1] === undefined String.prototype.split = function(separator, limit) { var str = this if (Object.prototype.toString.call(separator) !== '[object RegExp]') { return nativeSplit.call(str, separator, limit) } var output = [], flags = (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : '') + (separator.extended ? 'x' : '') + (separator.sticky ? 'y' : ''), lastLastIndex = 0, separator2, match, lastIndex, lastLength separator = new RegExp(separator.source, flags + 'g') str += '' if (!compliantExecNpcg) { separator2 = new RegExp('^' + separator.source + '$(?!\\s)', flags) } limit = limit === undefined ? -1 >>> 0 : limit >>> 0 while (match = separator.exec(str)) { lastIndex = match.index + match[0].length if (lastIndex > lastLastIndex) { output.push(str.slice(lastLastIndex, match.index)) if (!compliantExecNpcg && match.length > 1) { match[0].replace(separator2, function () { for (var i = 1; i < arguments.length - 2; i++) { if (arguments[i] === undefined) { match[i] = undefined } } }) } if (match.length > 1 && match.index < str.length) { Array.prototype.push.apply(output, match.slice(1)) } lastLength = match[0].length lastLastIndex = lastIndex if (output.length >= limit) { break } } if (separator.lastIndex === match.index) { separator.lastIndex++ } } if (lastLastIndex === str.length) { if (lastLength || !separator.test('')) { output.push('') } } else { output.push(str.slice(lastLastIndex)) } return output.length > limit ? output.slice(0, limit) : output } $(document).ready(function() { var switched = false; var updateTables = function() { if (($(window).width() <= 768) && !switched ){ console.log('entro'); switched = true; $("table.responsive").each(function(i, element) { splitTable($(element)); }); return true; } else if (switched && ($(window).width() > 768)) { switched = false; $("table.responsive").each(function(i, element) { unsplitTable($(element)); }); } }; $(window).load(updateTables); $(window).on("redraw",function(){switched=false;updateTables();}); // An event to listen for $(window).on("resize", updateTables); function splitTable(original) { original.wrap("
"); var copy = original.clone(); copy.find("td:not(:first-child), th:not(:first-child)").css("display", "none"); copy.removeClass("responsive"); original.closest(".table-wrapper").append(copy); copy.wrap("
"); original.wrap("
"); setCellHeights(original, copy); } function unsplitTable(original) { original.closest(".table-wrapper").find(".pinned").remove(); original.unwrap(); original.unwrap(); } function setCellHeights(original, copy) { var tr = original.find('tr'), tr_copy = copy.find('tr'), heights = []; tr.each(function (index) { var self = $(this), tx = self.find('th, td'); tx.each(function () { var height = $(this).outerHeight(true); heights[index] = heights[index] || 0; if (height > heights[index]) heights[index] = height; }); }); tr_copy.each(function (index) { $(this).height(heights[index]); }); } }); /* ============================================================ * bootstrap-dropdown.js v2.3.2 * http://twitter.github.com/bootstrap/javascript.html#dropdowns * ============================================================ * Copyright 2012 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============================================================ */ !function ($) { "use strict"; // jshint ;_; /* DROPDOWN CLASS DEFINITION * ========================= */ var toggle = '[data-toggle=dropdown]' , Dropdown = function (element) { var $el = $(element).on('click.dropdown.data-api', this.toggle) $('html').on('click.dropdown.data-api', function () { $el.parent().removeClass('open') }) } Dropdown.prototype = { constructor: Dropdown , toggle: function (e) { var $this = $(this) , $parent , isActive if ($this.is('.disabled, :disabled')) return $parent = getParent($this) isActive = $parent.hasClass('open') clearMenus() if (!isActive) { if ('ontouchstart' in document.documentElement) { // if mobile we we use a backdrop because click events don't delegate $('