You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1142 lines
32 KiB
1142 lines
32 KiB
9 years ago
|
/**
|
||
|
* @package PickMeUp - jQuery datepicker plugin
|
||
|
* @author Nazar Mokrynskyi <nazar@mokrynskyi.com>
|
||
|
* @author Stefan Petre <www.eyecon.ro>
|
||
|
* @copyright Copyright (c) 2013-2015, Nazar Mokrynskyi
|
||
|
* @copyright Copyright (c) 2008-2009, Stefan Petre
|
||
|
* @license MIT License, see license.txt
|
||
|
*/
|
||
|
|
||
|
(function (d) {
|
||
|
function getMaxDays () {
|
||
|
var tmpDate = new Date(this.toString()),
|
||
|
d = 28,
|
||
|
m = tmpDate.getMonth();
|
||
|
while (tmpDate.getMonth() == m) {
|
||
|
++d;
|
||
|
tmpDate.setDate(d);
|
||
|
}
|
||
|
return d - 1;
|
||
|
}
|
||
|
d.addDays = function (n) {
|
||
|
this.setDate(this.getDate() + n);
|
||
|
};
|
||
|
d.addMonths = function (n) {
|
||
|
var day = this.getDate();
|
||
|
this.setDate(1);
|
||
|
this.setMonth(this.getMonth() + n);
|
||
|
this.setDate(Math.min(day, getMaxDays.apply(this)));
|
||
|
};
|
||
|
d.addYears = function (n) {
|
||
|
var day = this.getDate();
|
||
|
this.setDate(1);
|
||
|
this.setFullYear(this.getFullYear() + n);
|
||
|
this.setDate(Math.min(day, getMaxDays.apply(this)));
|
||
|
};
|
||
|
d.getDayOfYear = function() {
|
||
|
var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
|
||
|
var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
|
||
|
var time = now - then;
|
||
|
return Math.floor(time / 24*60*60*1000);
|
||
|
};
|
||
|
})(Date.prototype);
|
||
|
|
||
|
(function (factory) {
|
||
|
if (typeof define === 'function' && define.amd) {
|
||
|
// AMD
|
||
|
define(['jquery'], factory);
|
||
|
} else if (typeof exports === 'object') {
|
||
|
// CommonJS
|
||
|
factory(require('jquery'));
|
||
|
} else {
|
||
|
// Browser globals
|
||
|
factory(jQuery);
|
||
|
}
|
||
|
}(function ($) {
|
||
|
var instances_count = 0;
|
||
|
$.pickmeup = $.extend($.pickmeup || {}, {
|
||
|
date : new Date,
|
||
|
default_date : new Date,
|
||
|
flat : false,
|
||
|
first_day : 1,
|
||
|
prev : '◀',
|
||
|
next : '▶',
|
||
|
mode : 'single',
|
||
|
select_year : true,
|
||
|
select_month : true,
|
||
|
select_day : true,
|
||
|
view : 'days',
|
||
|
calendars : 1,
|
||
|
format : 'd-m-Y',
|
||
|
position : 'bottom',
|
||
|
trigger_event : 'click touchstart',
|
||
|
class_name : '',
|
||
|
separator : ' - ',
|
||
|
hide_on_select : false,
|
||
|
min : null,
|
||
|
max : null,
|
||
|
render : function () {},
|
||
|
change : function () {return true;},
|
||
|
before_show : function () {return true;},
|
||
|
show : function () {return true;},
|
||
|
hide : function () {return true;},
|
||
|
fill : function () {return true;},
|
||
|
locale : {
|
||
|
days : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
|
||
|
daysShort : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||
|
daysMin : ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
|
||
|
months : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
||
|
monthsShort : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||
|
}
|
||
|
});
|
||
|
var views = {
|
||
|
years : 'pmu-view-years',
|
||
|
months : 'pmu-view-months',
|
||
|
days : 'pmu-view-days'
|
||
|
},
|
||
|
tpl = {
|
||
|
wrapper : '<div class="pickmeup" />',
|
||
|
head : function (d) {
|
||
|
var result = '';
|
||
|
for (var i = 0; i < 7; ++i) {
|
||
|
result += '<div>' + d.day[i] + '</div>'
|
||
|
}
|
||
|
return '<div class="pmu-instance">' +
|
||
|
'<nav>' +
|
||
|
'<div class="pmu-prev pmu-button">' + d.prev + '</div>' +
|
||
|
'<div class="pmu-month pmu-button" />' +
|
||
|
'<div class="pmu-next pmu-button">' + d.next + '</div>' +
|
||
|
'</nav>' +
|
||
|
'<nav class="pmu-day-of-week">' + result + '</nav>' +
|
||
|
'</div>';
|
||
|
},
|
||
|
body : function (elements, container_class_name) {
|
||
|
var result = '';
|
||
|
for (var i = 0; i < elements.length; ++i) {
|
||
|
result += '<div class="' + elements[i].class_name + ' pmu-button">' + elements[i].text + '</div>'
|
||
|
}
|
||
|
return '<div class="' + container_class_name + '">' + result + '</div>';
|
||
|
}
|
||
|
};
|
||
|
function fill () {
|
||
|
var options = $(this).data('pickmeup-options'),
|
||
|
pickmeup = this.pickmeup,
|
||
|
current_cal = Math.floor(options.calendars / 2),
|
||
|
actual_date = options.date,
|
||
|
current_date = options.current,
|
||
|
min_date = options.min ? new Date(options.min) : null,
|
||
|
max_date = options.max ? new Date(options.max) : null,
|
||
|
local_date,
|
||
|
header,
|
||
|
html,
|
||
|
instance,
|
||
|
today = (new Date).setHours(0,0,0,0).valueOf(),
|
||
|
shown_date_from,
|
||
|
shown_date_to,
|
||
|
tmp_date;
|
||
|
if (min_date) {
|
||
|
min_date.setDate(1);
|
||
|
min_date.addMonths(1);
|
||
|
min_date.addDays(-1);
|
||
|
}
|
||
|
if (max_date) {
|
||
|
max_date.setDate(1);
|
||
|
max_date.addMonths(1);
|
||
|
max_date.addDays(-1);
|
||
|
}
|
||
|
/**
|
||
|
* Remove old content except header navigation
|
||
|
*/
|
||
|
pickmeup.find('.pmu-instance > :not(nav)').remove();
|
||
|
/**
|
||
|
* If several calendars should be shown
|
||
|
*/
|
||
|
for (var i = 0; i < options.calendars; i++) {
|
||
|
local_date = new Date(current_date);
|
||
|
instance = pickmeup.find('.pmu-instance').eq(i);
|
||
|
if (pickmeup.hasClass('pmu-view-years')) {
|
||
|
local_date.addYears((i - current_cal) * 12);
|
||
|
header = (local_date.getFullYear() - 6) + ' - ' + (local_date.getFullYear()+5);
|
||
|
} else if (pickmeup.hasClass('pmu-view-months')) {
|
||
|
local_date.addYears(i - current_cal);
|
||
|
header = local_date.getFullYear();
|
||
|
} else if (pickmeup.hasClass('pmu-view-days')) {
|
||
|
local_date.addMonths(i - current_cal);
|
||
|
header = formatDate(local_date, 'B, Y', options.locale);
|
||
|
}
|
||
|
if (!shown_date_to) {
|
||
|
if (max_date) {
|
||
|
// If all dates in this month (months in year or years in years block) are after max option - set next month as current
|
||
|
// in order not to show calendar with all disabled dates
|
||
|
tmp_date = new Date(local_date);
|
||
|
if (options.select_day) {
|
||
|
tmp_date.addMonths(options.calendars - 1);
|
||
|
} else if (options.select_month) {
|
||
|
tmp_date.addYears(options.calendars - 1);
|
||
|
} else {
|
||
|
tmp_date.addYears((options.calendars - 1) * 12);
|
||
|
}
|
||
|
if (tmp_date > max_date) {
|
||
|
--i;
|
||
|
current_date.addMonths(-1);
|
||
|
shown_date_to = undefined;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
shown_date_to = new Date(local_date);
|
||
|
if (!shown_date_from) {
|
||
|
shown_date_from = new Date(local_date);
|
||
|
// If all dates in this month are before min option - set next month as current in order not to show calendar with all disabled dates
|
||
|
shown_date_from.setDate(1);
|
||
|
shown_date_from.addMonths(1);
|
||
|
shown_date_from.addDays(-1);
|
||
|
if (min_date && min_date > shown_date_from) {
|
||
|
--i;
|
||
|
current_date.addMonths(1);
|
||
|
shown_date_from = undefined;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
instance
|
||
|
.find('.pmu-month')
|
||
|
.text(header);
|
||
|
html = '';
|
||
|
var is_year_selected = function (year) {
|
||
|
return (
|
||
|
options.mode == 'range' &&
|
||
|
year >= new Date(actual_date[0]).getFullYear() &&
|
||
|
year <= new Date(actual_date[1]).getFullYear()
|
||
|
) ||
|
||
|
(
|
||
|
options.mode == 'multiple' &&
|
||
|
actual_date.reduce(function (prev, current) {
|
||
|
prev.push(new Date(current).getFullYear());
|
||
|
return prev;
|
||
|
}, []).indexOf(year) !== -1
|
||
|
) ||
|
||
|
new Date(actual_date).getFullYear() == year;
|
||
|
};
|
||
|
var is_months_selected = function (year, month) {
|
||
|
var first_year = new Date(actual_date[0]).getFullYear(),
|
||
|
lastyear = new Date(actual_date[1]).getFullYear(),
|
||
|
first_month = new Date(actual_date[0]).getMonth(),
|
||
|
last_month = new Date(actual_date[1]).getMonth();
|
||
|
return (
|
||
|
options.mode == 'range' &&
|
||
|
year > first_year &&
|
||
|
year < lastyear
|
||
|
) ||
|
||
|
(
|
||
|
options.mode == 'range' &&
|
||
|
year == first_year &&
|
||
|
year < lastyear &&
|
||
|
month >= first_month
|
||
|
) ||
|
||
|
(
|
||
|
options.mode == 'range' &&
|
||
|
year > first_year &&
|
||
|
year == lastyear &&
|
||
|
month <= last_month
|
||
|
) ||
|
||
|
(
|
||
|
options.mode == 'range' &&
|
||
|
year == first_year &&
|
||
|
year == lastyear &&
|
||
|
month >= first_month &&
|
||
|
month <= last_month
|
||
|
) ||
|
||
|
(
|
||
|
options.mode == 'multiple' &&
|
||
|
actual_date.reduce(function (prev, current) {
|
||
|
current = new Date(current);
|
||
|
prev.push(current.getFullYear() + '-' + current.getMonth());
|
||
|
return prev;
|
||
|
}, []).indexOf(year + '-' + month) !== -1
|
||
|
) ||
|
||
|
(
|
||
|
new Date(actual_date).getFullYear() == year &&
|
||
|
new Date(actual_date).getMonth() == month
|
||
|
)
|
||
|
};
|
||
|
(function () {
|
||
|
var years = [],
|
||
|
start_from_year = local_date.getFullYear() - 6,
|
||
|
min_year = new Date(options.min).getFullYear(),
|
||
|
max_year = new Date(options.max).getFullYear(),
|
||
|
year;
|
||
|
for (var j = 0; j < 12; ++j) {
|
||
|
year = {
|
||
|
text : start_from_year + j,
|
||
|
class_name : []
|
||
|
};
|
||
|
if (
|
||
|
(
|
||
|
options.min && year.text < min_year
|
||
|
) ||
|
||
|
(
|
||
|
options.max && year.text > max_year
|
||
|
)
|
||
|
) {
|
||
|
year.class_name.push('pmu-disabled');
|
||
|
} else if (is_year_selected(year.text)) {
|
||
|
year.class_name.push('pmu-selected');
|
||
|
}
|
||
|
year.class_name = year.class_name.join(' ');
|
||
|
years.push(year);
|
||
|
}
|
||
|
html += tpl.body(years, 'pmu-years');
|
||
|
})();
|
||
|
(function () {
|
||
|
var months = [],
|
||
|
current_year = local_date.getFullYear(),
|
||
|
min_year = new Date(options.min).getFullYear(),
|
||
|
min_month = new Date(options.min).getMonth(),
|
||
|
max_year = new Date(options.max).getFullYear(),
|
||
|
max_month = new Date(options.max).getMonth(),
|
||
|
month;
|
||
|
for (var j = 0; j < 12; ++j) {
|
||
|
month = {
|
||
|
text : options.locale.monthsShort[j],
|
||
|
class_name : []
|
||
|
};
|
||
|
if (
|
||
|
(
|
||
|
options.min &&
|
||
|
(
|
||
|
current_year < min_year ||
|
||
|
(
|
||
|
j < min_month && current_year == min_year
|
||
|
)
|
||
|
)
|
||
|
) ||
|
||
|
(
|
||
|
options.max &&
|
||
|
(
|
||
|
current_year > max_year ||
|
||
|
(
|
||
|
j > max_month && current_year >= max_year
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
) {
|
||
|
month.class_name.push('pmu-disabled');
|
||
|
} else if (is_months_selected(current_year, j)) {
|
||
|
month.class_name.push('pmu-selected');
|
||
|
}
|
||
|
month.class_name = month.class_name.join(' ');
|
||
|
months.push(month);
|
||
|
}
|
||
|
html += tpl.body(months, 'pmu-months');
|
||
|
})();
|
||
|
(function () {
|
||
|
var days = [],
|
||
|
current_month = local_date.getMonth(),
|
||
|
day;
|
||
|
// Correct first day in calendar taking into account first day of week (Sunday or Monday)
|
||
|
(function () {
|
||
|
local_date.setDate(1);
|
||
|
var day = (local_date.getDay() - options.first_day) % 7;
|
||
|
local_date.addDays(-(day + (day < 0 ? 7 : 0)));
|
||
|
})();
|
||
|
for (var j = 0; j < 42; ++j) {
|
||
|
day = {
|
||
|
text : local_date.getDate(),
|
||
|
class_name : []
|
||
|
};
|
||
|
if (current_month != local_date.getMonth()) {
|
||
|
day.class_name.push('pmu-not-in-month');
|
||
|
}
|
||
|
if (local_date.getDay() == 0) {
|
||
|
day.class_name.push('pmu-sunday');
|
||
|
} else if (local_date.getDay() == 6) {
|
||
|
day.class_name.push('pmu-saturday');
|
||
|
}
|
||
|
var from_user = options.render(new Date(local_date)) || {},
|
||
|
val = local_date.valueOf(),
|
||
|
disabled = (options.min && options.min > local_date) || (options.max && options.max < local_date);
|
||
|
if (from_user.disabled || disabled) {
|
||
|
day.class_name.push('pmu-disabled');
|
||
|
} else if (
|
||
|
from_user.selected ||
|
||
|
options.date == val ||
|
||
|
$.inArray(val, options.date) !== -1 ||
|
||
|
(
|
||
|
options.mode == 'range' && val >= options.date[0] && val <= options.date[1]
|
||
|
)
|
||
|
) {
|
||
|
day.class_name.push('pmu-selected');
|
||
|
}
|
||
|
if (val == today) {
|
||
|
day.class_name.push('pmu-today');
|
||
|
}
|
||
|
if (from_user.class_name) {
|
||
|
day.class_name.push(from_user.class_name);
|
||
|
}
|
||
|
day.class_name = day.class_name.join(' ');
|
||
|
days.push(day);
|
||
|
// Move to next day
|
||
|
local_date.addDays(1);
|
||
|
}
|
||
|
html += tpl.body(days, 'pmu-days');
|
||
|
})();
|
||
|
instance.append(html);
|
||
|
}
|
||
|
shown_date_from.setDate(1);
|
||
|
shown_date_to.setDate(1);
|
||
|
shown_date_to.addMonths(1);
|
||
|
shown_date_to.addDays(-1);
|
||
|
pickmeup.find('.pmu-prev').css(
|
||
|
'visibility',
|
||
|
options.min && options.min >= shown_date_from ? 'hidden' : 'visible'
|
||
|
);
|
||
|
pickmeup.find('.pmu-next').css(
|
||
|
'visibility',
|
||
|
options.max && options.max <= shown_date_to ? 'hidden' : 'visible'
|
||
|
);
|
||
|
options.fill.apply(this);
|
||
|
}
|
||
|
function parseDate (date, format, separator, locale) {
|
||
|
if (date.constructor == Date) {
|
||
|
return date;
|
||
|
} else if (!date) {
|
||
|
return new Date;
|
||
|
}
|
||
|
var splitted_date = date.split(separator);
|
||
|
if (splitted_date.length > 1) {
|
||
|
splitted_date.forEach(function (element, index, array) {
|
||
|
array[index] = parseDate($.trim(element), format, separator, locale);
|
||
|
});
|
||
|
return splitted_date;
|
||
|
}
|
||
|
var months_text = locale.monthsShort.join(')(') + ')(' + locale.months.join(')('),
|
||
|
separator = new RegExp('[^0-9a-zA-Z(' + months_text + ')]+'),
|
||
|
parts = date.split(separator),
|
||
|
against = format.split(separator),
|
||
|
d,
|
||
|
m,
|
||
|
y,
|
||
|
h,
|
||
|
min,
|
||
|
now = new Date();
|
||
|
for (var i = 0; i < parts.length; i++) {
|
||
|
switch (against[i]) {
|
||
|
case 'b':
|
||
|
m = locale.monthsShort.indexOf(parts[i]);
|
||
|
break;
|
||
|
case 'B':
|
||
|
m = locale.months.indexOf(parts[i]);
|
||
|
break;
|
||
|
case 'd':
|
||
|
case 'e':
|
||
|
d = parseInt(parts[i],10);
|
||
|
break;
|
||
|
case 'm':
|
||
|
m = parseInt(parts[i], 10)-1;
|
||
|
break;
|
||
|
case 'Y':
|
||
|
case 'y':
|
||
|
y = parseInt(parts[i], 10);
|
||
|
y += y > 100 ? 0 : (y < 29 ? 2000 : 1900);
|
||
|
break;
|
||
|
case 'H':
|
||
|
case 'I':
|
||
|
case 'k':
|
||
|
case 'l':
|
||
|
h = parseInt(parts[i], 10);
|
||
|
break;
|
||
|
case 'P':
|
||
|
case 'p':
|
||
|
if (/pm/i.test(parts[i]) && h < 12) {
|
||
|
h += 12;
|
||
|
} else if (/am/i.test(parts[i]) && h >= 12) {
|
||
|
h -= 12;
|
||
|
}
|
||
|
break;
|
||
|
case 'M':
|
||
|
min = parseInt(parts[i], 10);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
var parsed_date = new Date(
|
||
|
y === undefined ? now.getFullYear() : y,
|
||
|
m === undefined ? now.getMonth() : m,
|
||
|
d === undefined ? now.getDate() : d,
|
||
|
h === undefined ? now.getHours() : h,
|
||
|
min === undefined ? now.getMinutes() : min,
|
||
|
0
|
||
|
);
|
||
|
if (isNaN(parsed_date * 1)) {
|
||
|
parsed_date = new Date;
|
||
|
}
|
||
|
return parsed_date;
|
||
|
}
|
||
|
function formatDate (date, format, locale) {
|
||
|
var m = date.getMonth();
|
||
|
var d = date.getDate();
|
||
|
var y = date.getFullYear();
|
||
|
var w = date.getDay();
|
||
|
var s = {};
|
||
|
var hr = date.getHours();
|
||
|
var pm = (hr >= 12);
|
||
|
var ir = (pm) ? (hr - 12) : hr;
|
||
|
var dy = date.getDayOfYear();
|
||
|
if (ir == 0) {
|
||
|
ir = 12;
|
||
|
}
|
||
|
var min = date.getMinutes();
|
||
|
var sec = date.getSeconds();
|
||
|
var parts = format.split(''), part;
|
||
|
for (var i = 0; i < parts.length; i++) {
|
||
|
part = parts[i];
|
||
|
switch (part) {
|
||
|
case 'a':
|
||
|
part = locale.daysShort[w];
|
||
|
break;
|
||
|
case 'A':
|
||
|
part = locale.days[w];
|
||
|
break;
|
||
|
case 'b':
|
||
|
part = locale.monthsShort[m];
|
||
|
break;
|
||
|
case 'B':
|
||
|
part = locale.months[m];
|
||
|
break;
|
||
|
case 'C':
|
||
|
part = 1 + Math.floor(y / 100);
|
||
|
break;
|
||
|
case 'd':
|
||
|
part = (d < 10) ? ("0" + d) : d;
|
||
|
break;
|
||
|
case 'e':
|
||
|
part = d;
|
||
|
break;
|
||
|
case 'H':
|
||
|
part = (hr < 10) ? ("0" + hr) : hr;
|
||
|
break;
|
||
|
case 'I':
|
||
|
part = (ir < 10) ? ("0" + ir) : ir;
|
||
|
break;
|
||
|
case 'j':
|
||
|
part = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy;
|
||
|
break;
|
||
|
case 'k':
|
||
|
part = hr;
|
||
|
break;
|
||
|
case 'l':
|
||
|
part = ir;
|
||
|
break;
|
||
|
case 'm':
|
||
|
part = (m < 9) ? ("0" + (1+m)) : (1+m);
|
||
|
break;
|
||
|
case 'M':
|
||
|
part = (min < 10) ? ("0" + min) : min;
|
||
|
break;
|
||
|
case 'p':
|
||
|
case 'P':
|
||
|
part = pm ? "PM" : "AM";
|
||
|
break;
|
||
|
case 's':
|
||
|
part = Math.floor(date.getTime() / 1000);
|
||
|
break;
|
||
|
case 'S':
|
||
|
part = (sec < 10) ? ("0" + sec) : sec;
|
||
|
break;
|
||
|
case 'u':
|
||
|
part = w + 1;
|
||
|
break;
|
||
|
case 'w':
|
||
|
part = w;
|
||
|
break;
|
||
|
case 'y':
|
||
|
part = ('' + y).substr(2, 2);
|
||
|
break;
|
||
|
case 'Y':
|
||
|
part = y;
|
||
|
break;
|
||
|
}
|
||
|
parts[i] = part;
|
||
|
}
|
||
|
return parts.join('');
|
||
|
}
|
||
|
function update_date () {
|
||
|
var $this = $(this),
|
||
|
options = $this.data('pickmeup-options'),
|
||
|
current_date = options.current,
|
||
|
new_value;
|
||
|
switch (options.mode) {
|
||
|
case 'multiple':
|
||
|
new_value = current_date.setHours(0,0,0,0).valueOf();
|
||
|
if ($.inArray(new_value, options.date) !== -1) {
|
||
|
$.each(options.date, function (index, value){
|
||
|
if (value == new_value) {
|
||
|
options.date.splice(index,1);
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
});
|
||
|
} else {
|
||
|
options.date.push(new_value);
|
||
|
}
|
||
|
break;
|
||
|
case 'range':
|
||
|
if (!options.lastSel) {
|
||
|
options.date[0] = current_date.setHours(0,0,0,0).valueOf();
|
||
|
}
|
||
|
new_value = current_date.setHours(0,0,0,0).valueOf();
|
||
|
if (new_value <= options.date[0]) {
|
||
|
options.date[1] = options.date[0];
|
||
|
options.date[0] = new_value;
|
||
|
} else {
|
||
|
options.date[1] = new_value;
|
||
|
}
|
||
|
options.lastSel = !options.lastSel;
|
||
|
break;
|
||
|
default:
|
||
|
options.date = current_date.valueOf();
|
||
|
break;
|
||
|
}
|
||
|
var prepared_date = prepareDate(options);
|
||
|
if ($this.is('input')) {
|
||
|
$this.val(options.mode == 'single' ? prepared_date[0] : prepared_date[0].join(options.separator));
|
||
|
}
|
||
|
options.change.apply(this, prepared_date);
|
||
|
if (
|
||
|
!options.flat &&
|
||
|
options.hide_on_select &&
|
||
|
(
|
||
|
options.mode != 'range' ||
|
||
|
!options.lastSel
|
||
|
)
|
||
|
) {
|
||
|
options.binded.hide();
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
function click (e) {
|
||
|
var el = $(e.target);
|
||
|
if (!el.hasClass('pmu-button')) {
|
||
|
el = el.closest('.pmu-button');
|
||
|
}
|
||
|
if (el.length) {
|
||
|
if (el.hasClass('pmu-disabled')) {
|
||
|
return false;
|
||
|
}
|
||
|
var $this = $(this),
|
||
|
options = $this.data('pickmeup-options'),
|
||
|
instance = el.parents('.pmu-instance').eq(0),
|
||
|
root = instance.parent(),
|
||
|
instance_index = $('.pmu-instance', root).index(instance);
|
||
|
if (el.parent().is('nav')) {
|
||
|
if (el.hasClass('pmu-month')) {
|
||
|
options.current.addMonths(instance_index - Math.floor(options.calendars / 2));
|
||
|
if (root.hasClass('pmu-view-years')) {
|
||
|
// Shift back to current date, otherwise with min value specified may jump on few (tens) years forward
|
||
|
if (options.mode != 'single') {
|
||
|
options.current = new Date(options.date[options.date.length - 1]);
|
||
|
} else {
|
||
|
options.current = new Date(options.date);
|
||
|
}
|
||
|
if (options.select_day) {
|
||
|
root.removeClass('pmu-view-years').addClass('pmu-view-days');
|
||
|
} else if (options.select_month) {
|
||
|
root.removeClass('pmu-view-years').addClass('pmu-view-months');
|
||
|
}
|
||
|
} else if (root.hasClass('pmu-view-months')) {
|
||
|
if (options.select_year) {
|
||
|
root.removeClass('pmu-view-months').addClass('pmu-view-years');
|
||
|
} else if (options.select_day) {
|
||
|
root.removeClass('pmu-view-months').addClass('pmu-view-days');
|
||
|
}
|
||
|
} else if (root.hasClass('pmu-view-days')) {
|
||
|
if (options.select_month) {
|
||
|
root.removeClass('pmu-view-days').addClass('pmu-view-months');
|
||
|
} else if (options.select_year) {
|
||
|
root.removeClass('pmu-view-days').addClass('pmu-view-years');
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if (el.hasClass('pmu-prev')) {
|
||
|
options.binded.prev(false);
|
||
|
} else {
|
||
|
options.binded.next(false);
|
||
|
}
|
||
|
}
|
||
|
} else if (!el.hasClass('pmu-disabled')) {
|
||
|
if (root.hasClass('pmu-view-years')) {
|
||
|
options.current.setFullYear(parseInt(el.text(), 10));
|
||
|
if (options.select_month) {
|
||
|
root.removeClass('pmu-view-years').addClass('pmu-view-months');
|
||
|
} else if (options.select_day) {
|
||
|
root.removeClass('pmu-view-years').addClass('pmu-view-days');
|
||
|
} else {
|
||
|
options.binded.update_date();
|
||
|
}
|
||
|
} else if (root.hasClass('pmu-view-months')) {
|
||
|
options.current.setMonth(instance.find('.pmu-months .pmu-button').index(el));
|
||
|
options.current.setFullYear(parseInt(instance.find('.pmu-month').text(), 10));
|
||
|
if (options.select_day) {
|
||
|
root.removeClass('pmu-view-months').addClass('pmu-view-days');
|
||
|
} else {
|
||
|
options.binded.update_date();
|
||
|
}
|
||
|
// Move current month to the first place
|
||
|
options.current.addMonths(Math.floor(options.calendars / 2) - instance_index);
|
||
|
} else {
|
||
|
var val = parseInt(el.text(), 10);
|
||
|
options.current.addMonths(instance_index - Math.floor(options.calendars / 2));
|
||
|
if (el.hasClass('pmu-not-in-month')) {
|
||
|
options.current.addMonths(val > 15 ? -1 : 1);
|
||
|
}
|
||
|
options.current.setDate(val);
|
||
|
options.binded.update_date();
|
||
|
}
|
||
|
}
|
||
|
options.binded.fill();
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
function prepareDate (options) {
|
||
|
var result;
|
||
|
if (options.mode == 'single') {
|
||
|
result = new Date(options.date);
|
||
|
return [formatDate(result, options.format, options.locale), result];
|
||
|
} else {
|
||
|
result = [[],[]];
|
||
|
$.each(options.date, function(nr, val){
|
||
|
var date = new Date(val);
|
||
|
result[0].push(formatDate(date, options.format, options.locale));
|
||
|
result[1].push(date);
|
||
|
});
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
function show (force) {
|
||
|
var pickmeup = this.pickmeup;
|
||
|
if (force || !pickmeup.is(':visible')) {
|
||
|
var $this = $(this),
|
||
|
options = $this.data('pickmeup-options'),
|
||
|
pos = $this.offset(),
|
||
|
viewport = {
|
||
|
l : document.documentElement.scrollLeft,
|
||
|
t : document.documentElement.scrollTop,
|
||
|
w : document.documentElement.clientWidth,
|
||
|
h : document.documentElement.clientHeight
|
||
|
},
|
||
|
top = pos.top,
|
||
|
left = pos.left;
|
||
|
options.binded.fill();
|
||
|
if ($this.is('input')) {
|
||
|
$this
|
||
|
.pickmeup('set_date', parseDate($this.val() ? $this.val() : options.default_date, options.format, options.separator, options.locale))
|
||
|
.keydown(function (e) {
|
||
|
if (e.which == 9) {
|
||
|
$this.pickmeup('hide');
|
||
|
}
|
||
|
});
|
||
|
options.lastSel = false;
|
||
|
}
|
||
|
options.before_show();
|
||
|
if (options.show() == false) {
|
||
|
return;
|
||
|
}
|
||
|
if (!options.flat) {
|
||
|
switch (options.position){
|
||
|
case 'top':
|
||
|
top -= pickmeup.outerHeight();
|
||
|
break;
|
||
|
case 'left':
|
||
|
left -= pickmeup.outerWidth();
|
||
|
break;
|
||
|
case 'right':
|
||
|
left += this.offsetWidth;
|
||
|
break;
|
||
|
case 'bottom':
|
||
|
top += this.offsetHeight;
|
||
|
break;
|
||
|
}
|
||
|
if (top + pickmeup.offsetHeight > viewport.t + viewport.h) {
|
||
|
top = pos.top - pickmeup.offsetHeight;
|
||
|
}
|
||
|
if (top < viewport.t) {
|
||
|
top = pos.top + this.offsetHeight + pickmeup.offsetHeight;
|
||
|
}
|
||
|
if (left + pickmeup.offsetWidth > viewport.l + viewport.w) {
|
||
|
left = pos.left - pickmeup.offsetWidth;
|
||
|
}
|
||
|
if (left < viewport.l) {
|
||
|
left = pos.left + this.offsetWidth
|
||
|
}
|
||
|
pickmeup.css({
|
||
|
display : 'inline-block',
|
||
|
top : top + 'px',
|
||
|
left : left + 'px'
|
||
|
});
|
||
|
$(document)
|
||
|
.on(
|
||
|
'mousedown' + options.events_namespace + ' touchstart' + options.events_namespace,
|
||
|
options.binded.hide
|
||
|
)
|
||
|
.on(
|
||
|
'resize' + options.events_namespace,
|
||
|
[
|
||
|
true
|
||
|
],
|
||
|
options.binded.forced_show
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function forced_show () {
|
||
|
show.call(this, true);
|
||
|
}
|
||
|
function hide (e) {
|
||
|
if (
|
||
|
!e ||
|
||
|
!e.target || //Called directly
|
||
|
(
|
||
|
e.target != this && //Clicked not on element itself
|
||
|
!(this.pickmeup.get(0).compareDocumentPosition(e.target) & 16) //And not o its children
|
||
|
)
|
||
|
) {
|
||
|
var pickmeup = this.pickmeup,
|
||
|
options = $(this).data('pickmeup-options');
|
||
|
if (options.hide() != false) {
|
||
|
pickmeup.hide();
|
||
|
$(document)
|
||
|
.off('mousedown touchstart', options.binded.hide)
|
||
|
.off('resize', options.binded.forced_show);
|
||
|
options.lastSel = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function update () {
|
||
|
var options = $(this).data('pickmeup-options');
|
||
|
$(document)
|
||
|
.off('mousedown', options.binded.hide)
|
||
|
.off('resize', options.binded.forced_show);
|
||
|
options.binded.forced_show();
|
||
|
}
|
||
|
function clear () {
|
||
|
var options = $(this).data('pickmeup-options');
|
||
|
if (options.mode != 'single') {
|
||
|
options.date = [];
|
||
|
options.lastSel = false;
|
||
|
options.binded.fill();
|
||
|
}
|
||
|
}
|
||
|
function prev (fill) {
|
||
|
if (typeof fill == 'undefined') {
|
||
|
fill = true;
|
||
|
}
|
||
|
var root = this.pickmeup;
|
||
|
var options = $(this).data('pickmeup-options');
|
||
|
if (root.hasClass('pmu-view-years')) {
|
||
|
options.current.addYears(-12);
|
||
|
} else if (root.hasClass('pmu-view-months')) {
|
||
|
options.current.addYears(-1);
|
||
|
} else if (root.hasClass('pmu-view-days')) {
|
||
|
options.current.addMonths(-1);
|
||
|
}
|
||
|
if (fill) {
|
||
|
options.binded.fill();
|
||
|
}
|
||
|
}
|
||
|
function next (fill) {
|
||
|
if (typeof fill == 'undefined') {
|
||
|
fill = true;
|
||
|
}
|
||
|
var root = this.pickmeup;
|
||
|
var options = $(this).data('pickmeup-options');
|
||
|
if (root.hasClass('pmu-view-years')) {
|
||
|
options.current.addYears(12);
|
||
|
} else if (root.hasClass('pmu-view-months')) {
|
||
|
options.current.addYears(1);
|
||
|
} else if (root.hasClass('pmu-view-days')) {
|
||
|
options.current.addMonths(1);
|
||
|
}
|
||
|
if (fill) {
|
||
|
options.binded.fill();
|
||
|
}
|
||
|
}
|
||
|
function get_date (formatted) {
|
||
|
var options = $(this).data('pickmeup-options'),
|
||
|
prepared_date = prepareDate(options);
|
||
|
if (typeof formatted === 'string') {
|
||
|
var date = prepared_date[1];
|
||
|
if (date.constructor == Date) {
|
||
|
return formatDate(date, formatted, options.locale)
|
||
|
} else {
|
||
|
return date.map(function (value) {
|
||
|
return formatDate(value, formatted, options.locale);
|
||
|
});
|
||
|
}
|
||
|
} else {
|
||
|
return prepared_date[formatted ? 0 : 1];
|
||
|
}
|
||
|
}
|
||
|
function set_date (date) {
|
||
|
var $this = $(this),
|
||
|
options = $this.data('pickmeup-options');
|
||
|
options.date = date;
|
||
|
if (typeof options.date === 'string') {
|
||
|
options.date = parseDate(options.date, options.format, options.separator, options.locale).setHours(0,0,0,0);
|
||
|
} else if (options.date.constructor == Date) {
|
||
|
options.date.setHours(0,0,0,0);
|
||
|
}
|
||
|
if (!options.date) {
|
||
|
options.date = new Date;
|
||
|
options.date.setHours(0,0,0,0);
|
||
|
}
|
||
|
if (options.mode != 'single') {
|
||
|
if (options.date.constructor != Array) {
|
||
|
options.date = [options.date.valueOf()];
|
||
|
if (options.mode == 'range') {
|
||
|
options.date.push(((new Date(options.date[0])).setHours(0,0,0,0)).valueOf());
|
||
|
}
|
||
|
} else {
|
||
|
for (var i = 0; i < options.date.length; i++) {
|
||
|
options.date[i] = (parseDate(options.date[i], options.format, options.separator, options.locale).setHours(0,0,0,0)).valueOf();
|
||
|
}
|
||
|
if (options.mode == 'range') {
|
||
|
options.date[1] = ((new Date(options.date[1])).setHours(0,0,0,0)).valueOf();
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if($this.val() || options.default_date !== false) {
|
||
|
options.date = options.date.constructor == Array ? options.date[0].valueOf() : options.date.valueOf();
|
||
|
}
|
||
|
}
|
||
|
options.current = new Date (options.mode != 'single' ? options.date[0] : options.date);
|
||
|
options.binded.fill();
|
||
|
if ($this.is('input')) {
|
||
|
var prepared_date = prepareDate(options);
|
||
|
$this.val(
|
||
|
options.mode == 'single'
|
||
|
? (options.default_date === false ? $this.val() : prepared_date[0])
|
||
|
: prepared_date[0].join(options.separator)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
function destroy () {
|
||
|
var $this = $(this),
|
||
|
options = $this.data('pickmeup-options');
|
||
|
$this.removeData('pickmeup-options');
|
||
|
$this.off(options.events_namespace);
|
||
|
$(document).off(options.events_namespace);
|
||
|
$(this.pickmeup).remove();
|
||
|
}
|
||
|
$.fn.pickmeup = function (initial_options) {
|
||
|
if (typeof initial_options === 'string') {
|
||
|
var data,
|
||
|
parameters = Array.prototype.slice.call(arguments, 1);
|
||
|
switch (initial_options) {
|
||
|
case 'hide':
|
||
|
case 'show':
|
||
|
case 'clear':
|
||
|
case 'update':
|
||
|
case 'prev':
|
||
|
case 'next':
|
||
|
case 'destroy':
|
||
|
this.each(function () {
|
||
|
data = $(this).data('pickmeup-options');
|
||
|
if (data) {
|
||
|
data.binded[initial_options]();
|
||
|
}
|
||
|
});
|
||
|
break;
|
||
|
case 'get_date':
|
||
|
data = this.data('pickmeup-options');
|
||
|
if (data) {
|
||
|
return data.binded.get_date(parameters[0]);
|
||
|
} else {
|
||
|
return null;
|
||
|
}
|
||
|
break;
|
||
|
case 'set_date':
|
||
|
this.each(function () {
|
||
|
data = $(this).data('pickmeup-options');
|
||
|
if (data) {
|
||
|
data.binded[initial_options].apply(this, parameters);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
return this;
|
||
|
}
|
||
|
return this.each(function () {
|
||
|
var $this = $(this);
|
||
|
if ($this.data('pickmeup-options')) {
|
||
|
return;
|
||
|
}
|
||
|
var i,
|
||
|
option,
|
||
|
options = $.extend({}, $.pickmeup, initial_options || {});
|
||
|
for (i in options) {
|
||
|
option = $this.data('pmu-' + i);
|
||
|
if (typeof option !== 'undefined') {
|
||
|
options[i] = option;
|
||
|
}
|
||
|
}
|
||
|
// 4 conditional statements in order to account all cases
|
||
|
if (options.view == 'days' && !options.select_day) {
|
||
|
options.view = 'months';
|
||
|
}
|
||
|
if (options.view == 'months' && !options.select_month) {
|
||
|
options.view = 'years';
|
||
|
}
|
||
|
if (options.view == 'years' && !options.select_year) {
|
||
|
options.view = 'days';
|
||
|
}
|
||
|
if (options.view == 'days' && !options.select_day) {
|
||
|
options.view = 'months';
|
||
|
}
|
||
|
options.calendars = Math.max(1, parseInt(options.calendars, 10) || 1);
|
||
|
options.mode = /single|multiple|range/.test(options.mode) ? options.mode : 'single';
|
||
|
if (typeof options.min === 'string') {
|
||
|
options.min = parseDate(options.min, options.format, options.separator, options.locale).setHours(0,0,0,0);
|
||
|
} else if (options.min && options.min.constructor == Date) {
|
||
|
options.min.setHours(0,0,0,0);
|
||
|
}
|
||
|
if (typeof options.max === 'string') {
|
||
|
options.max = parseDate(options.max, options.format, options.separator, options.locale).setHours(0,0,0,0);
|
||
|
} else if (options.max && options.max.constructor == Date) {
|
||
|
options.max.setHours(0,0,0,0);
|
||
|
}
|
||
|
if (!options.select_day) {
|
||
|
if (options.min) {
|
||
|
options.min = new Date(options.min);
|
||
|
options.min.setDate(1);
|
||
|
options.min = options.min.valueOf();
|
||
|
}
|
||
|
if (options.max) {
|
||
|
options.max = new Date(options.max);
|
||
|
options.max.setDate(1);
|
||
|
options.max = options.max.valueOf();
|
||
|
}
|
||
|
}
|
||
|
if (typeof options.date === 'string') {
|
||
|
options.date = parseDate(options.date, options.format, options.separator, options.locale).setHours(0,0,0,0);
|
||
|
} else if (options.date.constructor == Date) {
|
||
|
options.date.setHours(0,0,0,0);
|
||
|
}
|
||
|
if (!options.date) {
|
||
|
options.date = new Date;
|
||
|
options.date.setHours(0,0,0,0);
|
||
|
}
|
||
|
if (options.mode != 'single') {
|
||
|
if (options.date.constructor != Array) {
|
||
|
options.date = [options.date.valueOf()];
|
||
|
if (options.mode == 'range') {
|
||
|
options.date.push(((new Date(options.date[0])).setHours(0,0,0,0)).valueOf());
|
||
|
}
|
||
|
} else {
|
||
|
for (i = 0; i < options.date.length; i++) {
|
||
|
options.date[i] = (parseDate(options.date[i], options.format, options.separator, options.locale).setHours(0,0,0,0)).valueOf();
|
||
|
}
|
||
|
if (options.mode == 'range') {
|
||
|
options.date[1] = ((new Date(options.date[1])).setHours(0,0,0,0)).valueOf();
|
||
|
}
|
||
|
}
|
||
|
options.current = new Date(options.date[0]);
|
||
|
// Set days to 1 in order to handle them consistently
|
||
|
if (!options.select_day) {
|
||
|
for (i = 0; i < options.date.length; ++i) {
|
||
|
options.date[i] = new Date(options.date[i]);
|
||
|
options.date[i].setDate(1);
|
||
|
options.date[i] = options.date[i].valueOf();
|
||
|
// Remove duplicates
|
||
|
if (
|
||
|
options.mode != 'range' &&
|
||
|
options.date.indexOf(options.date[i]) !== i
|
||
|
) {
|
||
|
delete options.date.splice(i, 1);
|
||
|
--i;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
options.date = options.date.valueOf();
|
||
|
options.current = new Date(options.date);
|
||
|
if (!options.select_day) {
|
||
|
options.date = new Date(options.date);
|
||
|
options.date.setDate(1);
|
||
|
options.date = options.date.valueOf();
|
||
|
}
|
||
|
}
|
||
|
options.current.setDate(1);
|
||
|
options.current.setHours(0,0,0,0);
|
||
|
var cnt,
|
||
|
pickmeup = $(tpl.wrapper);
|
||
|
this.pickmeup = pickmeup;
|
||
|
if (options.class_name) {
|
||
|
pickmeup.addClass(options.class_name);
|
||
|
}
|
||
|
var html = '';
|
||
|
for (i = 0; i < options.calendars; i++) {
|
||
|
cnt = options.first_day;
|
||
|
html += tpl.head({
|
||
|
prev : options.prev,
|
||
|
next : options.next,
|
||
|
day : [
|
||
|
options.locale.daysMin[(cnt++) % 7],
|
||
|
options.locale.daysMin[(cnt++) % 7],
|
||
|
options.locale.daysMin[(cnt++) % 7],
|
||
|
options.locale.daysMin[(cnt++) % 7],
|
||
|
options.locale.daysMin[(cnt++) % 7],
|
||
|
options.locale.daysMin[(cnt++) % 7],
|
||
|
options.locale.daysMin[(cnt++) % 7]
|
||
|
]
|
||
|
});
|
||
|
}
|
||
|
$this.data('pickmeup-options', options);
|
||
|
for (i in options) {
|
||
|
if (['render', 'change', 'before_show', 'show', 'hide'].indexOf(i) != -1) {
|
||
|
options[i] = options[i].bind(this);
|
||
|
}
|
||
|
}
|
||
|
options.binded = {
|
||
|
fill : fill.bind(this),
|
||
|
update_date : update_date.bind(this),
|
||
|
click : click.bind(this),
|
||
|
show : show.bind(this),
|
||
|
forced_show : forced_show.bind(this),
|
||
|
hide : hide.bind(this),
|
||
|
update : update.bind(this),
|
||
|
clear : clear.bind(this),
|
||
|
prev : prev.bind(this),
|
||
|
next : next.bind(this),
|
||
|
get_date : get_date.bind(this),
|
||
|
set_date : set_date.bind(this),
|
||
|
destroy : destroy.bind(this)
|
||
|
};
|
||
|
options.events_namespace = '.pickmeup-' + (++instances_count);
|
||
|
pickmeup
|
||
|
.on('click touchstart', options.binded.click)
|
||
|
.addClass(views[options.view])
|
||
|
.append(html)
|
||
|
.on(
|
||
|
$.support.selectstart ? 'selectstart' : 'mousedown',
|
||
|
function(e){
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
);
|
||
|
options.binded.fill();
|
||
|
if (options.flat) {
|
||
|
pickmeup.appendTo(this).css({
|
||
|
position : 'relative',
|
||
|
display : 'inline-block'
|
||
|
});
|
||
|
} else {
|
||
|
pickmeup.appendTo(document.body);
|
||
|
// Multiple events support
|
||
|
var trigger_event = options.trigger_event.split(' ');
|
||
|
for (i = 0; i < trigger_event.length; ++i) {
|
||
|
trigger_event[i] += options.events_namespace;
|
||
|
}
|
||
|
trigger_event = trigger_event.join(' ');
|
||
|
$this.on(trigger_event, options.binded.show);
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
}));
|