From 3e8b34be2fdeccf16c8b46f1ee518f970853768d Mon Sep 17 00:00:00 2001 From: Mitch Riedstra Date: Tue, 24 Oct 2017 16:59:48 -0400 Subject: Adding in materialize source and templates --- .../materialize/js/date_picker/picker.time.js | 695 +++++++++++++++++++++ 1 file changed, 695 insertions(+) create mode 100644 app/dispatch/static/materialize/js/date_picker/picker.time.js (limited to 'app/dispatch/static/materialize/js/date_picker/picker.time.js') diff --git a/app/dispatch/static/materialize/js/date_picker/picker.time.js b/app/dispatch/static/materialize/js/date_picker/picker.time.js new file mode 100644 index 0000000..7379529 --- /dev/null +++ b/app/dispatch/static/materialize/js/date_picker/picker.time.js @@ -0,0 +1,695 @@ +/*! + * ClockPicker v0.0.7 (http://weareoutman.github.io/clockpicker/) + * Copyright 2014 Wang Shenwei. + * Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE) + * + * Further modified + * Copyright 2015 Ching Yaw Hao. + */ + +(function($){ + var $win = $(window), + $doc = $(document); + + // Can I use inline svg ? + var svgNS = 'http://www.w3.org/2000/svg', + svgSupported = 'SVGAngle' in window && (function() { + var supported, + el = document.createElement('div'); + el.innerHTML = ''; + supported = (el.firstChild && el.firstChild.namespaceURI) == svgNS; + el.innerHTML = ''; + return supported; + })(); + + // Can I use transition ? + var transitionSupported = (function() { + var style = document.createElement('div').style; + return 'transition' in style || + 'WebkitTransition' in style || + 'MozTransition' in style || + 'msTransition' in style || + 'OTransition' in style; + })(); + + // Listen touch events in touch screen device, instead of mouse events in desktop. + var touchSupported = 'ontouchstart' in window, + mousedownEvent = 'mousedown' + ( touchSupported ? ' touchstart' : ''), + mousemoveEvent = 'mousemove.clockpicker' + ( touchSupported ? ' touchmove.clockpicker' : ''), + mouseupEvent = 'mouseup.clockpicker' + ( touchSupported ? ' touchend.clockpicker' : ''); + + // Vibrate the device if supported + var vibrate = navigator.vibrate ? 'vibrate' : navigator.webkitVibrate ? 'webkitVibrate' : null; + + function createSvgElement(name) { + return document.createElementNS(svgNS, name); + } + + function leadingZero(num) { + return (num < 10 ? '0' : '') + num; + } + + // Get a unique id + var idCounter = 0; + function uniqueId(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + } + + // Clock size + var dialRadius = 135, + outerRadius = 105, + // innerRadius = 80 on 12 hour clock + innerRadius = 70, + tickRadius = 20, + diameter = dialRadius * 2, + duration = transitionSupported ? 350 : 1; + + // Popover template + var tpl = [ + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '', + ':', + '', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '', + '
', + '
', + '
', + '
', + '
', + '
' + ].join(''); + + // ClockPicker + function ClockPicker(element, options) { + var popover = $(tpl), + plate = popover.find('.clockpicker-plate'), + holder = popover.find('.picker__holder'), + hoursView = popover.find('.clockpicker-hours'), + minutesView = popover.find('.clockpicker-minutes'), + amPmBlock = popover.find('.clockpicker-am-pm-block'), + isInput = element.prop('tagName') === 'INPUT', + input = isInput ? element : element.find('input'), + label = $("label[for=" + input.attr("id") + "]"), + self = this; + + this.id = uniqueId('cp'); + this.element = element; + this.holder = holder; + this.options = options; + this.isAppended = false; + this.isShown = false; + this.currentView = 'hours'; + this.isInput = isInput; + this.input = input; + this.label = label; + this.popover = popover; + this.plate = plate; + this.hoursView = hoursView; + this.minutesView = minutesView; + this.amPmBlock = amPmBlock; + this.spanHours = popover.find('.clockpicker-span-hours'); + this.spanMinutes = popover.find('.clockpicker-span-minutes'); + this.spanAmPm = popover.find('.clockpicker-span-am-pm'); + this.footer = popover.find('.picker__footer'); + this.amOrPm = "PM"; + + // Setup for for 12 hour clock if option is selected + if (options.twelvehour) { + if (!options.ampmclickable) { + this.spanAmPm.empty(); + $('
AM
').appendTo(this.spanAmPm); + $('
PM
').appendTo(this.spanAmPm); + } + else { + this.spanAmPm.empty(); + $('
AM
').on("click", function() { + self.spanAmPm.children('#click-am').addClass("text-primary"); + self.spanAmPm.children('#click-pm').removeClass("text-primary"); + self.amOrPm = "AM"; + }).appendTo(this.spanAmPm); + $('
PM
').on("click", function() { + self.spanAmPm.children('#click-pm').addClass("text-primary"); + self.spanAmPm.children('#click-am').removeClass("text-primary"); + self.amOrPm = 'PM'; + }).appendTo(this.spanAmPm); + } + } + + // Add buttons to footer + $('').click($.proxy(this.clear, this)).appendTo(this.footer); + $('').click($.proxy(this.hide, this)).appendTo(this.footer); + $('').click($.proxy(this.done, this)).appendTo(this.footer); + + this.spanHours.click($.proxy(this.toggleView, this, 'hours')); + this.spanMinutes.click($.proxy(this.toggleView, this, 'minutes')); + + // Show or toggle + input.on('focus.clockpicker click.clockpicker', $.proxy(this.show, this)); + + // Build ticks + var tickTpl = $('
'), + i, tick, radian, radius; + + // Hours view + if (options.twelvehour) { + for (i = 1; i < 13; i += 1) { + tick = tickTpl.clone(); + radian = i / 6 * Math.PI; + radius = outerRadius; + tick.css({ + left: dialRadius + Math.sin(radian) * radius - tickRadius, + top: dialRadius - Math.cos(radian) * radius - tickRadius + }); + tick.html(i === 0 ? '00' : i); + hoursView.append(tick); + tick.on(mousedownEvent, mousedown); + } + } else { + for (i = 0; i < 24; i += 1) { + tick = tickTpl.clone(); + radian = i / 6 * Math.PI; + var inner = i > 0 && i < 13; + radius = inner ? innerRadius : outerRadius; + tick.css({ + left: dialRadius + Math.sin(radian) * radius - tickRadius, + top: dialRadius - Math.cos(radian) * radius - tickRadius + }); + tick.html(i === 0 ? '00' : i); + hoursView.append(tick); + tick.on(mousedownEvent, mousedown); + } + } + + // Minutes view + for (i = 0; i < 60; i += 5) { + tick = tickTpl.clone(); + radian = i / 30 * Math.PI; + tick.css({ + left: dialRadius + Math.sin(radian) * outerRadius - tickRadius, + top: dialRadius - Math.cos(radian) * outerRadius - tickRadius + }); + tick.html(leadingZero(i)); + minutesView.append(tick); + tick.on(mousedownEvent, mousedown); + } + + // Clicking on minutes view space + plate.on(mousedownEvent, function(e) { + if ($(e.target).closest('.clockpicker-tick').length === 0) { + mousedown(e, true); + } + }); + + // Mousedown or touchstart + function mousedown(e, space) { + var offset = plate.offset(), + isTouch = /^touch/.test(e.type), + x0 = offset.left + dialRadius, + y0 = offset.top + dialRadius, + dx = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0, + dy = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0, + z = Math.sqrt(dx * dx + dy * dy), + moved = false; + + // When clicking on minutes view space, check the mouse position + if (space && (z < outerRadius - tickRadius || z > outerRadius + tickRadius)) { + return; + } + e.preventDefault(); + + // Set cursor style of body after 200ms + var movingTimer = setTimeout(function(){ + self.popover.addClass('clockpicker-moving'); + }, 200); + + // Clock + self.setHand(dx, dy, !space, true); + + // Mousemove on document + $doc.off(mousemoveEvent).on(mousemoveEvent, function(e){ + e.preventDefault(); + var isTouch = /^touch/.test(e.type), + x = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0, + y = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0; + if (! moved && x === dx && y === dy) { + // Clicking in chrome on windows will trigger a mousemove event + return; + } + moved = true; + self.setHand(x, y, false, true); + }); + + // Mouseup on document + $doc.off(mouseupEvent).on(mouseupEvent, function(e) { + $doc.off(mouseupEvent); + e.preventDefault(); + var isTouch = /^touch/.test(e.type), + x = (isTouch ? e.originalEvent.changedTouches[0] : e).pageX - x0, + y = (isTouch ? e.originalEvent.changedTouches[0] : e).pageY - y0; + if ((space || moved) && x === dx && y === dy) { + self.setHand(x, y); + } + + if (self.currentView === 'hours') { + self.toggleView('minutes', duration / 2); + } else if (options.autoclose) { + self.minutesView.addClass('clockpicker-dial-out'); + setTimeout(function(){ + self.done(); + }, duration / 2); + } + plate.prepend(canvas); + + // Reset cursor style of body + clearTimeout(movingTimer); + self.popover.removeClass('clockpicker-moving'); + + // Unbind mousemove event + $doc.off(mousemoveEvent); + }); + } + + if (svgSupported) { + // Draw clock hands and others + var canvas = popover.find('.clockpicker-canvas'), + svg = createSvgElement('svg'); + svg.setAttribute('class', 'clockpicker-svg'); + svg.setAttribute('width', diameter); + svg.setAttribute('height', diameter); + var g = createSvgElement('g'); + g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')'); + var bearing = createSvgElement('circle'); + bearing.setAttribute('class', 'clockpicker-canvas-bearing'); + bearing.setAttribute('cx', 0); + bearing.setAttribute('cy', 0); + bearing.setAttribute('r', 4); + var hand = createSvgElement('line'); + hand.setAttribute('x1', 0); + hand.setAttribute('y1', 0); + var bg = createSvgElement('circle'); + bg.setAttribute('class', 'clockpicker-canvas-bg'); + bg.setAttribute('r', tickRadius); + g.appendChild(hand); + g.appendChild(bg); + g.appendChild(bearing); + svg.appendChild(g); + canvas.append(svg); + + this.hand = hand; + this.bg = bg; + this.bearing = bearing; + this.g = g; + this.canvas = canvas; + } + + raiseCallback(this.options.init); + } + + function raiseCallback(callbackFunction) { + if (callbackFunction && typeof callbackFunction === "function") + callbackFunction(); + } + + // Default options + ClockPicker.DEFAULTS = { + 'default': '', // default time, 'now' or '13:14' e.g. + fromnow: 0, // set default time to * milliseconds from now (using with default = 'now') + donetext: 'Ok', // done button text + cleartext: 'Clear', + canceltext: 'Cancel', + autoclose: false, // auto close when minute is selected + ampmclickable: true, // set am/pm button on itself + darktheme: false, // set to dark theme + twelvehour: true, // change to 12 hour AM/PM clock from 24 hour + vibrate: true // vibrate the device when dragging clock hand + }; + + // Show or hide popover + ClockPicker.prototype.toggle = function() { + this[this.isShown ? 'hide' : 'show'](); + }; + + // Set popover position + ClockPicker.prototype.locate = function() { + var element = this.element, + popover = this.popover, + offset = element.offset(), + width = element.outerWidth(), + height = element.outerHeight(), + align = this.options.align, + self = this; + + popover.show(); + }; + + // Show popover + ClockPicker.prototype.show = function(e){ + // Not show again + if (this.isShown) { + return; + } + raiseCallback(this.options.beforeShow); + $(':input').each(function() { + $(this).attr('tabindex', -1); + }) + var self = this; + // Initialize + this.input.blur(); + this.popover.addClass('picker--opened'); + this.input.addClass('picker__input picker__input--active'); + $(document.body).css('overflow', 'hidden'); + // Get the time + var value = ((this.input.prop('value') || this.options['default'] || '') + '').split(':'); + if (this.options.twelvehour && !(typeof value[1] === 'undefined')) { + if (value[1].indexOf("AM") > 0){ + this.amOrPm = 'AM'; + } else { + this.amOrPm = 'PM'; + } + value[1] = value[1].replace("AM", "").replace("PM", ""); + } + if (value[0] === 'now') { + var now = new Date(+ new Date() + this.options.fromnow); + value = [ + now.getHours(), + now.getMinutes() + ]; + if (this.options.twelvehour) { + this.amOrPm = value[0] >= 12 && value[0] < 24 ? 'PM' : 'AM'; + } + } + this.hours = + value[0] || 0; + this.minutes = + value[1] || 0; + this.spanHours.html(this.hours); + this.spanMinutes.html(leadingZero(this.minutes)); + if (!this.isAppended) { + + // Append popover to input by default + var containerEl = document.querySelector(this.options.container); + if (this.options.container && containerEl) { + containerEl.appendChild(this.popover[0]); + } else { + this.popover.insertAfter(this.input); + } + + if (this.options.twelvehour) { + if (this.amOrPm === 'PM'){ + this.spanAmPm.children('#click-pm').addClass("text-primary"); + this.spanAmPm.children('#click-am').removeClass("text-primary"); + } else { + this.spanAmPm.children('#click-am').addClass("text-primary"); + this.spanAmPm.children('#click-pm').removeClass("text-primary"); + } + } + // Reset position when resize + $win.on('resize.clockpicker' + this.id, function() { + if (self.isShown) { + self.locate(); + } + }); + this.isAppended = true; + } + // Toggle to hours view + this.toggleView('hours'); + // Set position + this.locate(); + this.isShown = true; + // Hide when clicking or tabbing on any element except the clock and input + $doc.on('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id, function(e) { + var target = $(e.target); + if (target.closest(self.popover.find('.picker__wrap')).length === 0 && target.closest(self.input).length === 0) { + self.hide(); + } + }); + // Hide when ESC is pressed + $doc.on('keyup.clockpicker.' + this.id, function(e){ + if (e.keyCode === 27) { + self.hide(); + } + }); + raiseCallback(this.options.afterShow); + }; + // Hide popover + ClockPicker.prototype.hide = function() { + raiseCallback(this.options.beforeHide); + this.input.removeClass('picker__input picker__input--active'); + this.popover.removeClass('picker--opened'); + $(document.body).css('overflow', 'visible'); + this.isShown = false; + $(':input').each(function(index) { + $(this).attr('tabindex', index + 1); + }); + // Unbinding events on document + $doc.off('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id); + $doc.off('keyup.clockpicker.' + this.id); + this.popover.hide(); + raiseCallback(this.options.afterHide); + }; + // Toggle to hours or minutes view + ClockPicker.prototype.toggleView = function(view, delay) { + var raiseAfterHourSelect = false; + if (view === 'minutes' && $(this.hoursView).css("visibility") === "visible") { + raiseCallback(this.options.beforeHourSelect); + raiseAfterHourSelect = true; + } + var isHours = view === 'hours', + nextView = isHours ? this.hoursView : this.minutesView, + hideView = isHours ? this.minutesView : this.hoursView; + this.currentView = view; + + this.spanHours.toggleClass('text-primary', isHours); + this.spanMinutes.toggleClass('text-primary', ! isHours); + + // Let's make transitions + hideView.addClass('clockpicker-dial-out'); + nextView.css('visibility', 'visible').removeClass('clockpicker-dial-out'); + + // Reset clock hand + this.resetClock(delay); + + // After transitions ended + clearTimeout(this.toggleViewTimer); + this.toggleViewTimer = setTimeout(function() { + hideView.css('visibility', 'hidden'); + }, duration); + + if (raiseAfterHourSelect) { + raiseCallback(this.options.afterHourSelect); + } + }; + + // Reset clock hand + ClockPicker.prototype.resetClock = function(delay) { + var view = this.currentView, + value = this[view], + isHours = view === 'hours', + unit = Math.PI / (isHours ? 6 : 30), + radian = value * unit, + radius = isHours && value > 0 && value < 13 ? innerRadius : outerRadius, + x = Math.sin(radian) * radius, + y = - Math.cos(radian) * radius, + self = this; + + if (svgSupported && delay) { + self.canvas.addClass('clockpicker-canvas-out'); + setTimeout(function(){ + self.canvas.removeClass('clockpicker-canvas-out'); + self.setHand(x, y); + }, delay); + } else + this.setHand(x, y); + }; + + // Set clock hand to (x, y) + ClockPicker.prototype.setHand = function(x, y, roundBy5, dragging) { + var radian = Math.atan2(x, - y), + isHours = this.currentView === 'hours', + unit = Math.PI / (isHours || roundBy5? 6 : 30), + z = Math.sqrt(x * x + y * y), + options = this.options, + inner = isHours && z < (outerRadius + innerRadius) / 2, + radius = inner ? innerRadius : outerRadius, + value; + + if (options.twelvehour) { + radius = outerRadius; + } + + // Radian should in range [0, 2PI] + if (radian < 0) { + radian = Math.PI * 2 + radian; + } + + // Get the round value + value = Math.round(radian / unit); + + // Get the round radian + radian = value * unit; + + // Correct the hours or minutes + if (options.twelvehour) { + if (isHours) { + if (value === 0) + value = 12; + } else { + if (roundBy5) + value *= 5; + if (value === 60) + value = 0; + } + } else { + if (isHours) { + if (value === 12) + value = 0; + value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12; + } else { + if (roundBy5) + value *= 5; + if (value === 60) + value = 0; + } + } + + // Once hours or minutes changed, vibrate the device + if (this[this.currentView] !== value) { + if (vibrate && this.options.vibrate) { + // Do not vibrate too frequently + if (!this.vibrateTimer) { + navigator[vibrate](10); + this.vibrateTimer = setTimeout($.proxy(function(){ + this.vibrateTimer = null; + }, this), 100); + } + } + } + + this[this.currentView] = value; + if (isHours) { + this['spanHours'].html(value); + } else { + this['spanMinutes'].html(leadingZero(value)); + } + + // If svg is not supported, just add an active class to the tick + if (!svgSupported) { + this[isHours ? 'hoursView' : 'minutesView'].find('.clockpicker-tick').each(function(){ + var tick = $(this); + tick.toggleClass('active', value === + tick.html()); + }); + return; + } + + // Set clock hand and others' position + var cx1 = Math.sin(radian) * (radius - tickRadius), + cy1 = - Math.cos(radian) * (radius - tickRadius), + cx2 = Math.sin(radian) * radius, + cy2 = - Math.cos(radian) * radius; + this.hand.setAttribute('x2', cx1); + this.hand.setAttribute('y2', cy1); + this.bg.setAttribute('cx', cx2); + this.bg.setAttribute('cy', cy2); + }; + + // Hours and minutes are selected + ClockPicker.prototype.done = function() { + raiseCallback(this.options.beforeDone); + this.hide(); + this.label.addClass('active'); + + var last = this.input.prop('value'), + value = leadingZero(this.hours) + ':' + leadingZero(this.minutes); + if (this.options.twelvehour) { + value = value + this.amOrPm; + } + + this.input.prop('value', value); + if (value !== last) { + this.input.triggerHandler('change'); + if (!this.isInput) { + this.element.trigger('change'); + } + } + + if (this.options.autoclose) + this.input.trigger('blur'); + + raiseCallback(this.options.afterDone); + }; + + // Clear input field + ClockPicker.prototype.clear = function() { + this.hide(); + this.label.removeClass('active'); + + var last = this.input.prop('value'), + value = ''; + + this.input.prop('value', value); + if (value !== last) { + this.input.triggerHandler('change'); + if (! this.isInput) { + this.element.trigger('change'); + } + } + + if (this.options.autoclose) { + this.input.trigger('blur'); + } + }; + + // Remove clockpicker from input + ClockPicker.prototype.remove = function() { + this.element.removeData('clockpicker'); + this.input.off('focus.clockpicker click.clockpicker'); + if (this.isShown) { + this.hide(); + } + if (this.isAppended) { + $win.off('resize.clockpicker' + this.id); + this.popover.remove(); + } + }; + + // Extends $.fn.clockpicker + $.fn.pickatime = function(option){ + var args = Array.prototype.slice.call(arguments, 1); + return this.each(function(){ + var $this = $(this), + data = $this.data('clockpicker'); + if (!data) { + var options = $.extend({}, ClockPicker.DEFAULTS, $this.data(), typeof option == 'object' && option); + $this.data('clockpicker', new ClockPicker($this, options)); + } else { + // Manual operatsions. show, hide, remove, e.g. + if (typeof data[option] === 'function') { + data[option].apply(data, args); + } + } + }); + }; +})(jQuery); -- cgit v1.2.3