* packages.config:
* App.master: * datepair.js: * Book.aspx: * datepair.min.js: * LocalizedText.resx: * jquery.datepair.js: * jquery-ui-1.11.4.js: * jquery.timepicker.js: * BookQuery.cs: * jquery-1.11.3.min.js: * LocalizedText.fr.resx: * jquery.datepair.min.js: * WebCatalogExtensions.cs: * GoogleController.cs: * LocalizedText.Designer.cs: * jquery.timepicker.min.js: * jquery.timepicker.css: * Text.cs: * Euro.cs: * Unit.cs: * Link.cs: * Note.cs: * LocalizedText.fr.Designer.cs: * Brand.cs: * Label.cs: * Scalar.cs: * FrontOfficeController.cs: * Period.cs: * Option.cs: * Service.cs: * Catalog.cs: * Product.cs: * CheckBox.cs: * Currency.cs: * SaleForm.cs: * TextInput.cs: * FormInput.cs: * FilesInput.cs: * SelectItem.cs: * FormElement.cs: * SelectInput.cs: * RadioButton.cs: * StockStatus.cs: * ProductImage.cs: * CatalogHelper.cs: * CatalogManager.cs: * ProductCategory.cs: * PhysicalProduct.cs: * ui-icons_ffffff_256x240.png: * ui-icons_cccccc_256x240.png: * CatalogProvider.cs: * ui-icons_a83300_256x240.png: * ui-icons_222222_256x240.png: * ui-icons_4b8e0b_256x240.png: * ui-bg_glass_20_555555_1x400.png: * ui-bg_glass_40_0078a3_1x400.png: * ui-bg_glass_40_ffc73d_1x400.png: * ui-icons_222222_256x240.png: * ui-icons_a83300_256x240.png: * ui-icons_cccccc_256x240.png: * ui-icons_4b8e0b_256x240.png: * ui-icons_ffffff_256x240.png: * ui-bg_glass_40_0078a3_1x400.png: * ui-bg_glass_20_555555_1x400.png: * ui-bg_inset-soft_30_f58400_1x100.png: * ui-bg_inset-soft_25_000000_1x100.png: * ui-bg_glass_40_ffc73d_1x400.png: * ui-bg_gloss-wave_25_333333_500x100.png: * ui-bg_highlight-soft_80_eeeeee_1x100.png: * ui-bg_inset-soft_30_f58400_1x100.png: * ui-bg_inset-soft_25_000000_1x100.png: * ui-bg_gloss-wave_25_333333_500x100.png: * ui-bg_highlight-soft_80_eeeeee_1x100.png: * CatalogProviderConfigurationElement.cs: * CatalogProvidersConfigurationSection.cs: * CatalogProvidersConfigurationCollection.cs: Date pairing at booking, Fixes the client side ui, concerning the dates and times * MyClass.cs: * WorkFlowManager.cs: * IContentProvider.cs: * FrontOfficeController.cs: * XmlCatalog.cs: * NpgsqlContentProvider.cs: * Price.cs: * XmlCatalogProvider.cs: * PriceOnItemCount.cs: refactoring: a dedicated name space for the catalog * ChooseADate.aspx: WIP * Web.csproj: date pairing : includes the javascript modules
This commit is contained in:
parent
2a30ae85a9
commit
0a91d3935b
94 changed files with 955 additions and 297 deletions
343
web/Scripts/datepair.js
Normal file
343
web/Scripts/datepair.js
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
/*!
|
||||
* datepair.js v0.4.11 - A javascript plugin for intelligently selecting date and time ranges inspired by Google Calendar.
|
||||
* Copyright (c) 2015 Jon Thornton - http://jonthornton.github.com/Datepair.js
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
(function(window, document) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var _ONE_DAY = 86400000;
|
||||
var jq = window.Zepto || window.jQuery;
|
||||
|
||||
function simpleExtend(obj1, obj2) {
|
||||
var out = obj2 || {};
|
||||
|
||||
for (var i in obj1) {
|
||||
if (!(i in out)) {
|
||||
out[i] = obj1[i];
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// IE's custom event support is totally borked.
|
||||
// Use jQuery if possible
|
||||
function triggerSimpleCustomEvent(el, eventName) {
|
||||
if (jq) {
|
||||
jq(el).trigger(eventName);
|
||||
} else {
|
||||
var event = document.createEvent('CustomEvent');
|
||||
event.initCustomEvent(eventName, true, true, {});
|
||||
el.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
// el.classList not supported by < IE10
|
||||
// use jQuery if available
|
||||
function hasClass(el, className) {
|
||||
if (jq) {
|
||||
return jq(el).hasClass(className);
|
||||
} else {
|
||||
return el.classList.contains(className);
|
||||
}
|
||||
}
|
||||
|
||||
function Datepair(container, options) {
|
||||
this.dateDelta = null;
|
||||
this.timeDelta = null;
|
||||
this._defaults = {
|
||||
startClass: 'start',
|
||||
endClass: 'end',
|
||||
timeClass: 'time',
|
||||
dateClass: 'date',
|
||||
defaultDateDelta: 0,
|
||||
defaultTimeDelta: 3600000,
|
||||
anchor: 'start',
|
||||
|
||||
// defaults for jquery-timepicker; override when using other input widgets
|
||||
parseTime: function(input){
|
||||
return jq(input).timepicker('getTime');
|
||||
},
|
||||
updateTime: function(input, dateObj){
|
||||
jq(input).timepicker('setTime', dateObj);
|
||||
},
|
||||
setMinTime: function(input, dateObj){
|
||||
jq(input).timepicker('option', 'minTime', dateObj);
|
||||
},
|
||||
|
||||
// defaults for bootstrap datepicker; override when using other input widgets
|
||||
parseDate: function(input){
|
||||
return input.value && jq(input).datepicker('getDate');
|
||||
},
|
||||
updateDate: function(input, dateObj){
|
||||
jq(input).datepicker('update', dateObj);
|
||||
}
|
||||
};
|
||||
|
||||
this.container = container;
|
||||
this.settings = simpleExtend(this._defaults, options);
|
||||
|
||||
this.startDateInput = this.container.querySelector('.'+this.settings.startClass+'.'+this.settings.dateClass);
|
||||
this.endDateInput = this.container.querySelector('.'+this.settings.endClass+'.'+this.settings.dateClass);
|
||||
this.startTimeInput = this.container.querySelector('.'+this.settings.startClass+'.'+this.settings.timeClass);
|
||||
this.endTimeInput = this.container.querySelector('.'+this.settings.endClass+'.'+this.settings.timeClass);
|
||||
|
||||
// initialize date and time deltas
|
||||
this.refresh();
|
||||
this._updateEndMintime();
|
||||
|
||||
// init starts here
|
||||
this._bindChangeHandler();
|
||||
}
|
||||
|
||||
Datepair.prototype = {
|
||||
constructor: Datepair,
|
||||
|
||||
option: function(key, value)
|
||||
{
|
||||
if (typeof key == 'object') {
|
||||
this.settings = simpleExtend(this.settings, key);
|
||||
|
||||
} else if (typeof key == 'string' && typeof value != 'undefined') {
|
||||
this.settings[key] = value;
|
||||
|
||||
} else if (typeof key == 'string') {
|
||||
return this.settings[key];
|
||||
}
|
||||
|
||||
this._updateEndMintime();
|
||||
},
|
||||
|
||||
getTimeDiff: function()
|
||||
{
|
||||
// due to the fact that times can wrap around, timeDiff for any
|
||||
// time-only pair will always be >= 0
|
||||
var delta = this.dateDelta + this.timeDelta;
|
||||
if (delta < 0 && (!this.startDateInput || !this.endDateInput) ) {
|
||||
delta += _ONE_DAY;
|
||||
}
|
||||
|
||||
return delta;
|
||||
},
|
||||
|
||||
refresh: function()
|
||||
{
|
||||
if (this.startDateInput && this.startDateInput.value && this.endDateInput && this.endDateInput.value) {
|
||||
var startDate = this.settings.parseDate(this.startDateInput);
|
||||
var endDate = this.settings.parseDate(this.endDateInput);
|
||||
if (startDate && endDate) {
|
||||
this.dateDelta = endDate.getTime() - startDate.getTime();
|
||||
}
|
||||
}
|
||||
if (this.startTimeInput && this.startTimeInput.value && this.endTimeInput && this.endTimeInput.value) {
|
||||
var startTime = this.settings.parseTime(this.startTimeInput);
|
||||
var endTime = this.settings.parseTime(this.endTimeInput);
|
||||
if (startTime && endTime) {
|
||||
this.timeDelta = endTime.getTime() - startTime.getTime();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
remove: function()
|
||||
{
|
||||
this._unbindChangeHandler();
|
||||
},
|
||||
|
||||
_bindChangeHandler: function(){
|
||||
// addEventListener doesn't work with synthetic "change" events
|
||||
// fired by jQuery's trigger() functioin. If jQuery is present,
|
||||
// use that for event binding
|
||||
if (jq) {
|
||||
jq(this.container).on('change.datepair', jq.proxy(this.handleEvent, this));
|
||||
} else {
|
||||
this.container.addEventListener('change', this, false);
|
||||
}
|
||||
},
|
||||
|
||||
_unbindChangeHandler: function(){
|
||||
if (jq) {
|
||||
jq(this.container).off('change.datepair');
|
||||
} else {
|
||||
this.container.removeEventListener('change', this, false);
|
||||
}
|
||||
},
|
||||
|
||||
// This function will be called when passing 'this' to addEventListener
|
||||
handleEvent: function(e){
|
||||
// temporarily unbind the change handler to prevent triggering this
|
||||
// if we update other inputs
|
||||
this._unbindChangeHandler();
|
||||
|
||||
if (hasClass(e.target, this.settings.dateClass)) {
|
||||
if (e.target.value != '') {
|
||||
this._dateChanged(e.target);
|
||||
this._timeChanged(e.target);
|
||||
} else {
|
||||
this.dateDelta = null;
|
||||
}
|
||||
|
||||
} else if (hasClass(e.target, this.settings.timeClass)) {
|
||||
if (e.target.value != '') {
|
||||
this._timeChanged(e.target);
|
||||
} else {
|
||||
this.timeDelta = null;
|
||||
}
|
||||
}
|
||||
|
||||
this._validateRanges();
|
||||
this._updateEndMintime();
|
||||
this._bindChangeHandler();
|
||||
},
|
||||
|
||||
_dateChanged: function(target){
|
||||
if (!this.startDateInput || !this.endDateInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
var startDate = this.settings.parseDate(this.startDateInput);
|
||||
var endDate = this.settings.parseDate(this.endDateInput);
|
||||
|
||||
if (!startDate || !endDate) {
|
||||
if (this.settings.defaultDateDelta !== null) {
|
||||
if (startDate) {
|
||||
var newEnd = new Date(startDate.getTime() + this.settings.defaultDateDelta * _ONE_DAY);
|
||||
this.settings.updateDate(this.endDateInput, newEnd);
|
||||
|
||||
} else if (endDate) {
|
||||
var newStart = new Date(endDate.getTime() - this.settings.defaultDateDelta * _ONE_DAY);
|
||||
this.settings.updateDate(this.startDateInput, newStart);
|
||||
}
|
||||
|
||||
this.dateDelta = this.settings.defaultDateDelta * _ONE_DAY;
|
||||
} else {
|
||||
this.dateDelta = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.settings.anchor == 'start' && hasClass(target, this.settings.startClass)) {
|
||||
var newDate = new Date(startDate.getTime() + this.dateDelta);
|
||||
this.settings.updateDate(this.endDateInput, newDate);
|
||||
} else if (this.settings.anchor == 'end' && hasClass(target, this.settings.endClass)) {
|
||||
var newDate = new Date(endDate.getTime() - this.dateDelta);
|
||||
this.settings.updateDate(this.startDateInput, newDate);
|
||||
} else {
|
||||
if (endDate < startDate) {
|
||||
var otherInput = hasClass(target, this.settings.startClass) ? this.endDateInput : this.startDateInput;
|
||||
var selectedDate = this.settings.parseDate(target);
|
||||
this.dateDelta = 0;
|
||||
this.settings.updateDate(otherInput, selectedDate);
|
||||
} else {
|
||||
this.dateDelta = endDate.getTime() - startDate.getTime();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_timeChanged: function(target){
|
||||
if (!this.startTimeInput || !this.endTimeInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
var startTime = this.settings.parseTime(this.startTimeInput);
|
||||
var endTime = this.settings.parseTime(this.endTimeInput);
|
||||
|
||||
if (!startTime || !endTime) {
|
||||
if (this.settings.defaultTimeDelta !== null) {
|
||||
if (startTime) {
|
||||
var newEnd = new Date(startTime.getTime() + this.settings.defaultTimeDelta);
|
||||
this.settings.updateTime(this.endTimeInput, newEnd);
|
||||
} else if (endTime) {
|
||||
var newStart = new Date(endTime.getTime() - this.settings.defaultTimeDelta);
|
||||
this.settings.updateTime(this.startTimeInput, newStart);
|
||||
}
|
||||
|
||||
this.timeDelta = this.settings.defaultTimeDelta;
|
||||
} else {
|
||||
this.timeDelta = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.settings.anchor == 'start' && hasClass(target, this.settings.startClass)) {
|
||||
var newTime = new Date(startTime.getTime() + this.timeDelta);
|
||||
this.settings.updateTime(this.endTimeInput, newTime);
|
||||
endTime = this.settings.parseTime(this.endTimeInput);
|
||||
} else if (this.settings.anchor == 'end' && hasClass(target, this.settings.endClass)) {
|
||||
var newTime = new Date(endTime.getTime() - this.timeDelta);
|
||||
this.settings.updateTime(this.startTimeInput, newTime);
|
||||
startTime = this.settings.parseTime(this.startTimeInput);
|
||||
} else {
|
||||
var startDate = this.settings.parseDate(this.startDateInput);
|
||||
var endDate = this.settings.parseDate(this.endDateInput);
|
||||
if ((+startDate == +endDate) && (endTime < startTime)) {
|
||||
var thisInput = hasClass(target, this.settings.endClass) ? this.endTimeInput : this.startTimeInput;
|
||||
var otherInput = hasClass(target, this.settings.startClass) ? this.endTimeInput : this.startTimeInput;
|
||||
var selectedTime = this.settings.parseTime(thisInput);
|
||||
this.timeDelta = 0;
|
||||
this.settings.updateTime(otherInput, selectedTime);
|
||||
} else {
|
||||
this.timeDelta = endTime.getTime() - startTime.getTime();
|
||||
}
|
||||
}
|
||||
|
||||
var newDelta = endTime.getTime() - startTime.getTime();
|
||||
var offset = (endTime < startTime) ? _ONE_DAY : -1 * _ONE_DAY;
|
||||
|
||||
if (this.dateDelta !== null
|
||||
&& this.dateDelta + this.timeDelta <= _ONE_DAY
|
||||
&& this.dateDelta + newDelta != 0
|
||||
&& (offset > 0 || this.dateDelta != 0)
|
||||
&& ((newDelta >= 0 && this.timeDelta < 0) || (newDelta < 0 && this.timeDelta >= 0))) {
|
||||
|
||||
if (this.settings.anchor == 'start') {
|
||||
var endDate = this.settings.parseDate(this.endDateInput);
|
||||
this.settings.updateDate(this.endDateInput, new Date(endDate.getTime() + offset));
|
||||
this._dateChanged(this.endDateInput);
|
||||
} else if (this.settings.anchor == 'end') {
|
||||
var startDate = this.settings.parseDate(this.startDateInput);
|
||||
this.settings.updateDate(this.startDateInput, new Date(startDate.getTime() - offset));
|
||||
this._dateChanged(this.startDateInput);
|
||||
}
|
||||
}
|
||||
this.timeDelta = newDelta;
|
||||
},
|
||||
|
||||
_updateEndMintime: function(){
|
||||
if (typeof this.settings.setMinTime != 'function') return;
|
||||
|
||||
var baseTime = null;
|
||||
if (this.settings.anchor == 'start' && (!this.dateDelta || this.dateDelta < _ONE_DAY || (this.timeDelta && this.dateDelta + this.timeDelta < _ONE_DAY))) {
|
||||
baseTime = this.settings.parseTime(this.startTimeInput);
|
||||
}
|
||||
|
||||
this.settings.setMinTime(this.endTimeInput, baseTime);
|
||||
},
|
||||
|
||||
_validateRanges: function(){
|
||||
if (this.startTimeInput && this.endTimeInput && this.timeDelta === null) {
|
||||
triggerSimpleCustomEvent(this.container, 'rangeIncomplete');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.startDateInput && this.endDateInput && this.dateDelta === null) {
|
||||
triggerSimpleCustomEvent(this.container, 'rangeIncomplete');
|
||||
return;
|
||||
}
|
||||
|
||||
// due to the fact that times can wrap around, any time-only pair will be considered valid
|
||||
if (!this.startDateInput || !this.endDateInput || this.dateDelta + this.timeDelta >= 0) {
|
||||
triggerSimpleCustomEvent(this.container, 'rangeSelected');
|
||||
} else {
|
||||
triggerSimpleCustomEvent(this.container, 'rangeError');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.Datepair = Datepair;
|
||||
|
||||
}(window, document));
|
||||
7
web/Scripts/datepair.min.js
vendored
Normal file
7
web/Scripts/datepair.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
web/Scripts/jquery-1.11.3.min.js
vendored
Normal file
5
web/Scripts/jquery-1.11.3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
web/Scripts/jquery-ui-1.11.4.js
vendored
1
web/Scripts/jquery-ui-1.11.4.js
vendored
|
|
@ -4555,6 +4555,7 @@ $.extend(Datepicker.prototype, {
|
|||
_updateDatepicker: function(inst) {
|
||||
this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
|
||||
datepicker_instActive = inst; // for delegate hover events
|
||||
if (!inst.dpDiv) return;
|
||||
inst.dpDiv.empty().append(this._generateHTML(inst));
|
||||
this._attachHandlers(inst);
|
||||
|
||||
|
|
|
|||
46
web/Scripts/jquery.datepair.js
Normal file
46
web/Scripts/jquery.datepair.js
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*!
|
||||
* datepair.js v0.4.11 - A javascript plugin for intelligently selecting date and time ranges inspired by Google Calendar.
|
||||
* Copyright (c) 2015 Jon Thornton - http://jonthornton.github.com/Datepair.js
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
if(!$) {
|
||||
return;
|
||||
}
|
||||
|
||||
////////////
|
||||
// Plugin //
|
||||
////////////
|
||||
|
||||
$.fn.datepair = function(option) {
|
||||
var out;
|
||||
this.each(function() {
|
||||
var $this = $(this);
|
||||
var data = $this.data('datepair');
|
||||
var options = typeof option === 'object' && option;
|
||||
|
||||
if (!data) {
|
||||
data = new Datepair(this, options);
|
||||
$this.data('datepair', data);
|
||||
}
|
||||
|
||||
if (typeof option === 'string') {
|
||||
out = data[option]();
|
||||
}
|
||||
});
|
||||
|
||||
return out || this;
|
||||
};
|
||||
|
||||
//////////////
|
||||
// Data API //
|
||||
//////////////
|
||||
|
||||
$('[data-datepair]').each(function() {
|
||||
var $this = $(this);
|
||||
$this.datepair($this.data());
|
||||
});
|
||||
|
||||
}(window.Zepto || window.jQuery));
|
||||
7
web/Scripts/jquery.datepair.min.js
vendored
Normal file
7
web/Scripts/jquery.datepair.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,9 +1,8 @@
|
|||
/************************
|
||||
jquery-timepicker v1.4.13
|
||||
http://jonthornton.github.com/jquery-timepicker/
|
||||
|
||||
requires jQuery 1.7+
|
||||
************************/
|
||||
/*!
|
||||
* jquery-timepicker v1.8.3 - A jQuery timepicker plugin inspired by Google Calendar. It supports both mouse and keyboard navigation.
|
||||
* Copyright (c) 2015 Jon Thornton - http://jonthornton.github.com/jquery-timepicker/
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
|
||||
(function (factory) {
|
||||
|
|
@ -32,8 +31,7 @@ requires jQuery 1.7+
|
|||
hrs: 'hrs'
|
||||
};
|
||||
|
||||
var methods =
|
||||
{
|
||||
var methods = {
|
||||
init: function(options)
|
||||
{
|
||||
return this.each(function()
|
||||
|
|
@ -62,10 +60,17 @@ requires jQuery 1.7+
|
|||
_render(self);
|
||||
} else {
|
||||
self.prop('autocomplete', 'off');
|
||||
self.on('click.timepicker focus.timepicker', methods.show);
|
||||
if (settings.showOn) {
|
||||
for (i in settings.showOn) {
|
||||
self.on(settings.showOn[i]+'.timepicker', methods.show);
|
||||
}
|
||||
}
|
||||
self.on('change.timepicker', _formatValue);
|
||||
self.on('keydown.timepicker', _keydownhandler);
|
||||
self.on('keyup.timepicker', _keyuphandler);
|
||||
if (settings.disableTextInput) {
|
||||
self.on('keypress.timepicker', function(e) { e.preventDefault(); });
|
||||
}
|
||||
|
||||
_formatValue.call(self.get(0));
|
||||
}
|
||||
|
|
@ -78,10 +83,6 @@ requires jQuery 1.7+
|
|||
var settings = self.data('timepicker-settings');
|
||||
|
||||
if (e) {
|
||||
if (!settings.showOnFocus) {
|
||||
return true;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +113,9 @@ requires jQuery 1.7+
|
|||
return;
|
||||
}
|
||||
|
||||
self.data('ui-timepicker-value', self.val());
|
||||
_setSelected(self, list);
|
||||
|
||||
// make sure other pickers are hidden
|
||||
methods.hide();
|
||||
|
||||
|
|
@ -119,7 +123,7 @@ requires jQuery 1.7+
|
|||
list.show();
|
||||
var listOffset = {};
|
||||
|
||||
if (settings.orientation == 'rtl') {
|
||||
if (settings.orientation.match(/r/)) {
|
||||
// right-align the dropdown
|
||||
listOffset.left = self.offset().left + self.outerWidth() - list.outerWidth() + parseInt(list.css('marginLeft').replace('px', ''), 10);
|
||||
} else {
|
||||
|
|
@ -127,7 +131,18 @@ requires jQuery 1.7+
|
|||
listOffset.left = self.offset().left + parseInt(list.css('marginLeft').replace('px', ''), 10);
|
||||
}
|
||||
|
||||
if ((self.offset().top + self.outerHeight(true) + list.outerHeight()) > $(window).height() + $(window).scrollTop()) {
|
||||
var verticalOrientation;
|
||||
if (settings.orientation.match(/t/)) {
|
||||
verticalOrientation = 't';
|
||||
} else if (settings.orientation.match(/b/)) {
|
||||
verticalOrientation = 'b';
|
||||
} else if ((self.offset().top + self.outerHeight(true) + list.outerHeight()) > $(window).height() + $(window).scrollTop()) {
|
||||
verticalOrientation = 't';
|
||||
} else {
|
||||
verticalOrientation = 'b';
|
||||
}
|
||||
|
||||
if (verticalOrientation == 't') {
|
||||
// position the dropdown on top
|
||||
list.addClass('ui-timepicker-positioned-top');
|
||||
listOffset.top = self.offset().top - list.outerHeight() + parseInt(list.css('marginTop').replace('px', ''), 10);
|
||||
|
|
@ -143,10 +158,11 @@ requires jQuery 1.7+
|
|||
var selected = list.find('.ui-timepicker-selected');
|
||||
|
||||
if (!selected.length) {
|
||||
if (_getTimeValue(self)) {
|
||||
selected = _findRow(self, list, _time2int(_getTimeValue(self)));
|
||||
var timeInt = _time2int(_getTimeValue(self));
|
||||
if (timeInt !== null) {
|
||||
selected = _findRow(self, list, timeInt);
|
||||
} else if (settings.scrollDefault) {
|
||||
selected = _findRow(self, list, settings.scrollDefault);
|
||||
selected = _findRow(self, list, settings.scrollDefault());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -157,8 +173,18 @@ requires jQuery 1.7+
|
|||
list.scrollTop(0);
|
||||
}
|
||||
|
||||
// prevent scroll propagation
|
||||
if(settings.stopScrollPropagation) {
|
||||
$(document).on('wheel.ui-timepicker', '.ui-timepicker-wrapper', function(e){
|
||||
e.preventDefault();
|
||||
var currentScroll = $(this).scrollTop();
|
||||
$(this).scrollTop(currentScroll + e.originalEvent.deltaY);
|
||||
});
|
||||
}
|
||||
|
||||
// attach close handlers
|
||||
$(document).on('touchstart.ui-timepicker mousedown.ui-timepicker', _closeHandler);
|
||||
$(window).on('resize.ui-timepicker', _closeHandler);
|
||||
if (settings.closeOnWindowScroll) {
|
||||
$(document).on('scroll.ui-timepicker', _closeHandler);
|
||||
}
|
||||
|
|
@ -243,10 +269,14 @@ requires jQuery 1.7+
|
|||
return null;
|
||||
}
|
||||
|
||||
var offset = _time2int(time_string);
|
||||
if (offset === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!relative_date) {
|
||||
relative_date = new Date();
|
||||
}
|
||||
var offset = _time2int(time_string);
|
||||
|
||||
// construct a Date with today's date, and offset's time
|
||||
var time = new Date(relative_date);
|
||||
|
|
@ -264,9 +294,13 @@ requires jQuery 1.7+
|
|||
var settings = self.data('timepicker-settings');
|
||||
|
||||
if (settings.forceRoundTime) {
|
||||
var prettyTime = _roundAndFormatTime(value, settings)
|
||||
var prettyTime = _roundAndFormatTime(_time2int(value), settings)
|
||||
} else {
|
||||
var prettyTime = _int2time(_time2int(value), settings.timeFormat);
|
||||
var prettyTime = _int2time(_time2int(value), settings);
|
||||
}
|
||||
|
||||
if (value && prettyTime === null && settings.noneOption) {
|
||||
prettyTime = value;
|
||||
}
|
||||
|
||||
_setTimeValue(self, prettyTime);
|
||||
|
|
@ -330,21 +364,28 @@ requires jQuery 1.7+
|
|||
}
|
||||
|
||||
if (settings.scrollDefault == 'now') {
|
||||
settings.scrollDefault = _time2int(new Date());
|
||||
} else if (settings.scrollDefault) {
|
||||
settings.scrollDefault = _time2int(settings.scrollDefault);
|
||||
settings.scrollDefault = function() {
|
||||
return settings.roundingFunction(_time2int(new Date()), settings);
|
||||
}
|
||||
} else if (settings.scrollDefault && typeof settings.scrollDefault != 'function') {
|
||||
var val = settings.scrollDefault;
|
||||
settings.scrollDefault = function() {
|
||||
return settings.roundingFunction(_time2int(val), settings);
|
||||
}
|
||||
} else if (settings.minTime) {
|
||||
settings.scrollDefault = settings.minTime;
|
||||
}
|
||||
|
||||
if (settings.scrollDefault) {
|
||||
settings.scrollDefault = _roundTime(settings.scrollDefault, settings);
|
||||
settings.scrollDefault = function() {
|
||||
return settings.roundingFunction(settings.minTime, settings);
|
||||
}
|
||||
}
|
||||
|
||||
if ($.type(settings.timeFormat) === "string" && settings.timeFormat.match(/[gh]/)) {
|
||||
settings._twelveHourTime = true;
|
||||
}
|
||||
|
||||
if (settings.showOnFocus === false && settings.showOn.indexOf('focus') != -1) {
|
||||
settings.showOn.splice(settings.showOn.indexOf('focus'), 1);
|
||||
}
|
||||
|
||||
if (settings.disableTimeRanges.length > 0) {
|
||||
// convert string times to integers
|
||||
for (var i in settings.disableTimeRanges) {
|
||||
|
|
@ -417,6 +458,7 @@ requires jQuery 1.7+
|
|||
}
|
||||
|
||||
if ((settings.minTime !== null || settings.durationTime !== null) && settings.showDuration) {
|
||||
var stepval = typeof settings.step == 'function' ? 'function' : settings.step;
|
||||
wrapped_list.addClass('ui-timepicker-with-duration');
|
||||
wrapped_list.addClass('ui-timepicker-step-'+settings.step);
|
||||
}
|
||||
|
|
@ -430,12 +472,12 @@ requires jQuery 1.7+
|
|||
var start = (settings.minTime !== null) ? settings.minTime : 0;
|
||||
var end = (settings.maxTime !== null) ? settings.maxTime : (start + _ONE_DAY - 1);
|
||||
|
||||
if (end <= start) {
|
||||
if (end < start) {
|
||||
// make sure the end time is greater than start time, otherwise there will be no list to show
|
||||
end += _ONE_DAY;
|
||||
}
|
||||
|
||||
if (end === _ONE_DAY-1 && $.type(settings.timeFormat) === "string" && settings.timeFormat.indexOf('H') !== -1) {
|
||||
if (end === _ONE_DAY-1 && $.type(settings.timeFormat) === "string" && settings.show2400) {
|
||||
// show a 24:00 option when using military time
|
||||
end = _ONE_DAY;
|
||||
}
|
||||
|
|
@ -444,9 +486,16 @@ requires jQuery 1.7+
|
|||
var drCur = 0;
|
||||
var drLen = dr.length;
|
||||
|
||||
for (var i=start; i <= end; i += settings.step*60) {
|
||||
var stepFunc = settings.step;
|
||||
if (typeof stepFunc != 'function') {
|
||||
stepFunc = function() {
|
||||
return settings.step;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i=start, j=0; i <= end; j++, i += stepFunc(j)*60) {
|
||||
var timeInt = i;
|
||||
var timeString = _int2time(timeInt, settings.timeFormat);
|
||||
var timeString = _int2time(timeInt, settings);
|
||||
|
||||
if (settings.useSelect) {
|
||||
var row = $('<option />', { 'value': timeString });
|
||||
|
|
@ -490,7 +539,7 @@ requires jQuery 1.7+
|
|||
|
||||
if (settings.useSelect) {
|
||||
if (self.val()) {
|
||||
list.val(_roundAndFormatTime(self.val(), settings));
|
||||
list.val(_roundAndFormatTime(_time2int(self.val()), settings));
|
||||
}
|
||||
|
||||
list.on('focus', function(){
|
||||
|
|
@ -503,7 +552,7 @@ requires jQuery 1.7+
|
|||
_setTimeValue(self, $(this).val(), 'select');
|
||||
});
|
||||
|
||||
_setTimeValue(self, list.val());
|
||||
_setTimeValue(self, list.val(), 'initial');
|
||||
self.hide().after(list);
|
||||
} else {
|
||||
var appendTo = settings.appendTo;
|
||||
|
|
@ -536,7 +585,11 @@ requires jQuery 1.7+
|
|||
|
||||
if (_selectValue(self)) {
|
||||
self.trigger('hideTimepicker');
|
||||
wrapped_list.hide();
|
||||
|
||||
list.on('mouseup.timepicker', 'li', function(e) {
|
||||
list.off('mouseup.timepicker');
|
||||
wrapped_list.hide();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -570,34 +623,11 @@ requires jQuery 1.7+
|
|||
}
|
||||
}
|
||||
|
||||
function _roundTime(seconds, settings)
|
||||
{
|
||||
if (!$.isNumeric(seconds)) {
|
||||
seconds = _time2int(seconds);
|
||||
}
|
||||
|
||||
if (seconds === null) {
|
||||
return null;
|
||||
} else {
|
||||
var offset = seconds % (settings.step*60); // step is in minutes
|
||||
|
||||
if (offset >= settings.step*30) {
|
||||
// if offset is larger than a half step, round up
|
||||
seconds += (settings.step*60) - offset;
|
||||
} else {
|
||||
// round down
|
||||
seconds -= offset;
|
||||
}
|
||||
|
||||
return seconds;
|
||||
}
|
||||
}
|
||||
|
||||
function _roundAndFormatTime(seconds, settings)
|
||||
{
|
||||
seconds = _roundTime(seconds, settings);
|
||||
seconds = settings.roundingFunction(seconds, settings);
|
||||
if (seconds !== null) {
|
||||
return _int2time(seconds, settings.timeFormat);
|
||||
return _int2time(seconds, settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -614,6 +644,7 @@ requires jQuery 1.7+
|
|||
if (input.length === 0 && target.closest('.ui-timepicker-wrapper').length === 0) {
|
||||
methods.hide();
|
||||
$(document).unbind('.ui-timepicker');
|
||||
$(window).unbind('.ui-timepicker');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -631,7 +662,7 @@ requires jQuery 1.7+
|
|||
|
||||
var settings = self.data('timepicker-settings');
|
||||
var out = false;
|
||||
var halfStep = settings.step*30;
|
||||
var value = settings.roundingFunction(value, settings);
|
||||
|
||||
// loop through the menu items
|
||||
list.find('li').each(function(i, obj) {
|
||||
|
|
@ -640,10 +671,7 @@ requires jQuery 1.7+
|
|||
return;
|
||||
}
|
||||
|
||||
var offset = jObj.data('time') - value;
|
||||
|
||||
// check if the value is less than half a step from each row
|
||||
if (Math.abs(offset) < halfStep || offset == halfStep) {
|
||||
if (jObj.data('time') == value) {
|
||||
out = jObj;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -682,20 +710,19 @@ requires jQuery 1.7+
|
|||
}
|
||||
|
||||
var self = $(this);
|
||||
var list = self.data('timepicker-list');
|
||||
|
||||
if (self.is(':focus') && (!e || e.type != 'change')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var seconds = _time2int(this.value);
|
||||
var settings = self.data('timepicker-settings');
|
||||
var seconds = _time2int(this.value, settings);
|
||||
|
||||
if (seconds === null) {
|
||||
self.trigger('timeFormatError');
|
||||
return;
|
||||
}
|
||||
|
||||
var settings = self.data('timepicker-settings');
|
||||
var rangeError = false;
|
||||
// check that the time in within bounds
|
||||
if (settings.minTime !== null && seconds < settings.minTime) {
|
||||
|
|
@ -713,18 +740,10 @@ requires jQuery 1.7+
|
|||
});
|
||||
|
||||
if (settings.forceRoundTime) {
|
||||
var offset = seconds % (settings.step*60); // step is in minutes
|
||||
|
||||
if (offset >= settings.step*30) {
|
||||
// if offset is larger than a half step, round up
|
||||
seconds += (settings.step*60) - offset;
|
||||
} else {
|
||||
// round down
|
||||
seconds -= offset;
|
||||
}
|
||||
seconds = settings.roundingFunction(seconds, settings);
|
||||
}
|
||||
|
||||
var prettyTime = _int2time(seconds, settings.timeFormat);
|
||||
var prettyTime = _int2time(seconds, settings);
|
||||
|
||||
if (rangeError) {
|
||||
if (_setTimeValue(self, prettyTime, 'error')) {
|
||||
|
|
@ -751,8 +770,8 @@ requires jQuery 1.7+
|
|||
self.val(value);
|
||||
|
||||
var settings = self.data('timepicker-settings');
|
||||
if (settings.useSelect && source != 'select') {
|
||||
self.data('timepicker-list').val(_roundAndFormatTime(value, settings));
|
||||
if (settings.useSelect && source != 'select' && source != 'initial') {
|
||||
self.data('timepicker-list').val(_roundAndFormatTime(_time2int(value), settings));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -869,13 +888,9 @@ requires jQuery 1.7+
|
|||
{
|
||||
var self = $(this);
|
||||
var list = self.data('timepicker-list');
|
||||
var settings = self.data('timepicker-settings');
|
||||
|
||||
if (!list || !_isVisible(list)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!self.data('timepicker-settings').typeaheadHighlight) {
|
||||
list.find('li').removeClass('ui-timepicker-selected');
|
||||
if (!list || !_isVisible(list) || settings.disableTextInput) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -907,12 +922,12 @@ requires jQuery 1.7+
|
|||
case 186: // colon
|
||||
case 8: // backspace
|
||||
case 46: // delete
|
||||
_setSelected(self, list);
|
||||
if (settings.typeaheadHighlight) {
|
||||
_setSelected(self, list);
|
||||
} else {
|
||||
list.hide();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// list.find('li').removeClass('ui-timepicker-selected');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -934,13 +949,11 @@ requires jQuery 1.7+
|
|||
}
|
||||
|
||||
if (timeValue !== null) {
|
||||
if (typeof timeValue == 'string') {
|
||||
self.val(timeValue);
|
||||
self.trigger('selectTime').trigger('changeTime').trigger('change', 'timepicker');
|
||||
} else {
|
||||
var timeString = _int2time(timeValue, settings.timeFormat);
|
||||
_setTimeValue(self, timeString, 'select');
|
||||
if (typeof timeValue != 'string') {
|
||||
timeValue = _int2time(timeValue, settings);
|
||||
}
|
||||
|
||||
_setTimeValue(self, timeValue, 'select');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -979,27 +992,27 @@ requires jQuery 1.7+
|
|||
return duration.join(' ');
|
||||
}
|
||||
|
||||
function _int2time(seconds, format)
|
||||
function _int2time(seconds, settings)
|
||||
{
|
||||
if (seconds === null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
var time = new Date(_baseDate.valueOf() + (seconds*1000));
|
||||
|
||||
if (isNaN(time.getTime())) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($.type(format) === "function") {
|
||||
return format(time);
|
||||
if ($.type(settings.timeFormat) === "function") {
|
||||
return settings.timeFormat(time);
|
||||
}
|
||||
|
||||
var output = '';
|
||||
var hour, code;
|
||||
for (var i=0; i<format.length; i++) {
|
||||
for (var i=0; i<settings.timeFormat.length; i++) {
|
||||
|
||||
code = format.charAt(i);
|
||||
code = settings.timeFormat.charAt(i);
|
||||
switch (code) {
|
||||
|
||||
case 'a':
|
||||
|
|
@ -1007,7 +1020,7 @@ requires jQuery 1.7+
|
|||
break;
|
||||
|
||||
case 'A':
|
||||
output += (time.getHours() > 11) ? _lang.pm.toUpperCase() : _lang.am.toUpperCase();
|
||||
output += (time.getHours() > 11) ? _lang.PM : _lang.AM;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
|
|
@ -1016,7 +1029,9 @@ requires jQuery 1.7+
|
|||
break;
|
||||
|
||||
case 'G':
|
||||
output += time.getHours();
|
||||
hour = time.getHours();
|
||||
if (seconds === _ONE_DAY) hour = 24;
|
||||
output += hour;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
|
|
@ -1048,7 +1063,7 @@ requires jQuery 1.7+
|
|||
case '\\':
|
||||
// escape character; add the next character and skip ahead
|
||||
i++;
|
||||
output += format.charAt(i);
|
||||
output += settings.timeFormat.charAt(i);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1068,45 +1083,54 @@ requires jQuery 1.7+
|
|||
return timeString.getHours()*3600 + timeString.getMinutes()*60 + timeString.getSeconds();
|
||||
}
|
||||
|
||||
timeString = timeString.toLowerCase();
|
||||
timeString = timeString.toLowerCase().replace(/[\s\.]/g, '');
|
||||
|
||||
// if the last character is an "a" or "p", add the "m"
|
||||
if (timeString.slice(-1) == 'a' || timeString.slice(-1) == 'p') {
|
||||
timeString += 'm';
|
||||
}
|
||||
|
||||
var ampmRegex = '(' +
|
||||
_lang.am.replace('.', '')+'|' +
|
||||
_lang.pm.replace('.', '')+'|' +
|
||||
_lang.AM.replace('.', '')+'|' +
|
||||
_lang.PM.replace('.', '')+')?';
|
||||
|
||||
// try to parse time input
|
||||
var pattern = new RegExp('^([0-2]?[0-9])\\W?([0-5][0-9])?\\W?([0-5][0-9])?\\s*('+_lang.am+'|'+_lang.pm+')?$');
|
||||
var pattern = new RegExp('^'+ampmRegex+'([0-2]?[0-9])\\W?([0-5][0-9])?\\W?([0-5][0-9])?'+ampmRegex+'$');
|
||||
|
||||
var time = timeString.match(pattern);
|
||||
if (!time) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var hour = parseInt(time[1]*1, 10);
|
||||
var ampm = time[4];
|
||||
var hour = parseInt(time[2]*1, 10);
|
||||
var ampm = time[1] || time[5];
|
||||
var hours = hour;
|
||||
|
||||
if (hour <= 12 && ampm) {
|
||||
var isPm = (ampm == _lang.pm || ampm == _lang.PM);
|
||||
|
||||
if (hour == 12) {
|
||||
hours = (time[4] == _lang.pm) ? 12 : 0;
|
||||
hours = isPm ? 12 : 0;
|
||||
} else {
|
||||
hours = (hour + (time[4] == _lang.pm ? 12 : 0));
|
||||
hours = (hour + (isPm ? 12 : 0));
|
||||
}
|
||||
}
|
||||
|
||||
var minutes = ( time[2]*1 || 0 );
|
||||
var seconds = ( time[3]*1 || 0 );
|
||||
var minutes = ( time[3]*1 || 0 );
|
||||
var seconds = ( time[4]*1 || 0 );
|
||||
var timeInt = hours*3600 + minutes*60 + seconds;
|
||||
|
||||
// if no am/pm provided, intelligently guess based on the scrollDefault
|
||||
if (!ampm && settings && settings._twelveHourTime && settings.scrollDefault) {
|
||||
var delta = timeInt - settings.scrollDefault;
|
||||
if (hour < 12 && !ampm && settings && settings._twelveHourTime && settings.scrollDefault) {
|
||||
var delta = timeInt - settings.scrollDefault();
|
||||
if (delta < 0 && delta >= _ONE_DAY / -2) {
|
||||
timeInt = (timeInt + (_ONE_DAY / 2)) % _ONE_DAY;
|
||||
}
|
||||
}
|
||||
|
||||
return timeInt
|
||||
return timeInt;
|
||||
}
|
||||
|
||||
function _pad2(n) {
|
||||
|
|
@ -1129,23 +1153,45 @@ requires jQuery 1.7+
|
|||
};
|
||||
// Global defaults
|
||||
$.fn.timepicker.defaults = {
|
||||
appendTo: 'body',
|
||||
className: null,
|
||||
minTime: null,
|
||||
maxTime: null,
|
||||
closeOnWindowScroll: false,
|
||||
disableTextInput: false,
|
||||
disableTimeRanges: [],
|
||||
disableTouchKeyboard: false,
|
||||
durationTime: null,
|
||||
step: 30,
|
||||
showDuration: false,
|
||||
showOnFocus: true,
|
||||
timeFormat: 'g:ia',
|
||||
forceRoundTime: false,
|
||||
maxTime: null,
|
||||
minTime: null,
|
||||
noneOption: false,
|
||||
orientation: 'l',
|
||||
roundingFunction: function(seconds, settings) {
|
||||
if (seconds === null) {
|
||||
return null;
|
||||
} else {
|
||||
var offset = seconds % (settings.step*60); // step is in minutes
|
||||
|
||||
if (offset >= settings.step*30) {
|
||||
// if offset is larger than a half step, round up
|
||||
seconds += (settings.step*60) - offset;
|
||||
} else {
|
||||
// round down
|
||||
seconds -= offset;
|
||||
}
|
||||
|
||||
return seconds;
|
||||
}
|
||||
},
|
||||
scrollDefault: null,
|
||||
selectOnBlur: false,
|
||||
disableTouchKeyboard: false,
|
||||
forceRoundTime: false,
|
||||
appendTo: 'body',
|
||||
orientation: 'ltr',
|
||||
disableTimeRanges: [],
|
||||
closeOnWindowScroll: false,
|
||||
show2400: false,
|
||||
showDuration: false,
|
||||
showOn: ['click', 'focus'],
|
||||
showOnFocus: true,
|
||||
step: 30,
|
||||
stopScrollPropagation: false,
|
||||
timeFormat: 'g:ia',
|
||||
typeaheadHighlight: true,
|
||||
noneOption: false
|
||||
useSelect: false
|
||||
};
|
||||
}));
|
||||
|
|
|
|||
8
web/Scripts/jquery.timepicker.min.js
vendored
8
web/Scripts/jquery.timepicker.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue