';
for (var h = o.hourMin; h <= hourMax; h += parseInt(o.hourGrid,10)) {
hourGridSize++;
var tmph = (o.ampm && h > 12) ? h-12 : h;
if (tmph < 10) tmph = '0' + tmph;
if (o.ampm) {
if (h == 0) tmph = 12 +'a';
else if (h < 12) tmph += 'a';
else tmph += 'p';
}
html += '
' + tmph + '
';
}
html += '
';
}
html += '
';
// Minutes
html += '
' + o.minuteText + '
'+
'
';
if (o.showMinute && o.minuteGrid > 0) {
html += '
';
for (var m = o.minuteMin; m <= minMax; m += parseInt(o.minuteGrid,10)) {
minuteGridSize++;
html += '
' + ((m < 10) ? '0' : '') + m + '
';
}
html += '
';
}
html += '
';
// Seconds
html += '
' + o.secondText + '
'+
'
';
if (o.showSecond && o.secondGrid > 0) {
html += '
';
for (var s = o.secondMin; s <= secMax; s += parseInt(o.secondGrid,10)) {
secondGridSize++;
html += '
' + ((s < 10) ? '0' : '') + s + '
';
}
html += '
';
}
html += '
';
// Milliseconds
html += '
' + o.millisecText + '
'+
'
';
if (o.showMillisec && o.millisecGrid > 0) {
html += '
';
for (var l = o.millisecMin; l <= millisecMax; l += parseInt(o.millisecGrid,10)) {
millisecGridSize++;
html += '
' + ((l < 10) ? '0' : '') + l + '
';
}
html += '
';
}
html += '
';
// Timezone
html += '
' + o.timezoneText + '
';
html += '';
html += '
';
$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();
}
this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({
orientation: "horizontal",
value: this.hour,
min: o.hourMin,
max: hourMax,
step: o.stepHour,
slide: function(event, ui) {
tp_inst.hour_slider.slider( "option", "value", ui.value);
tp_inst._onTimeChange();
}
});
// Updated by Peter Medeiros:
// - Pass in Event and UI instance into slide function
this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({
orientation: "horizontal",
value: this.minute,
min: o.minuteMin,
max: minMax,
step: o.stepMinute,
slide: function(event, ui) {
tp_inst.minute_slider.slider( "option", "value", ui.value);
tp_inst._onTimeChange();
}
});
this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({
orientation: "horizontal",
value: this.second,
min: o.secondMin,
max: secMax,
step: o.stepSecond,
slide: function(event, ui) {
tp_inst.second_slider.slider( "option", "value", ui.value);
tp_inst._onTimeChange();
}
});
this.millisec_slider = $tp.find('#ui_tpicker_millisec_'+ dp_id).slider({
orientation: "horizontal",
value: this.millisec,
min: o.millisecMin,
max: millisecMax,
step: o.stepMillisec,
slide: function(event, ui) {
tp_inst.millisec_slider.slider( "option", "value", ui.value);
tp_inst._onTimeChange();
}
});
this.timezone_select = $tp.find('#ui_tpicker_timezone_'+ dp_id).append('').find("select");
$.fn.append.apply(this.timezone_select,
$.map(o.timezoneList, function(val, idx) {
return $("")
.val(typeof val == "object" ? val.value : val)
.text(typeof val == "object" ? val.label : val);
})
);
this.timezone_select.val((typeof this.timezone != "undefined" && this.timezone != null && this.timezone != "") ? this.timezone : o.timezone);
this.timezone_select.change(function() {
tp_inst._onTimeChange();
});
// Add grid functionality
if (o.showHour && o.hourGrid > 0) {
size = 100 * hourGridSize * o.hourGrid / (hourMax - o.hourMin);
$tp.find(".ui_tpicker_hour table").css({
width: size + "%",
marginLeft: (size / (-2 * hourGridSize)) + "%",
borderCollapse: 'collapse'
}).find("td").each( function(index) {
$(this).click(function() {
var h = $(this).html();
if(o.ampm) {
var ap = h.substring(2).toLowerCase(),
aph = parseInt(h.substring(0,2), 10);
if (ap == 'a') {
if (aph == 12) h = 0;
else h = aph;
} else if (aph == 12) h = 12;
else h = aph + 12;
}
tp_inst.hour_slider.slider("option", "value", h);
tp_inst._onTimeChange();
tp_inst._onSelectHandler();
}).css({
cursor: 'pointer',
width: (100 / hourGridSize) + '%',
textAlign: 'center',
overflow: 'hidden'
});
});
}
if (o.showMinute && o.minuteGrid > 0) {
size = 100 * minuteGridSize * o.minuteGrid / (minMax - o.minuteMin);
$tp.find(".ui_tpicker_minute table").css({
width: size + "%",
marginLeft: (size / (-2 * minuteGridSize)) + "%",
borderCollapse: 'collapse'
}).find("td").each(function(index) {
$(this).click(function() {
tp_inst.minute_slider.slider("option", "value", $(this).html());
tp_inst._onTimeChange();
tp_inst._onSelectHandler();
}).css({
cursor: 'pointer',
width: (100 / minuteGridSize) + '%',
textAlign: 'center',
overflow: 'hidden'
});
});
}
if (o.showSecond && o.secondGrid > 0) {
$tp.find(".ui_tpicker_second table").css({
width: size + "%",
marginLeft: (size / (-2 * secondGridSize)) + "%",
borderCollapse: 'collapse'
}).find("td").each(function(index) {
$(this).click(function() {
tp_inst.second_slider.slider("option", "value", $(this).html());
tp_inst._onTimeChange();
tp_inst._onSelectHandler();
}).css({
cursor: 'pointer',
width: (100 / secondGridSize) + '%',
textAlign: 'center',
overflow: 'hidden'
});
});
}
if (o.showMillisec && o.millisecGrid > 0) {
$tp.find(".ui_tpicker_millisec table").css({
width: size + "%",
marginLeft: (size / (-2 * millisecGridSize)) + "%",
borderCollapse: 'collapse'
}).find("td").each(function(index) {
$(this).click(function() {
tp_inst.millisec_slider.slider("option", "value", $(this).html());
tp_inst._onTimeChange();
tp_inst._onSelectHandler();
}).css({
cursor: 'pointer',
width: (100 / millisecGridSize) + '%',
textAlign: 'center',
overflow: 'hidden'
});
});
}
var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');
if ($buttonPanel.length) $buttonPanel.before($tp);
else $dp.append($tp);
this.$timeObj = $tp.find('#ui_tpicker_time_'+ dp_id);
if (this.inst !== null) {
var timeDefined = this.timeDefined;
this._onTimeChange();
this.timeDefined = timeDefined;
}
//Emulate datepicker onSelect behavior. Call on slidestop.
var onSelectDelegate = function() {
tp_inst._onSelectHandler();
};
this.hour_slider.bind('slidestop',onSelectDelegate);
this.minute_slider.bind('slidestop',onSelectDelegate);
this.second_slider.bind('slidestop',onSelectDelegate);
this.millisec_slider.bind('slidestop',onSelectDelegate);
// slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/
if (this._defaults.addSliderAccess){
var sliderAccessArgs = this._defaults.sliderAccessArgs;
setTimeout(function(){ // fix for inline mode
if($tp.find('.ui-slider-access').length == 0){
$tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);
// fix any grids since sliders are shorter
var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);
if(sliderAccessWidth){
$tp.find('table:visible').each(function(){
var $g = $(this),
oldWidth = $g.outerWidth(),
oldMarginLeft = $g.css('marginLeft').toString().replace('%',''),
newWidth = oldWidth - sliderAccessWidth,
newMarginLeft = ((oldMarginLeft * newWidth)/oldWidth) + '%';
$g.css({width: newWidth, marginLeft: newMarginLeft});
});
}
}
},0);
}
// end slideAccess integration
}
},
//########################################################################
// This function tries to limit the ability to go outside the
// min/max date range
//########################################################################
_limitMinMaxDateTime: function(dp_inst, adjustSliders){
var o = this._defaults,
dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);
if(!this._defaults.showTimepicker) return; // No time so nothing to check here
if($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date){
var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),
minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);
if(this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null){
this.hourMinOriginal = o.hourMin;
this.minuteMinOriginal = o.minuteMin;
this.secondMinOriginal = o.secondMin;
this.millisecMinOriginal = o.millisecMin;
}
if(dp_inst.settings.timeOnly || minDateTimeDate.getTime() == dp_date.getTime()) {
this._defaults.hourMin = minDateTime.getHours();
if (this.hour <= this._defaults.hourMin) {
this.hour = this._defaults.hourMin;
this._defaults.minuteMin = minDateTime.getMinutes();
if (this.minute <= this._defaults.minuteMin) {
this.minute = this._defaults.minuteMin;
this._defaults.secondMin = minDateTime.getSeconds();
} else if (this.second <= this._defaults.secondMin){
this.second = this._defaults.secondMin;
this._defaults.millisecMin = minDateTime.getMilliseconds();
} else {
if(this.millisec < this._defaults.millisecMin)
this.millisec = this._defaults.millisecMin;
this._defaults.millisecMin = this.millisecMinOriginal;
}
} else {
this._defaults.minuteMin = this.minuteMinOriginal;
this._defaults.secondMin = this.secondMinOriginal;
this._defaults.millisecMin = this.millisecMinOriginal;
}
}else{
this._defaults.hourMin = this.hourMinOriginal;
this._defaults.minuteMin = this.minuteMinOriginal;
this._defaults.secondMin = this.secondMinOriginal;
this._defaults.millisecMin = this.millisecMinOriginal;
}
}
if($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date){
var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),
maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);
if(this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null){
this.hourMaxOriginal = o.hourMax;
this.minuteMaxOriginal = o.minuteMax;
this.secondMaxOriginal = o.secondMax;
this.millisecMaxOriginal = o.millisecMax;
}
if(dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()){
this._defaults.hourMax = maxDateTime.getHours();
if (this.hour >= this._defaults.hourMax) {
this.hour = this._defaults.hourMax;
this._defaults.minuteMax = maxDateTime.getMinutes();
if (this.minute >= this._defaults.minuteMax) {
this.minute = this._defaults.minuteMax;
this._defaults.secondMax = maxDateTime.getSeconds();
} else if (this.second >= this._defaults.secondMax) {
this.second = this._defaults.secondMax;
this._defaults.millisecMax = maxDateTime.getMilliseconds();
} else {
if(this.millisec > this._defaults.millisecMax) this.millisec = this._defaults.millisecMax;
this._defaults.millisecMax = this.millisecMaxOriginal;
}
} else {
this._defaults.minuteMax = this.minuteMaxOriginal;
this._defaults.secondMax = this.secondMaxOriginal;
this._defaults.millisecMax = this.millisecMaxOriginal;
}
}else{
this._defaults.hourMax = this.hourMaxOriginal;
this._defaults.minuteMax = this.minuteMaxOriginal;
this._defaults.secondMax = this.secondMaxOriginal;
this._defaults.millisecMax = this.millisecMaxOriginal;
}
}
if(adjustSliders !== undefined && adjustSliders === true){
var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)) ,10),
minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)) ,10),
secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)) ,10),
millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)) ,10);
if(this.hour_slider)
this.hour_slider.slider("option", {min: this._defaults.hourMin, max: hourMax}).slider('value', this.hour);
if(this.minute_slider)
this.minute_slider.slider("option", {min: this._defaults.minuteMin, max: minMax}).slider('value', this.minute);
if(this.second_slider)
this.second_slider.slider("option", {min: this._defaults.secondMin, max: secMax}).slider('value', this.second);
if(this.millisec_slider)
this.millisec_slider.slider("option", {min: this._defaults.millisecMin, max: millisecMax}).slider('value', this.millisec);
}
},
//########################################################################
// when a slider moves, set the internal time...
// on time change is also called when the time is updated in the text field
//########################################################################
_onTimeChange: function() {
var hour = (this.hour_slider) ? this.hour_slider.slider('value') : false,
minute = (this.minute_slider) ? this.minute_slider.slider('value') : false,
second = (this.second_slider) ? this.second_slider.slider('value') : false,
millisec = (this.millisec_slider) ? this.millisec_slider.slider('value') : false,
timezone = (this.timezone_select) ? this.timezone_select.val() : false,
o = this._defaults;
if (typeof(hour) == 'object') hour = false;
if (typeof(minute) == 'object') minute = false;
if (typeof(second) == 'object') second = false;
if (typeof(millisec) == 'object') millisec = false;
if (typeof(timezone) == 'object') timezone = false;
if (hour !== false) hour = parseInt(hour,10);
if (minute !== false) minute = parseInt(minute,10);
if (second !== false) second = parseInt(second,10);
if (millisec !== false) millisec = parseInt(millisec,10);
var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];
// If the update was done in the input field, the input field should not be updated.
// If the update was done using the sliders, update the input field.
var hasChanged = (hour != this.hour || minute != this.minute
|| second != this.second || millisec != this.millisec
|| (this.ampm.length > 0
&& (hour < 12) != ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1))
|| timezone != this.timezone);
if (hasChanged) {
if (hour !== false)this.hour = hour;
if (minute !== false) this.minute = minute;
if (second !== false) this.second = second;
if (millisec !== false) this.millisec = millisec;
if (timezone !== false) this.timezone = timezone;
if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);
this._limitMinMaxDateTime(this.inst, true);
}
if (o.ampm) this.ampm = ampm;
//this._formatTime();
this.formattedTime = $.datepicker.formatTime(this._defaults.timeFormat, this, this._defaults);
if (this.$timeObj) this.$timeObj.text(this.formattedTime + o.timeSuffix);
this.timeDefined = true;
if (hasChanged) this._updateDateTime();
},
//########################################################################
// call custom onSelect.
// bind to sliders slidestop, and grid click.
//########################################################################
_onSelectHandler: function() {
var onSelect = this._defaults.onSelect;
var inputEl = this.$input ? this.$input[0] : null;
if (onSelect && inputEl) {
onSelect.apply(inputEl, [this.formattedDateTime, this]);
}
},
//########################################################################
// left for any backwards compatibility
//########################################################################
_formatTime: function(time, format) {
time = time || {hour: this.hour, minute: this.minute, second: this.second, millisec: this.millisec, ampm: this.ampm, timezone: this.timezone};
var tmptime = (format || this._defaults.timeFormat).toString();
tmptime = $.datepicker.formatTime(tmptime, time, this._defaults);
if (arguments.length) return tmptime;
else this.formattedTime = tmptime;
},
//########################################################################
// update our input with the new date time..
//########################################################################
_updateDateTime: function(dp_inst) {
dp_inst = this.inst || dp_inst;
var dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),
dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),
formatCfg = $.datepicker._getFormatConfig(dp_inst),
timeAvailable = dt !== null && this.timeDefined;
this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);
var formattedDateTime = this.formattedDate;
if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0))
return;
if (this._defaults.timeOnly === true) {
formattedDateTime = this.formattedTime;
} else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) {
formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;
}
this.formattedDateTime = formattedDateTime;
if(!this._defaults.showTimepicker) {
this.$input.val(this.formattedDate);
} else if (this.$altInput && this._defaults.altFieldTimeOnly === true) {
this.$altInput.val(this.formattedTime);
this.$input.val(this.formattedDate);
} else if(this.$altInput) {
this.$altInput.val(formattedDateTime);
this.$input.val(formattedDateTime);
} else {
this.$input.val(formattedDateTime);
}
this.$input.trigger("change");
}
});
$.fn.extend({
//########################################################################
// shorthand just to use timepicker..
//########################################################################
timepicker: function(o) {
o = o || {};
var tmp_args = arguments;
if (typeof o == 'object') tmp_args[0] = $.extend(o, {timeOnly: true});
return $(this).each(function() {
$.fn.datetimepicker.apply($(this), tmp_args);
});
},
//########################################################################
// extend timepicker to datepicker
//########################################################################
datetimepicker: function(o) {
o = o || {};
var $input = this,
tmp_args = arguments;
if (typeof(o) == 'string'){
if(o == 'getDate')
return $.fn.datepicker.apply($(this[0]), tmp_args);
else
return this.each(function() {
var $t = $(this);
$t.datepicker.apply($t, tmp_args);
});
}
else
return this.each(function() {
var $t = $(this);
$t.datepicker($.timepicker._newInst($t, o)._defaults);
});
}
});
//########################################################################
// format the time all pretty...
// format = string format of the time
// time = a {}, not a Date() for timezones
// options = essentially the regional[].. amNames, pmNames, ampm
//########################################################################
$.datepicker.formatTime = function(format, time, options) {
options = options || {};
options = $.extend($.timepicker._defaults, options);
time = $.extend({hour:0, minute:0, second:0, millisec:0, timezone:'+0000'}, time);
var tmptime = format;
var ampmName = options['amNames'][0];
var hour = parseInt(time.hour, 10);
if (options.ampm) {
if (hour > 11){
ampmName = options['pmNames'][0];
if(hour > 12)
hour = hour % 12;
}
if (hour === 0)
hour = 12;
}
tmptime = tmptime.replace(/(?:hh?|mm?|ss?|[tT]{1,2}|[lz])/g, function(match) {
switch (match.toLowerCase()) {
case 'hh':return ('0' + hour).slice(-2);
case 'h':return hour;
case 'mm':return ('0' + time.minute).slice(-2);
case 'm':return time.minute;
case 'ss':return ('0' + time.second).slice(-2);
case 's':return time.second;
case 'l':return ('00' + time.millisec).slice(-3);
case 'z':return time.timezone;
case 't': case 'tt':
if (options.ampm) {
if (match.length == 1)
ampmName = ampmName.charAt(0);
return match.charAt(0) == 'T' ? ampmName.toUpperCase() : ampmName.toLowerCase();
}
return '';
}
});
tmptime = $.trim(tmptime);
return tmptime;
}
//########################################################################
// the bad hack :/ override datepicker so it doesnt close on select
// inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378
//########################################################################
$.datepicker._base_selectDate = $.datepicker._selectDate;
$.datepicker._selectDate = function (id, dateStr) {
var inst = this._getInst($(id)[0]),
tp_inst = this._get(inst, 'timepicker');
if (tp_inst) {
tp_inst._limitMinMaxDateTime(inst, true);
inst.inline = inst.stay_open = true;
//This way the onSelect handler called from calendarpicker get the full dateTime
this._base_selectDate(id, dateStr);
inst.inline = inst.stay_open = false;
this._notifyChange(inst);
this._updateDatepicker(inst);
}
else this._base_selectDate(id, dateStr);
};
//#############################################################################################
// second bad hack :/ override datepicker so it triggers an event when changing the input field
// and does not redraw the datepicker on every selectDate event
//#############################################################################################
$.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;
$.datepicker._updateDatepicker = function(inst) {
// don't popup the datepicker if there is another instance already opened
var input = inst.input[0];
if($.datepicker._curInst &&
$.datepicker._curInst != inst &&
$.datepicker._datepickerShowing &&
$.datepicker._lastInput != input) {
return;
}
if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {
this._base_updateDatepicker(inst);
// Reload the time control when changing something in the input text field.
var tp_inst = this._get(inst, 'timepicker');
if(tp_inst) tp_inst._addTimePicker(inst);
}
};
//#######################################################################################
// third bad hack :/ override datepicker so it allows spaces and colon in the input field
//#######################################################################################
$.datepicker._base_doKeyPress = $.datepicker._doKeyPress;
$.datepicker._doKeyPress = function(event) {
var inst = $.datepicker._getInst(event.target),
tp_inst = $.datepicker._get(inst, 'timepicker');
if (tp_inst) {
if ($.datepicker._get(inst, 'constrainInput')) {
var ampm = tp_inst._defaults.ampm,
dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),
datetimeChars = tp_inst._defaults.timeFormat.toString()
.replace(/[hms]/g, '')
.replace(/TT/g, ampm ? 'APM' : '')
.replace(/Tt/g, ampm ? 'AaPpMm' : '')
.replace(/tT/g, ampm ? 'AaPpMm' : '')
.replace(/T/g, ampm ? 'AP' : '')
.replace(/tt/g, ampm ? 'apm' : '')
.replace(/t/g, ampm ? 'ap' : '') +
" " +
tp_inst._defaults.separator +
tp_inst._defaults.timeSuffix +
(tp_inst._defaults.showTimezone ? tp_inst._defaults.timezoneList.join('') : '') +
(tp_inst._defaults.amNames.join('')) +
(tp_inst._defaults.pmNames.join('')) +
dateChars,
chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);
return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);
}
}
return $.datepicker._base_doKeyPress(event);
};
//#######################################################################################
// Override key up event to sync manual input changes.
//#######################################################################################
$.datepicker._base_doKeyUp = $.datepicker._doKeyUp;
$.datepicker._doKeyUp = function (event) {
var inst = $.datepicker._getInst(event.target),
tp_inst = $.datepicker._get(inst, 'timepicker');
if (tp_inst) {
if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) {
try {
$.datepicker._updateDatepicker(inst);
}
catch (err) {
$.datepicker.log(err);
}
}
}
return $.datepicker._base_doKeyUp(event);
};
//#######################################################################################
// override "Today" button to also grab the time.
//#######################################################################################
$.datepicker._base_gotoToday = $.datepicker._gotoToday;
$.datepicker._gotoToday = function(id) {
var inst = this._getInst($(id)[0]),
$dp = inst.dpDiv;
this._base_gotoToday(id);
var now = new Date();
var tp_inst = this._get(inst, 'timepicker');
if (tp_inst && tp_inst._defaults.showTimezone && tp_inst.timezone_select) {
var tzoffset = now.getTimezoneOffset(); // If +0100, returns -60
var tzsign = tzoffset > 0 ? '-' : '+';
tzoffset = Math.abs(tzoffset);
var tzmin = tzoffset % 60;
tzoffset = tzsign + ('0' + (tzoffset - tzmin) / 60).slice(-2) + ('0' + tzmin).slice(-2);
if (tp_inst._defaults.timezoneIso8609)
tzoffset = tzoffset.substring(0, 3) + ':' + tzoffset.substring(3);
tp_inst.timezone_select.val(tzoffset);
}
this._setTime(inst, now);
$( '.ui-datepicker-today', $dp).click();
};
//#######################################################################################
// Disable & enable the Time in the datetimepicker
//#######################################################################################
$.datepicker._disableTimepickerDatepicker = function(target, date, withDate) {
var inst = this._getInst(target),
tp_inst = this._get(inst, 'timepicker');
$(target).datepicker('getDate'); // Init selected[Year|Month|Day]
if (tp_inst) {
tp_inst._defaults.showTimepicker = false;
tp_inst._updateDateTime(inst);
}
};
$.datepicker._enableTimepickerDatepicker = function(target, date, withDate) {
var inst = this._getInst(target),
tp_inst = this._get(inst, 'timepicker');
$(target).datepicker('getDate'); // Init selected[Year|Month|Day]
if (tp_inst) {
tp_inst._defaults.showTimepicker = true;
tp_inst._addTimePicker(inst); // Could be disabled on page load
tp_inst._updateDateTime(inst);
}
};
//#######################################################################################
// Create our own set time function
//#######################################################################################
$.datepicker._setTime = function(inst, date) {
var tp_inst = this._get(inst, 'timepicker');
if (tp_inst) {
var defaults = tp_inst._defaults,
// calling _setTime with no date sets time to defaults
hour = date ? date.getHours() : defaults.hour,
minute = date ? date.getMinutes() : defaults.minute,
second = date ? date.getSeconds() : defaults.second,
millisec = date ? date.getMilliseconds() : defaults.millisec;
//check if within min/max times..
if ((hour < defaults.hourMin || hour > defaults.hourMax) || (minute < defaults.minuteMin || minute > defaults.minuteMax) || (second < defaults.secondMin || second > defaults.secondMax) || (millisec < defaults.millisecMin || millisec > defaults.millisecMax)) {
hour = defaults.hourMin;
minute = defaults.minuteMin;
second = defaults.secondMin;
millisec = defaults.millisecMin;
}
tp_inst.hour = hour;
tp_inst.minute = minute;
tp_inst.second = second;
tp_inst.millisec = millisec;
if (tp_inst.hour_slider) tp_inst.hour_slider.slider('value', hour);
if (tp_inst.minute_slider) tp_inst.minute_slider.slider('value', minute);
if (tp_inst.second_slider) tp_inst.second_slider.slider('value', second);
if (tp_inst.millisec_slider) tp_inst.millisec_slider.slider('value', millisec);
tp_inst._onTimeChange();
tp_inst._updateDateTime(inst);
}
};
//#######################################################################################
// Create new public method to set only time, callable as $().datepicker('setTime', date)
//#######################################################################################
$.datepicker._setTimeDatepicker = function(target, date, withDate) {
var inst = this._getInst(target),
tp_inst = this._get(inst, 'timepicker');
if (tp_inst) {
this._setDateFromField(inst);
var tp_date;
if (date) {
if (typeof date == "string") {
tp_inst._parseTime(date, withDate);
tp_date = new Date();
tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
}
else tp_date = new Date(date.getTime());
if (tp_date.toString() == 'Invalid Date') tp_date = undefined;
this._setTime(inst, tp_date);
}
}
};
//#######################################################################################
// override setDate() to allow setting time too within Date object
//#######################################################################################
$.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;
$.datepicker._setDateDatepicker = function(target, date) {
var inst = this._getInst(target),
tp_date = (date instanceof Date) ? new Date(date.getTime()) : date;
this._updateDatepicker(inst);
this._base_setDateDatepicker.apply(this, arguments);
this._setTimeDatepicker(target, tp_date, true);
};
//#######################################################################################
// override getDate() to allow getting time too within Date object
//#######################################################################################
$.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;
$.datepicker._getDateDatepicker = function(target, noDefault) {
var inst = this._getInst(target),
tp_inst = this._get(inst, 'timepicker');
if (tp_inst) {
this._setDateFromField(inst, noDefault);
var date = this._getDate(inst);
if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
return date;
}
return this._base_getDateDatepicker(target, noDefault);
};
//#######################################################################################
// override parseDate() because UI 1.8.14 throws an error about "Extra characters"
// An option in datapicker to ignore extra format characters would be nicer.
//#######################################################################################
$.datepicker._base_parseDate = $.datepicker.parseDate;
$.datepicker.parseDate = function(format, value, settings) {
var date;
try {
date = this._base_parseDate(format, value, settings);
} catch (err) {
if (err.indexOf(":") >= 0) {
// Hack! The error message ends with a colon, a space, and
// the "extra" characters. We rely on that instead of
// attempting to perfectly reproduce the parsing algorithm.
date = this._base_parseDate(format, value.substring(0,value.length-(err.length-err.indexOf(':')-2)), settings);
} else {
// The underlying error was not related to the time
throw err;
}
}
return date;
};
//#######################################################################################
// override formatDate to set date with time to the input
//#######################################################################################
$.datepicker._base_formatDate=$.datepicker._formatDate;
$.datepicker._formatDate = function(inst, day, month, year){
var tp_inst = this._get(inst, 'timepicker');
if(tp_inst)
{
if(day)
var b = this._base_formatDate(inst, day, month, year);
tp_inst._updateDateTime(inst);
return tp_inst.$input.val();
}
return this._base_formatDate(inst);
};
//#######################################################################################
// override options setter to add time to maxDate(Time) and minDate(Time). MaxDate
//#######################################################################################
$.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;
$.datepicker._optionDatepicker = function(target, name, value) {
var inst = this._getInst(target),
tp_inst = this._get(inst, 'timepicker');
if (tp_inst) {
var min,max,onselect;
if (typeof name == 'string') { // if min/max was set with the string
if (name==='minDate' || name==='minDateTime' )
min = value;
else if (name==='maxDate' || name==='maxDateTime')
max = value;
else if (name==='onSelect')
onselect=value;
} else if (typeof name == 'object') { //if min/max was set with the JSON
if(name.minDate)
min = name.minDate;
else if (name.minDateTime)
min = name.minDateTime;
else if (name.maxDate)
max = name.maxDate;
else if (name.maxDateTime)
max = name.maxDateTime;
}
if(min){ //if min was set
if(min==0)
min=new Date();
else
min= new Date(min);
tp_inst._defaults.minDate = min;
tp_inst._defaults.minDateTime = min;
} else if (max){ //if max was set
if(max==0)
max=new Date();
else
max= new Date(max);
tp_inst._defaults.maxDate = max;
tp_inst._defaults.maxDateTime = max;
}
else if (onselect)
tp_inst._defaults.onSelect=onselect;
}
if (value === undefined)
return this._base_optionDatepicker(target, name);
return this._base_optionDatepicker(target, name, value);
};
//#######################################################################################
// jQuery extend now ignores nulls!
//#######################################################################################
function extendRemove(target, props) {
$.extend(target, props);
for (var name in props)
if (props[name] === null || props[name] === undefined)
target[name] = props[name];
return target;
};
$.timepicker = new Timepicker(); // singleton instance
$.timepicker.version = "0.9.9";
})(jQuery);
const uploadFile = (input, type = false) => {
// btn_next_ste.disabled = false;
input.closest(".row").classList.remove('border-danger-1-solid-m');
const fileToUpload = input.files[0];
if(type) {
let formData = new FormData();
formData.append('file', input.files[0])
return fetch(`${base_url}/file/getFileInfo`, {
method: 'post',
body: formData,
})
}
if((fileToUpload && ((fileToUpload.size/1024)/1024) <= 5)) {
let formData = new FormData();
formData.append('file', input.files[0])
fetch(`${base_url}/file/getFileInfo`, {
method: 'post',
body: formData,
})
.then((response) => response.json())
.then((result) => {
console.log("🚀 ~ file: organizer_addMatch.php:1330 ~ .then ~ dobio sam rezultat result:", result)
if(result.status) {
input.style.borderColor = 'initial'
if(result.mime_type != "application/pdf") {
input.closest(".row").classList.add('border-danger-1-solid-m');
// btn_next_ste.disabled = true;
noty({text: "Razpis mora biti v PDF formatu", type: "error"});
console.log("🚀 ~ file: organizer_addMatch.php:1338 ~ .then ~ vracam false:")
return false;
}
console.log("🚀 ~ file: organizer_addMatch.php:1338 ~ .then ~ vracam true:")
return true;
}
})
return true;
}
// btn_next_ste.disabled = true;
noty({text: "Datoteka ne sme presegati 5 MB.", type: "error"});
console.log("🚀 ~ file: organizer_addMatch.php:1338 ~ .then ~ vracam false:")
return false;
console.log("🚀 ~ file: organizer_addMatch.php:1338 ~ .then ~ vracam true, prazno je:")
return true;
}
$(document).ready(function() {
const razpis_file_element = document.querySelector("#razpis_file");
const btn_next_ste = document.querySelector("#next");
if(razpis_file_element) {
razpis_file_element.addEventListener('change', (e) => {
uploadFile(e.target)
})
}
$('.helper').CreateBubblePopup({
position : 'top',
align : 'center',
innerHtml: $(this).attr('help'),
innerHtmlStyle: {
color:'#FFFFFF',
'text-align':'center'
},
themeName: 'all-azure',
themePath: base_url+'assets/img'
});
$('.helper').live('mouseover', function(event) {
var text = $(this).attr('help');
$(this).ShowBubblePopup({
position : 'top',
align : 'center',
innerHtml: text,
innerHtmlStyle: {
color:'#FFFFFF',
'text-align':'center'
},
themeName: 'all-azure',
themePath: base_url+'assets/img'
});
});
$("#match_form").formwizard({
formPluginEnabled: true,
validationEnabled: true,
focusFirstInput : true,
textNext: '',
textSubmit: '',
textBack: '',
formOptions :{
success: function(data){$("#status").fadeTo(500,1,function(){ $(this).html("You are now registered!").fadeTo(5000, 0); })},
beforeSubmit: function(e) {
$("#next").css('pointer-events', 'none');
var form = $("#match_form")[0];
// check if its valid
var eventdate = new Date(form.eventdate.value);
var lastsignin = new Date(form.eventlastsignindate.value);
var lastsignout = new Date(form.eventlastsignout);
var today = new Date();
/*if (eventdate < today) {
noty({text: '!', type: "error"});
return false;
}
if (eventdate < lastsignin) {
noty({text: '!', type: "error"});
return false;
}
if (eventdate < lastsignout ) {
noty({text: '!', type: "error"});
return false;
}
if (lastsignin > lastsignout) {
noty({text: '!', type: "error"});
return false;
}*/
//if (form.pdf.value != "" && !form.pdf.value.match(/\.pdf$/)) {
// noty({text: '!', type: "error"});
// return false;
//}
//
//if (form.link1.value != "" && !form.link1.value.match(/\.pdf$/)) {
// noty({text: '!', type: "error"});
// return false;
//}
if (form.security_nr != undefined) {
if ($.ajax({
type: "POST",
data: 'id='+form.security_nr.value+'&answer='+form.security.value,
url: base_url + 'organizer/secQuestion',
async: false
}).responseText != 'OK') {
noty({text: '!', type: "error"});
return false;
}
}
if(razpis_file_element) {
const fileToUpload = razpis_file_element.files[0];
if(fileToUpload) {
if(((fileToUpload.size/1024)/1024) <= 5) {
if(fileToUpload) {
uploadFile(razpis_file_element, 1)
.then((response) => response.json())
.then((result) => {
console.log("🚀 ~ file: organizer_addMatch.php:1474 ~ .then ~ result:", result)
if(result.status) {
if(result.mime_type != "application/pdf") {
razpis_file_element.closest(".row").classList.add('border-danger-1-solid-m');
// btn_next_ste.disabled = true;
noty({text: "Razpis mora biti v PDF formatu", type: "error"});
console.log("🚀 ~ file: organizer_addMatch.php:1338 ~ .then ~ vracam false:")
return false;
}
form.submit();
return false;
console.log("🚀 ~ file: organizer_addMatch.php:1474 ~ submit u prvom uslovu")
}
})
return false
}
}else{
noty({text: "Datoteka ne sme presegati 5 MB.", type: "error"});
return false;
}
}
form.submit();
return false;
}else {
form.submit();
return false;
}
},
dataType: 'json',
resetForm: true
}
}
);
$("#match_form").bind("before_step_shown", function(event, data){
if (data.currentStep == 'options') {
var form = $("#match_form")[0];
if (form.eventlastsignindate.value == '') {
/*DEV TRY*/
var from = form.eventdate.value.split(".");
var date = new Date(from[2], from[1] - 1, from[0]);
//var date = Date.parse(form.eventdate.value);
//var date = Date.parse(form.eventdate.value);
var time = form.starttime.value;
form.eventlastsignindate.value = date.add({days: -2}).toString('dd.MM.yyyy');
form.eventlastsignout.value = date.add({days: +1}).toString('dd.MM.yyyy');
form.eventlastsignintime.value = "23:59";
form.eventlastsignouttime.value = "23:59";
}
}
});
/// Initialize dates
$.each($('.date'), function() {
$(this).datepicker({
dateFormat: "dd.mm.yy",
showAnim: 'drop'
});
})
/// Initialize times
$.each($('.timer'), function() {
$(this).timepicker({
timeFormat: 'hh:mm',
hourGrid: 4,
minuteGrid: 10
})
})
/// When user changes main discipline, get sub disciplines from database and show them.
$("#discipline").live('change', function() {
var content = $("#sub-disciplines");
var discipline = $(this).val();
var form_data = {
id : discipline,
ajax : '1'
};
$.ajax({
url: base_url+'ajax/getSubDisciplines',
type: 'POST',
async : false,
data: form_data,
success: function(data)
{
content.fadeOut('slow', function() {
content.html(data).fadeIn('slow');
})
}
});
})
$("#sub-disciplines").live('change', function() {
var content = $("#leagues");
var discipline = $(this).val();
var form_data = {
id : discipline,
ajax : '1'
};
$.ajax({
url: base_url+'organizer/getLeagues',
type: 'POST',
async : false,
data: form_data,
success: function(data)
{
content.fadeOut('slow', function() {
content.html(data).fadeIn('slow');
})
}
});
})
function completeOrganizer(selector, numero)
{
if ($(selector).length == 0) return;
$( selector ).autocomplete({
source: base_url+"common/organizerSearch",
minLength: 2,
focus: function( event, ui ) {
$(selector).val( ui.item.title );
return false;
},
select: function( event, ui ) {
$("#organizer-id"+numero).val(ui.item.id);
$("#organizer-title"+numero).val(ui.item.title);
$("#organizer-address"+numero).val(ui.item.address);
$("#organizer-city"+numero).val(ui.item.city);
$("#organizer-trr"+numero).val(ui.item.trr);
$("#organizer-email"+numero).val(ui.item.email);
$("#organizer-phone"+numero).val(ui.item.phone);
$("#organizer-contact"+numero).val(ui.item.contact);
return false;
}
})
.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "" )
.data( "item.autocomplete", item )
.append( "" + item.title + "" )
.appendTo( ul );
};
}
completeOrganizer("#organizer-title0", "0");
/// Set start number for dynamic parameters.
var numero = 0;
var valnumero = 1;
/// Whole logic for adding dynamic parameters for that mach!
$("#control-parameter").live('click', function(e) {
var type = $(this).attr("class");
var holder = $("#dynamic-param");
if(type == "add")
{
numero++;
valnumero++;
if(numero > 0) {holder.fadeIn();}
holder.append('\
\n\
\n\
Naslov parametra
Tekstualni parametar?
\n\
Vrednost 1
');
$(".paramDiv"+numero).hide().fadeIn('slow');
$(".add-value").fadeIn('slow');
dynamicChange("save");
}
else if (type == "save")
{
dynamicChange("add");
}
e.preventDefault();
})
/// Add value input for this numero.
$(".add-value").live('click', function(e) {
var holder = $("#dynamic-param");
holder.append('
Vrednost '+valnumero+'
');
valnumero++;
e.preventDefault();
})
/// Changer for SAVE or ADD parameter
function dynamicChange(type)
{
var controler = $("#control-parameter");
if(type == "add")
{
var i = 0;
$(".add-value").fadeOut('slow', function() {
i++;
if(i == 1){
var title = $("#title").val();
if ($('input.textual').is(':checked')) {
var param_text = 1;
}else{
var param_text = 0;
}
var append_middle = "";
var append_post = "";
$.each($(".value"), function(){
append_middle += "";
append_post += '';
})
$("#dynamic-param").fadeOut('fast', function() {$(this).empty();
var append = '\n\