From c84ebf26e008a0492fb2d7f3f05b4fa0c4d2b975 Mon Sep 17 00:00:00 2001 From: Henne Vogelsang Date: Thu, 27 Nov 2014 14:00:03 +0100 Subject: [PATCH 1/9] Better scroll handling for the venue map --- app/assets/javascripts/application.js | 1 + app/assets/javascripts/waypoints.js | 517 ++++++++++++++++++++++++++ app/views/conference/_venue.html.haml | 21 +- 3 files changed, 538 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/waypoints.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index b81e82d5..0370bfd9 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -12,6 +12,7 @@ // //= require jquery //= require jquery_ujs +//= require waypoints //= require dataTables/jquery.dataTables //= require dataTables/bootstrap/3/jquery.dataTables.bootstrap //= require cocoon diff --git a/app/assets/javascripts/waypoints.js b/app/assets/javascripts/waypoints.js new file mode 100644 index 00000000..4f9a33b2 --- /dev/null +++ b/app/assets/javascripts/waypoints.js @@ -0,0 +1,517 @@ +// Generated by CoffeeScript 1.6.2 +/*! +jQuery Waypoints - v2.0.5 +Copyright (c) 2011-2014 Caleb Troughton +Licensed under the MIT license. +https://github.com/imakewebthings/jquery-waypoints/blob/master/licenses.txt +*/ + + +(function() { + var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + __slice = [].slice; + + (function(root, factory) { + if (typeof define === 'function' && define.amd) { + return define('waypoints', ['jquery'], function($) { + return factory($, root); + }); + } else { + return factory(root.jQuery, root); + } + })(window, function($, window) { + var $w, Context, Waypoint, allWaypoints, contextCounter, contextKey, contexts, isTouch, jQMethods, methods, resizeEvent, scrollEvent, waypointCounter, waypointKey, wp, wps; + + $w = $(window); + isTouch = __indexOf.call(window, 'ontouchstart') >= 0; + allWaypoints = { + horizontal: {}, + vertical: {} + }; + contextCounter = 1; + contexts = {}; + contextKey = 'waypoints-context-id'; + resizeEvent = 'resize.waypoints'; + scrollEvent = 'scroll.waypoints'; + waypointCounter = 1; + waypointKey = 'waypoints-waypoint-ids'; + wp = 'waypoint'; + wps = 'waypoints'; + Context = (function() { + function Context($element) { + var _this = this; + + this.$element = $element; + this.element = $element[0]; + this.didResize = false; + this.didScroll = false; + this.id = 'context' + contextCounter++; + this.oldScroll = { + x: $element.scrollLeft(), + y: $element.scrollTop() + }; + this.waypoints = { + horizontal: {}, + vertical: {} + }; + this.element[contextKey] = this.id; + contexts[this.id] = this; + $element.bind(scrollEvent, function() { + var scrollHandler; + + if (!(_this.didScroll || isTouch)) { + _this.didScroll = true; + scrollHandler = function() { + _this.doScroll(); + return _this.didScroll = false; + }; + return window.setTimeout(scrollHandler, $[wps].settings.scrollThrottle); + } + }); + $element.bind(resizeEvent, function() { + var resizeHandler; + + if (!_this.didResize) { + _this.didResize = true; + resizeHandler = function() { + $[wps]('refresh'); + return _this.didResize = false; + }; + return window.setTimeout(resizeHandler, $[wps].settings.resizeThrottle); + } + }); + } + + Context.prototype.doScroll = function() { + var axes, + _this = this; + + axes = { + horizontal: { + newScroll: this.$element.scrollLeft(), + oldScroll: this.oldScroll.x, + forward: 'right', + backward: 'left' + }, + vertical: { + newScroll: this.$element.scrollTop(), + oldScroll: this.oldScroll.y, + forward: 'down', + backward: 'up' + } + }; + if (isTouch && (!axes.vertical.oldScroll || !axes.vertical.newScroll)) { + $[wps]('refresh'); + } + $.each(axes, function(aKey, axis) { + var direction, isForward, triggered; + + triggered = []; + isForward = axis.newScroll > axis.oldScroll; + direction = isForward ? axis.forward : axis.backward; + $.each(_this.waypoints[aKey], function(wKey, waypoint) { + var _ref, _ref1; + + if ((axis.oldScroll < (_ref = waypoint.offset) && _ref <= axis.newScroll)) { + return triggered.push(waypoint); + } else if ((axis.newScroll < (_ref1 = waypoint.offset) && _ref1 <= axis.oldScroll)) { + return triggered.push(waypoint); + } + }); + triggered.sort(function(a, b) { + return a.offset - b.offset; + }); + if (!isForward) { + triggered.reverse(); + } + return $.each(triggered, function(i, waypoint) { + if (waypoint.options.continuous || i === triggered.length - 1) { + return waypoint.trigger([direction]); + } + }); + }); + return this.oldScroll = { + x: axes.horizontal.newScroll, + y: axes.vertical.newScroll + }; + }; + + Context.prototype.refresh = function() { + var axes, cOffset, isWin, + _this = this; + + isWin = $.isWindow(this.element); + cOffset = this.$element.offset(); + this.doScroll(); + axes = { + horizontal: { + contextOffset: isWin ? 0 : cOffset.left, + contextScroll: isWin ? 0 : this.oldScroll.x, + contextDimension: this.$element.width(), + oldScroll: this.oldScroll.x, + forward: 'right', + backward: 'left', + offsetProp: 'left' + }, + vertical: { + contextOffset: isWin ? 0 : cOffset.top, + contextScroll: isWin ? 0 : this.oldScroll.y, + contextDimension: isWin ? $[wps]('viewportHeight') : this.$element.height(), + oldScroll: this.oldScroll.y, + forward: 'down', + backward: 'up', + offsetProp: 'top' + } + }; + return $.each(axes, function(aKey, axis) { + return $.each(_this.waypoints[aKey], function(i, waypoint) { + var adjustment, elementOffset, oldOffset, _ref, _ref1; + + adjustment = waypoint.options.offset; + oldOffset = waypoint.offset; + elementOffset = $.isWindow(waypoint.element) ? 0 : waypoint.$element.offset()[axis.offsetProp]; + if ($.isFunction(adjustment)) { + adjustment = adjustment.apply(waypoint.element); + } else if (typeof adjustment === 'string') { + adjustment = parseFloat(adjustment); + if (waypoint.options.offset.indexOf('%') > -1) { + adjustment = Math.ceil(axis.contextDimension * adjustment / 100); + } + } + waypoint.offset = elementOffset - axis.contextOffset + axis.contextScroll - adjustment; + if ((waypoint.options.onlyOnScroll && (oldOffset != null)) || !waypoint.enabled) { + return; + } + if (oldOffset !== null && (oldOffset < (_ref = axis.oldScroll) && _ref <= waypoint.offset)) { + return waypoint.trigger([axis.backward]); + } else if (oldOffset !== null && (oldOffset > (_ref1 = axis.oldScroll) && _ref1 >= waypoint.offset)) { + return waypoint.trigger([axis.forward]); + } else if (oldOffset === null && axis.oldScroll >= waypoint.offset) { + return waypoint.trigger([axis.forward]); + } + }); + }); + }; + + Context.prototype.checkEmpty = function() { + if ($.isEmptyObject(this.waypoints.horizontal) && $.isEmptyObject(this.waypoints.vertical)) { + this.$element.unbind([resizeEvent, scrollEvent].join(' ')); + return delete contexts[this.id]; + } + }; + + return Context; + + })(); + Waypoint = (function() { + function Waypoint($element, context, options) { + var idList, _ref; + + if (options.offset === 'bottom-in-view') { + options.offset = function() { + var contextHeight; + + contextHeight = $[wps]('viewportHeight'); + if (!$.isWindow(context.element)) { + contextHeight = context.$element.height(); + } + return contextHeight - $(this).outerHeight(); + }; + } + this.$element = $element; + this.element = $element[0]; + this.axis = options.horizontal ? 'horizontal' : 'vertical'; + this.callback = options.handler; + this.context = context; + this.enabled = options.enabled; + this.id = 'waypoints' + waypointCounter++; + this.offset = null; + this.options = options; + context.waypoints[this.axis][this.id] = this; + allWaypoints[this.axis][this.id] = this; + idList = (_ref = this.element[waypointKey]) != null ? _ref : []; + idList.push(this.id); + this.element[waypointKey] = idList; + } + + Waypoint.prototype.trigger = function(args) { + if (!this.enabled) { + return; + } + if (this.callback != null) { + this.callback.apply(this.element, args); + } + if (this.options.triggerOnce) { + return this.destroy(); + } + }; + + Waypoint.prototype.disable = function() { + return this.enabled = false; + }; + + Waypoint.prototype.enable = function() { + this.context.refresh(); + return this.enabled = true; + }; + + Waypoint.prototype.destroy = function() { + delete allWaypoints[this.axis][this.id]; + delete this.context.waypoints[this.axis][this.id]; + return this.context.checkEmpty(); + }; + + Waypoint.getWaypointsByElement = function(element) { + var all, ids; + + ids = element[waypointKey]; + if (!ids) { + return []; + } + all = $.extend({}, allWaypoints.horizontal, allWaypoints.vertical); + return $.map(ids, function(id) { + return all[id]; + }); + }; + + return Waypoint; + + })(); + methods = { + init: function(f, options) { + var _ref; + + options = $.extend({}, $.fn[wp].defaults, options); + if ((_ref = options.handler) == null) { + options.handler = f; + } + this.each(function() { + var $this, context, contextElement, _ref1; + + $this = $(this); + contextElement = (_ref1 = options.context) != null ? _ref1 : $.fn[wp].defaults.context; + if (!$.isWindow(contextElement)) { + contextElement = $this.closest(contextElement); + } + contextElement = $(contextElement); + context = contexts[contextElement[0][contextKey]]; + if (!context) { + context = new Context(contextElement); + } + return new Waypoint($this, context, options); + }); + $[wps]('refresh'); + return this; + }, + disable: function() { + return methods._invoke.call(this, 'disable'); + }, + enable: function() { + return methods._invoke.call(this, 'enable'); + }, + destroy: function() { + return methods._invoke.call(this, 'destroy'); + }, + prev: function(axis, selector) { + return methods._traverse.call(this, axis, selector, function(stack, index, waypoints) { + if (index > 0) { + return stack.push(waypoints[index - 1]); + } + }); + }, + next: function(axis, selector) { + return methods._traverse.call(this, axis, selector, function(stack, index, waypoints) { + if (index < waypoints.length - 1) { + return stack.push(waypoints[index + 1]); + } + }); + }, + _traverse: function(axis, selector, push) { + var stack, waypoints; + + if (axis == null) { + axis = 'vertical'; + } + if (selector == null) { + selector = window; + } + waypoints = jQMethods.aggregate(selector); + stack = []; + this.each(function() { + var index; + + index = $.inArray(this, waypoints[axis]); + return push(stack, index, waypoints[axis]); + }); + return this.pushStack(stack); + }, + _invoke: function(method) { + this.each(function() { + var waypoints; + + waypoints = Waypoint.getWaypointsByElement(this); + return $.each(waypoints, function(i, waypoint) { + waypoint[method](); + return true; + }); + }); + return this; + } + }; + $.fn[wp] = function() { + var args, method; + + method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + if (methods[method]) { + return methods[method].apply(this, args); + } else if ($.isFunction(method)) { + return methods.init.apply(this, arguments); + } else if ($.isPlainObject(method)) { + return methods.init.apply(this, [null, method]); + } else if (!method) { + return $.error("jQuery Waypoints needs a callback function or handler option."); + } else { + return $.error("The " + method + " method does not exist in jQuery Waypoints."); + } + }; + $.fn[wp].defaults = { + context: window, + continuous: true, + enabled: true, + horizontal: false, + offset: 0, + triggerOnce: false + }; + jQMethods = { + refresh: function() { + return $.each(contexts, function(i, context) { + return context.refresh(); + }); + }, + viewportHeight: function() { + var _ref; + + return (_ref = window.innerHeight) != null ? _ref : $w.height(); + }, + aggregate: function(contextSelector) { + var collection, waypoints, _ref; + + collection = allWaypoints; + if (contextSelector) { + collection = (_ref = contexts[$(contextSelector)[0][contextKey]]) != null ? _ref.waypoints : void 0; + } + if (!collection) { + return []; + } + waypoints = { + horizontal: [], + vertical: [] + }; + $.each(waypoints, function(axis, arr) { + $.each(collection[axis], function(key, waypoint) { + return arr.push(waypoint); + }); + arr.sort(function(a, b) { + return a.offset - b.offset; + }); + waypoints[axis] = $.map(arr, function(waypoint) { + return waypoint.element; + }); + return waypoints[axis] = $.unique(waypoints[axis]); + }); + return waypoints; + }, + above: function(contextSelector) { + if (contextSelector == null) { + contextSelector = window; + } + return jQMethods._filter(contextSelector, 'vertical', function(context, waypoint) { + return waypoint.offset <= context.oldScroll.y; + }); + }, + below: function(contextSelector) { + if (contextSelector == null) { + contextSelector = window; + } + return jQMethods._filter(contextSelector, 'vertical', function(context, waypoint) { + return waypoint.offset > context.oldScroll.y; + }); + }, + left: function(contextSelector) { + if (contextSelector == null) { + contextSelector = window; + } + return jQMethods._filter(contextSelector, 'horizontal', function(context, waypoint) { + return waypoint.offset <= context.oldScroll.x; + }); + }, + right: function(contextSelector) { + if (contextSelector == null) { + contextSelector = window; + } + return jQMethods._filter(contextSelector, 'horizontal', function(context, waypoint) { + return waypoint.offset > context.oldScroll.x; + }); + }, + enable: function() { + return jQMethods._invoke('enable'); + }, + disable: function() { + return jQMethods._invoke('disable'); + }, + destroy: function() { + return jQMethods._invoke('destroy'); + }, + extendFn: function(methodName, f) { + return methods[methodName] = f; + }, + _invoke: function(method) { + var waypoints; + + waypoints = $.extend({}, allWaypoints.vertical, allWaypoints.horizontal); + return $.each(waypoints, function(key, waypoint) { + waypoint[method](); + return true; + }); + }, + _filter: function(selector, axis, test) { + var context, waypoints; + + context = contexts[$(selector)[0][contextKey]]; + if (!context) { + return []; + } + waypoints = []; + $.each(context.waypoints[axis], function(i, waypoint) { + if (test(context, waypoint)) { + return waypoints.push(waypoint); + } + }); + waypoints.sort(function(a, b) { + return a.offset - b.offset; + }); + return $.map(waypoints, function(waypoint) { + return waypoint.element; + }); + } + }; + $[wps] = function() { + var args, method; + + method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + if (jQMethods[method]) { + return jQMethods[method].apply(null, args); + } else { + return jQMethods.aggregate.call(null, method); + } + }; + $[wps].settings = { + resizeThrottle: 100, + scrollThrottle: 30 + }; + return $w.on('load.waypoints', function() { + return $[wps]('refresh'); + }); + }); + +}).call(this); diff --git a/app/views/conference/_venue.html.haml b/app/views/conference/_venue.html.haml index 5c8742bb..4fd90246 100644 --- a/app/views/conference/_venue.html.haml +++ b/app/views/conference/_venue.html.haml @@ -3,7 +3,7 @@ %a.smoothscroll{ href: '#venue' } Venue -if !@conference.venue.latitude.blank? and !@conference.venue.longitude.blank? #map{style: "height: 500px;" } - - popup = "

#{@conference.venue.name}


#{@conference.venue.street}
#{@conference.venue.postalcode}, #{@conference.venue.city}
#{@conference.venue.country_name}" + - popup = "

#{@conference.venue.name}


#{@conference.venue.street}
#{@conference.venue.city}
#{@conference.venue.country_name}" - content_for(:script_body) do :javascript // create a map in the "map" div, set the view to a given place and zoom @@ -17,6 +17,25 @@ L.marker([#{@conference.venue.longitude}, #{@conference.venue.latitude}]).addTo(map) .bindPopup("#{popup}") .openPopup(); + // Turn scrollwheel on when user clicks + map.on('focus', function(e) { + map.scrollWheelZoom.enable(); + }); + // Turn scrollwheel off once the map isn't in the viewport anymore + $('#map').waypoint({ + handler: function(direction) { + map.scrollWheelZoom.disable(); + //alert('map'); + }, + offset: '90%' + }); + $('#map').waypoint({ + handler: function(direction) { + map.scrollWheelZoom.disable(); + //alert('map'); + }, + offset: '10%' + }); -else .container .row From ebb7d8da2c28d1bb299349ebe253780ec94b7820 Mon Sep 17 00:00:00 2001 From: Henne Vogelsang Date: Thu, 27 Nov 2014 14:00:52 +0100 Subject: [PATCH 2/9] We don't use the JqueryUI timepicker anymore --- .../javascripts/jquery-ui-timepicker-addon.js | 1902 ----------------- 1 file changed, 1902 deletions(-) delete mode 100644 app/assets/javascripts/jquery-ui-timepicker-addon.js diff --git a/app/assets/javascripts/jquery-ui-timepicker-addon.js b/app/assets/javascripts/jquery-ui-timepicker-addon.js deleted file mode 100644 index 1bc8d53b..00000000 --- a/app/assets/javascripts/jquery-ui-timepicker-addon.js +++ /dev/null @@ -1,1902 +0,0 @@ -/* - * jQuery timepicker addon - * By: Trent Richardson [http://trentrichardson.com] - * Version 1.1.2 - * Last Modified: 01/19/2013 - * - * Copyright 2012 Trent Richardson - * You may use this project under MIT or GPL licenses. - * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt - * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt - */ - -/*jslint evil: true, white: false, undef: false, nomen: false */ - -(function($) { - - /* - * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded" - */ - $.ui.timepicker = $.ui.timepicker || {}; - if ($.ui.timepicker.version) { - return; - } - - /* - * Extend jQueryUI, get it started with our version number - */ - $.extend($.ui, { - timepicker: { - version: "1.1.2" - } - }); - - /* - * Timepicker manager. - * Use the singleton instance of this class, $.timepicker, to interact with the time picker. - * Settings for (groups of) time pickers are maintained in an instance object, - * allowing multiple different settings on the same page. - */ - function Timepicker() { - this.regional = []; // Available regional settings, indexed by language code - this.regional[''] = { // Default regional settings - currentText: 'Now', - closeText: 'Done', - amNames: ['AM', 'A'], - pmNames: ['PM', 'P'], - timeFormat: 'HH:mm', - timeSuffix: '', - timeOnlyTitle: 'Choose Time', - timeText: 'Time', - hourText: 'Hour', - minuteText: 'Minute', - secondText: 'Second', - millisecText: 'Millisecond', - timezoneText: 'Time Zone', - isRTL: false - }; - this._defaults = { // Global defaults for all the datetime picker instances - showButtonPanel: true, - timeOnly: false, - showHour: true, - showMinute: true, - showSecond: false, - showMillisec: false, - showTimezone: false, - showTime: true, - stepHour: 1, - stepMinute: 1, - stepSecond: 1, - stepMillisec: 1, - hour: 0, - minute: 0, - second: 0, - millisec: 0, - timezone: null, - useLocalTimezone: false, - defaultTimezone: "+0000", - hourMin: 0, - minuteMin: 0, - secondMin: 0, - millisecMin: 0, - hourMax: 23, - minuteMax: 59, - secondMax: 59, - millisecMax: 999, - minDateTime: null, - maxDateTime: null, - onSelect: null, - hourGrid: 0, - minuteGrid: 0, - secondGrid: 0, - millisecGrid: 0, - alwaysSetTime: true, - separator: ' ', - altFieldTimeOnly: true, - altTimeFormat: null, - altSeparator: null, - altTimeSuffix: null, - pickerTimeFormat: null, - pickerTimeSuffix: null, - showTimepicker: true, - timezoneIso8601: false, - timezoneList: null, - addSliderAccess: false, - sliderAccessArgs: null, - controlType: 'slider', - defaultValue: null, - parse: 'strict' - }; - $.extend(this._defaults, this.regional['']); - } - - $.extend(Timepicker.prototype, { - $input: null, - $altInput: null, - $timeObj: null, - inst: null, - hour_slider: null, - minute_slider: null, - second_slider: null, - millisec_slider: null, - timezone_select: null, - hour: 0, - minute: 0, - second: 0, - millisec: 0, - timezone: null, - defaultTimezone: "+0000", - hourMinOriginal: null, - minuteMinOriginal: null, - secondMinOriginal: null, - millisecMinOriginal: null, - hourMaxOriginal: null, - minuteMaxOriginal: null, - secondMaxOriginal: null, - millisecMaxOriginal: null, - ampm: '', - formattedDate: '', - formattedTime: '', - formattedDateTime: '', - timezoneList: null, - units: ['hour','minute','second','millisec'], - control: null, - - /* - * Override the default settings for all instances of the time picker. - * @param settings object - the new settings to use as defaults (anonymous object) - * @return the manager object - */ - setDefaults: function(settings) { - extendRemove(this._defaults, settings || {}); - return this; - }, - - /* - * Create a new Timepicker instance - */ - _newInst: function($input, o) { - var tp_inst = new Timepicker(), - inlineSettings = {}, - fns = {}, - overrides, i; - - for (var attrName in this._defaults) { - if(this._defaults.hasOwnProperty(attrName)){ - var attrValue = $input.attr('time:' + attrName); - if (attrValue) { - try { - inlineSettings[attrName] = eval(attrValue); - } catch (err) { - inlineSettings[attrName] = attrValue; - } - } - } - } - overrides = { - beforeShow: function (input, dp_inst) { - if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) { - return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst); - } - }, - onChangeMonthYear: function (year, month, dp_inst) { - // Update the time as well : this prevents the time from disappearing from the $input field. - tp_inst._updateDateTime(dp_inst); - if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) { - tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); - } - }, - onClose: function (dateText, dp_inst) { - if (tp_inst.timeDefined === true && $input.val() !== '') { - tp_inst._updateDateTime(dp_inst); - } - if ($.isFunction(tp_inst._defaults.evnts.onClose)) { - tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst); - } - } - }; - for (i in overrides) { - if (overrides.hasOwnProperty(i)) { - fns[i] = o[i] || null; - } - } - tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, overrides, { - evnts:fns, - timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); - }); - tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { - return val.toUpperCase(); - }); - tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { - return val.toUpperCase(); - }); - - // controlType is string - key to our this._controls - if(typeof(tp_inst._defaults.controlType) === 'string'){ - if($.fn[tp_inst._defaults.controlType] === undefined){ - tp_inst._defaults.controlType = 'select'; - } - tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType]; - } - // controlType is an object and must implement create, options, value methods - else{ - tp_inst.control = tp_inst._defaults.controlType; - } - - if (tp_inst._defaults.timezoneList === null) { - var timezoneList = ['-1200', '-1100', '-1000', '-0930', '-0900', '-0800', '-0700', '-0600', '-0500', '-0430', '-0400', '-0330', '-0300', '-0200', '-0100', '+0000', - '+0100', '+0200', '+0300', '+0330', '+0400', '+0430', '+0500', '+0530', '+0545', '+0600', '+0630', '+0700', '+0800', '+0845', '+0900', '+0930', - '+1000', '+1030', '+1100', '+1130', '+1200', '+1245', '+1300', '+1400']; - - if (tp_inst._defaults.timezoneIso8601) { - timezoneList = $.map(timezoneList, function(val) { - return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3)); - }); - } - tp_inst._defaults.timezoneList = timezoneList; - } - - tp_inst.timezone = tp_inst._defaults.timezone; - tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin? tp_inst._defaults.hourMin : - tp_inst._defaults.hour > tp_inst._defaults.hourMax? tp_inst._defaults.hourMax : tp_inst._defaults.hour; - tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin? tp_inst._defaults.minuteMin : - tp_inst._defaults.minute > tp_inst._defaults.minuteMax? tp_inst._defaults.minuteMax : tp_inst._defaults.minute; - tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin? tp_inst._defaults.secondMin : - tp_inst._defaults.second > tp_inst._defaults.secondMax? tp_inst._defaults.secondMax : tp_inst._defaults.second; - tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin? tp_inst._defaults.millisecMin : - tp_inst._defaults.millisec > tp_inst._defaults.millisecMax? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec; - tp_inst.ampm = ''; - tp_inst.$input = $input; - - if (o.altField) { - tp_inst.$altInput = $(o.altField).css({ - cursor: 'pointer' - }).focus(function() { - $input.trigger("focus"); - }); - } - - if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) { - tp_inst._defaults.minDate = new Date(); - } - if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) { - tp_inst._defaults.maxDate = new Date(); - } - - // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. - if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) { - tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); - } - if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) { - tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); - } - if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) { - tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); - } - if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) { - tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); - } - tp_inst.$input.bind('focus', function() { - tp_inst._onFocus(); - }); - - return tp_inst; - }, - - /* - * add our sliders to the calendar - */ - _addTimePicker: function(dp_inst) { - var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val(); - - this.timeDefined = this._parseTime(currDT); - this._limitMinMaxDateTime(dp_inst, false); - this._injectTimePicker(); - }, - - /* - * parse the time string from input value or _setTime - */ - _parseTime: function(timeString, withDate) { - if (!this.inst) { - this.inst = $.datepicker._getInst(this.$input[0]); - } - - if (withDate || !this._defaults.timeOnly) { - var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); - try { - var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults); - if (!parseRes.timeObj) { - return false; - } - $.extend(this, parseRes.timeObj); - } catch (err) { - $.datepicker.log("Error parsing the date/time string: " + err + - "\ndate/time string = " + timeString + - "\ntimeFormat = " + this._defaults.timeFormat + - "\ndateFormat = " + dp_dateFormat); - return false; - } - return true; - } else { - var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults); - if (!timeObj) { - return false; - } - $.extend(this, timeObj); - return true; - } - }, - - /* - * generate and inject html for timepicker into ui datepicker - */ - _injectTimePicker: function() { - var $dp = this.inst.dpDiv, - o = this.inst.settings, - tp_inst = this, - litem = '', - uitem = '', - max = {}, - gridSize = {}, - size = null; - - // Prevent displaying twice - if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) { - var noDisplay = ' style="display:none;"', - html = '
' + '
' + o.timeText + '
' + - '
'; - - // Create the markup - for(var i=0,l=this.units.length; i' + o[litem +'Text'] + '' + - '
'; - - if (o['show'+uitem] && o[litem+'Grid'] > 0) { - html += '
'; - - if(litem == 'hour'){ - for (var h = o[litem+'Min']; h <= max[litem]; h += parseInt(o[litem+'Grid'], 10)) { - gridSize[litem]++; - var tmph = $.datepicker.formatTime(useAmpm(o.pickerTimeFormat || o.timeFormat)? 'hht':'HH', {hour:h}, o); - html += ''; - } - } - else{ - for (var m = o[litem+'Min']; m <= max[litem]; m += parseInt(o[litem+'Grid'], 10)) { - gridSize[litem]++; - html += ''; - } - } - - html += '
' + tmph + '' + ((m < 10) ? '0' : '') + m + '
'; - } - html += '
'; - } - - // Timezone - html += '
' + o.timezoneText + '
'; - html += '
'; - - // Create the elements from string - html += '
'; - var $tp = $(html); - - // if we only want time picker... - if (o.timeOnly === true) { - $tp.prepend('
' + '
' + o.timeOnlyTitle + '
' + '
'); - $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); - } - - // add sliders, adjust grids, add events - for(var i=0,l=tp_inst.units.length; i 0) { - size = 100 * gridSize[litem] * o[litem+'Grid'] / (max[litem] - o[litem+'Min']); - $tp.find('.ui_tpicker_'+litem+' table').css({ - width: size + "%", - marginLeft: o.isRTL? '0' : ((size / (-2 * gridSize[litem])) + "%"), - marginRight: o.isRTL? ((size / (-2 * gridSize[litem])) + "%") : '0', - borderCollapse: 'collapse' - }).find("td").click(function(e){ - var $t = $(this), - h = $t.html(), - n = parseInt(h.replace(/[^0-9]/g),10), - ap = h.replace(/[^apm]/ig), - f = $t.data('for'); // loses scope, so we use data-for - - if(f == 'hour'){ - if(ap.indexOf('p') !== -1 && n < 12){ - n += 12; - } - else{ - if(ap.indexOf('a') !== -1 && n === 12){ - n = 0; - } - } - } - - tp_inst.control.value(tp_inst, tp_inst[f+'_slider'], litem, n); - - tp_inst._onTimeChange(); - tp_inst._onSelectHandler(); - }) - .css({ - cursor: 'pointer', - width: (100 / gridSize[litem]) + '%', - textAlign: 'center', - overflow: 'hidden' - }); - } // end if grid > 0 - } // end for loop - - // Add timezone options - this.timezone_select = $tp.find('.ui_tpicker_timezone').append('').find("select"); - $.fn.append.apply(this.timezone_select, - $.map(o.timezoneList, function(val, idx) { - return $("