我成功使用了 TigraCalendar - https://www.softcomplex.com/products/tigra_calendar。但是只有 Datepicker。相反,我需要 Timepicker(选择小时和分钟的机会)。
真诚地说。我需要本地化 JS 日历的语言。由于 TigraCalendar,这是可能的。但没有机会选择小时和分钟。我也不喜欢 JQuery 日历样式。
是否可以自定义 TigraCalendar?或者,也许有人知道其他带有时间选择器和语言本地化的日历。
这是他们的代码。
// Tigra Calendar v5.2 (11/20/2011)
// http://www.softcomplex.com/products/tigra_calendar/
// License: Public Domain... You're welcome.
// default settins - this structure can be moved in separate file in multilangual applications
var A_TCALCONF = {
'cssprefix' : 'tcal',
'months' : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
'weekdays' : ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
'longwdays' : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
'yearscroll' : true, // show year scroller
'weekstart' : 0, // first day of week: 0-Su or 1-Mo
'prevyear' : 'Previous Year',
'nextyear' : 'Next Year',
'prevmonth' : 'Previous Month',
'nextmonth' : 'Next Month',
'format' : 'm/d/Y' // 'd-m-Y', Y-m-d', 'l, F jS Y'
};
var A_TCALTOKENS = [
// A full numeric representation of a year, 4 digits
{'t': 'Y', 'r': '19\\d{2}|20\\d{2}', 'p': function (d_date, n_value) { d_date.setFullYear(Number(n_value)); return d_date; }, 'g': function (d_date) { var n_year = d_date.getFullYear(); return n_year; }},
// Numeric representation of a month, with leading zeros
{'t': 'm', 'r': '0?[1-9]|1[0-2]', 'p': function (d_date, n_value) { d_date.setMonth(Number(n_value) - 1); return d_date; }, 'g': function (d_date) { var n_month = d_date.getMonth() + 1; return (n_month < 10 ? '0' : '') + n_month }},
// A full textual representation of a month, such as January or March
{'t': 'F', 'r': A_TCALCONF.months.join('|'), 'p': function (d_date, s_value) { for (var m = 0; m < 12; m++) if (A_TCALCONF.months[m] == s_value) { d_date.setMonth(m); return d_date; }}, 'g': function (d_date) { return A_TCALCONF.months[d_date.getMonth()]; }},
// Day of the month, 2 digits with leading zeros
{'t': 'd', 'r': '0?[1-9]|[12][0-9]|3[01]', 'p': function (d_date, n_value) { d_date.setDate(Number(n_value)); if (d_date.getDate() != n_value) d_date.setDate(0); return d_date }, 'g': function (d_date) { var n_date = d_date.getDate(); return (n_date < 10 ? '0' : '') + n_date; }},
// Day of the month without leading zeros
{'t': 'j', 'r': '0?[1-9]|[12][0-9]|3[01]', 'p': function (d_date, n_value) { d_date.setDate(Number(n_value)); if (d_date.getDate() != n_value) d_date.setDate(0); return d_date }, 'g': function (d_date) { var n_date = d_date.getDate(); return n_date; }},
// A full textual representation of the day of the week
{'t': 'l', 'r': A_TCALCONF.longwdays.join('|'), 'p': function (d_date, s_value) { return d_date }, 'g': function (d_date) { return A_TCALCONF.longwdays[d_date.getDay()]; }},
// English ordinal suffix for the day of the month, 2 characters
{'t': 'S', 'r': 'st|nd|rd|th', 'p': function (d_date, s_value) { return d_date }, 'g': function (d_date) { n_date = d_date.getDate(); if (n_date % 10 == 1 && n_date != 11) return 'st'; if (n_date % 10 == 2 && n_date != 12) return 'nd'; if (n_date % 10 == 3 && n_date != 13) return 'rd'; return 'th'; }}
];
function f_tcalGetHTML (d_date) {
var e_input = f_tcalGetInputs(true);
if (!e_input) return;
var s_pfx = A_TCALCONF.cssprefix,
s_format = A_TCALCONF.format;
// today from config or client date
var d_today = f_tcalParseDate(A_TCALCONF.today, A_TCALCONF.format);
if (!d_today)
d_today = f_tcalResetTime(new Date());
// selected date from input or config or today
var d_selected = f_tcalParseDate(e_input.value, s_format);
if (!d_selected)
d_selected = f_tcalParseDate(A_TCALCONF.selected, A_TCALCONF.format);
if (!d_selected)
d_selected = new Date(d_today);
// show calendar for passed or selected date
d_date = d_date ? f_tcalResetTime(d_date) : new Date(d_selected);
var d_firstDay = new Date(d_date);
d_firstDay.setDate(1);
d_firstDay.setDate(1 - (7 + d_firstDay.getDay() - A_TCALCONF.weekstart) % 7);
var a_class, s_html = '<table id="' + s_pfx + 'Controls"><tbody><tr>'
+ (A_TCALCONF.yearscroll ? '<td id="' + s_pfx + 'PrevYear" ' + f_tcalRelDate(d_date, -1, 'y') + ' title="' + A_TCALCONF.prevyear + '"></td>' : '')
+ '<td id="' + s_pfx + 'PrevMonth"' + f_tcalRelDate(d_date, -1) + ' title="' + A_TCALCONF.prevmonth + '"></td><th>'
+ A_TCALCONF.months[d_date.getMonth()] + ' ' + d_date.getFullYear()
+ '</th><td id="' + s_pfx + 'NextMonth"' + f_tcalRelDate(d_date, 1) + ' title="' + A_TCALCONF.nextmonth + '"></td>'
+ (A_TCALCONF.yearscroll ? '<td id="' + s_pfx + 'NextYear"' + f_tcalRelDate(d_date, 1, 'y') + ' title="' + A_TCALCONF.nextyear + '"></td>' : '')
+ '</tr></tbody></table><table id="' + s_pfx + 'Grid"><tbody><tr>';
// print weekdays titles
for (var i = 0; i < 7; i++)
s_html += '<th>' + A_TCALCONF.weekdays[(A_TCALCONF.weekstart + i) % 7] + '</th>';
s_html += '</tr>' ;
// print calendar table
var n_date, n_month, d_current = new Date(d_firstDay);
while (d_current.getMonth() == d_date.getMonth() ||
d_current.getMonth() == d_firstDay.getMonth()) {
s_html +='<tr>';
for (var n_wday = 0; n_wday < 7; n_wday++) {
a_class = [];
n_date = d_current.getDate();
n_month = d_current.getMonth();
if (d_current.getMonth() != d_date.getMonth())
a_class[a_class.length] = s_pfx + 'OtherMonth';
if (d_current.getDay() == 0 || d_current.getDay() == 6)
a_class[a_class.length] = s_pfx + 'Weekend';
if (d_current.valueOf() == d_today.valueOf())
a_class[a_class.length] = s_pfx + 'Today';
if (d_current.valueOf() == d_selected.valueOf())
a_class[a_class.length] = s_pfx + 'Selected';
s_html += '<td' + f_tcalRelDate(d_current) + (a_class.length ? ' class="' + a_class.join(' ') + '">' : '>') + n_date + '</td>';
d_current.setDate(++n_date);
}
s_html +='</tr>';
}
s_html +='</tbody></table>';
return s_html;
}
function f_tcalRelDate (d_date, d_diff, s_units) {
var s_units = (s_units == 'y' ? 'FullYear' : 'Month');
var d_result = new Date(d_date);
if (d_diff) {
d_result['set' + s_units](d_date['get' + s_units]() + d_diff);
if (d_result.getDate() != d_date.getDate())
d_result.setDate(0);
}
return ' onclick="f_tcalUpdate(' + d_result.valueOf() + (d_diff ? ',1' : '') + ')"';
}
function f_tcalResetTime (d_date) {
d_date.setMilliseconds(0);
d_date.setSeconds(0);
d_date.setMinutes(0);
d_date.setHours(12);
return d_date;
}
// closes calendar and returns all inputs to default state
function f_tcalCancel () {
var s_pfx = A_TCALCONF.cssprefix;
var e_cal = document.getElementById(s_pfx);
if (e_cal)
e_cal.style.visibility = '';
var a_inputs = f_tcalGetInputs();
for (var n = 0; n < a_inputs.length; n++)
f_tcalRemoveClass(a_inputs[n], s_pfx + 'Active');
}
function f_tcalUpdate (n_date, b_keepOpen) {
var e_input = f_tcalGetInputs(true);
if (!e_input) return;
d_date = new Date(n_date);
var s_pfx = A_TCALCONF.cssprefix;
if (b_keepOpen) {
var e_cal = document.getElementById(s_pfx);
if (!e_cal || e_cal.style.visibility != 'visible') return;
e_cal.innerHTML = f_tcalGetHTML(d_date, e_input);
}
else {
e_input.value = f_tcalGenerateDate(d_date, A_TCALCONF.format);
f_tcalCancel();
}
}
function f_tcalOnClick () {
// see if already opened
var s_pfx = A_TCALCONF.cssprefix;
var s_activeClass = s_pfx + 'Active';
var b_close = f_tcalHasClass(this, s_activeClass);
// close all clalendars
f_tcalCancel();
if (b_close) return;
// get position of input
f_tcalAddClass(this, s_activeClass);
var n_left = f_getPosition (this, 'Left'),
n_top = f_getPosition (this, 'Top') + this.offsetHeight;
var e_cal = document.getElementById(s_pfx);
if (!e_cal) {
e_cal = document.createElement('div');
e_cal.onselectstart = function () { return false };
e_cal.id = s_pfx;
document.getElementsByTagName("body").item(0).appendChild(e_cal);
}
e_cal.innerHTML = f_tcalGetHTML(null);
e_cal.style.top = n_top + 'px';
e_cal.style.left = (n_left + this.offsetWidth - e_cal.offsetWidth) + 'px';
e_cal.style.visibility = 'visible';
}
function f_tcalParseDate (s_date, s_format) {
if (!s_date) return;
var s_char, s_regexp = '^', a_tokens = {}, a_options, n_token = 0;
for (var n = 0; n < s_format.length; n++) {
s_char = s_format.charAt(n);
if (A_TCALTOKENS_IDX[s_char]) {
a_tokens[s_char] = ++n_token;
s_regexp += '(' + A_TCALTOKENS_IDX[s_char]['r'] + ')';
}
else if (s_char == ' ')
s_regexp += '\\s';
else
s_regexp += (s_char.match(/[\w\d]/) ? '' : '\\') + s_char;
}
var r_date = new RegExp(s_regexp + '$');
if (!s_date.match(r_date)) return;
var s_val, d_date = f_tcalResetTime(new Date());
d_date.setDate(1);
for (n = 0; n < A_TCALTOKENS.length; n++) {
s_char = A_TCALTOKENS[n]['t'];
if (!a_tokens[s_char])
continue;
s_val = RegExp['$' + a_tokens[s_char]];
d_date = A_TCALTOKENS[n]['p'](d_date, s_val);
}
return d_date;
}
function f_tcalGenerateDate (d_date, s_format) {
var s_char, s_date = '';
for (var n = 0; n < s_format.length; n++) {
s_char = s_format.charAt(n);
s_date += A_TCALTOKENS_IDX[s_char] ? A_TCALTOKENS_IDX[s_char]['g'](d_date) : s_char;
}
return s_date;
}
function f_tcalGetInputs (b_active) {
var a_inputs = document.getElementsByTagName('input'),
e_input, s_rel, a_result = [];
for (n = 0; n < a_inputs.length; n++) {
e_input = a_inputs[n];
if (!e_input.type || e_input.type != 'text')
continue;
if (!f_tcalHasClass(e_input, 'tcal'))
continue;
if (b_active && f_tcalHasClass(e_input, A_TCALCONF.cssprefix + 'Active'))
return e_input;
a_result[a_result.length] = e_input;
}
return b_active ? null : a_result;
}
function f_tcalHasClass (e_elem, s_class) {
var s_classes = e_elem.className;
if (!s_classes)
return false;
var a_classes = s_classes.split(' ');
for (var n = 0; n < a_classes.length; n++)
if (a_classes[n] == s_class)
return true;
return false;
}
function f_tcalAddClass (e_elem, s_class) {
if (f_tcalHasClass (e_elem, s_class))
return;
var s_classes = e_elem.className;
e_elem.className = (s_classes ? s_classes + ' ' : '') + s_class;
}
function f_tcalRemoveClass (e_elem, s_class) {
var s_classes = e_elem.className;
if (!s_classes || s_classes.indexOf(s_class) == -1)
return false;
var a_classes = s_classes.split(' '),
a_newClasses = [];
for (var n = 0; n < a_classes.length; n++) {
if (a_classes[n] == s_class)
continue;
a_newClasses[a_newClasses.length] = a_classes[n];
}
e_elem.className = a_newClasses.join(' ');
return true;
}
function f_getPosition (e_elemRef, s_coord) {
var n_pos = 0, n_offset,
e_elem = e_elemRef;
while (e_elem) {
n_offset = e_elem["offset" + s_coord];
n_pos += n_offset;
e_elem = e_elem.offsetParent;
}
e_elem = e_elemRef;
while (e_elem != document.body) {
n_offset = e_elem["scroll" + s_coord];
if (n_offset && e_elem.style.overflow == 'scroll')
n_pos -= n_offset;
e_elem = e_elem.parentNode;
}
return n_pos;
}
function f_tcalInit () {
if (!document.getElementsByTagName)
return;
var e_input, a_inputs = f_tcalGetInputs();
for (var n = 0; n < a_inputs.length; n++) {
e_input = a_inputs[n];
e_input.onclick = f_tcalOnClick;
f_tcalAddClass(e_input, A_TCALCONF.cssprefix + 'Input');
}
window.A_TCALTOKENS_IDX = {};
for (n = 0; n < A_TCALTOKENS.length; n++)
A_TCALTOKENS_IDX[A_TCALTOKENS[n]['t']] = A_TCALTOKENS[n];
}
function f_tcalAddOnload (f_func) {
if (document.addEventListener) {
window.addEventListener('load', f_func, false);
}
else if (window.attachEvent) {
window.attachEvent('onload', f_func);
}
else {
var f_onLoad = window.onload;
if (typeof window.onload != 'function') {
window.onload = f_func;
}
else {
window.onload = function() {
f_onLoad();
f_func();
}
}
}
}
f_tcalAddOnload (f_tcalInit);
/*
Stylesheet for Tigra Calendar v5.0
Product is Public Domain (Free for any kind of applicaiton, customization and derivative works are allowed)
URL: http://www.softcomplex.com/products/tigra_calendar/
- all image paths are relative to path of stylesheet
- the styles below can be moved into the document or in existing stylesheet
*/
/* input box in default state */
.tcalInput {
background: url('img/cal.gif') 100% 50% no-repeat;
padding-right: 20px;
cursor: pointer;
}
/* additional properties for input boxe in activated state, above still applies unless in conflict */
.tcalActive {
background-image: url('img/no_cal.gif');
}
/* container of calendar's pop-up */
#tcal {
position: absolute;
visibility: hidden;
z-index: 100;
width: 170px;
background-color: white;
margin-top: 2px;
padding: 0 2px 2px 2px;
border: 1px solid silver;
-moz-box-shadow: 3px 3px 4px silver;
-webkit-box-shadow: 3px 3px 4px silver;
box-shadow: 3px 3px 4px silver;
-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='silver')";
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='silver');
}
/* table containing navigation and current month */
#tcalControls {
border-collapse: collapse;
border: 0;
width: 100%;
}
#tcalControls td {
border-collapse: collapse;
border: 0;
padding: 0;
width: 16px;
background-position: 50% 50%;
background-repeat: no-repeat;
cursor: pointer;
}
#tcalControls th {
border-collapse: collapse;
border: 0;
padding: 0;
line-height: 25px;
font-size: 10px;
text-align: center;
font-family: Tahoma, Geneva, sans-serif;
font-weight: bold;
white-space: nowrap;
}
#tcalPrevYear { background-image: url('img/prev_year.gif'); }
#tcalPrevMonth { background-image: url('img/prev_mon.gif'); }
#tcalNextMonth { background-image: url('img/next_mon.gif'); }
#tcalNextYear { background-image: url('img/next_year.gif'); }
/* table containing week days header and calendar grid */
#tcalGrid {
border-collapse: collapse;
border: 1px solid silver;
width: 100%;
}
#tcalGrid th {
border: 1px solid silver;
border-collapse: collapse;
padding: 3px 0;
text-align: center;
font-family: Tahoma, Geneva, sans-serif;
font-size: 10px;
background-color: gray;
color: white;
}
#tcalGrid td {
border: 0;
border-collapse: collapse;
padding: 2px 0;
text-align: center;
font-family: Tahoma, Geneva, sans-serif;
width: 14%;
font-size: 11px;
cursor: pointer;
}
#tcalGrid td.tcalOtherMonth { color: silver; }
#tcalGrid td.tcalWeekend { background-color: #ACD6F5; }
#tcalGrid td.tcalToday { border: 1px solid red; }
#tcalGrid td.tcalSelected { background-color: #FFB3BE; }
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
<title>Simple Tigra Calendar</title>
<!-- link calendar resources -->
<link rel="stylesheet" type="text/css" href="tcal.css" />
<script type="text/javascript" src="tcal.js"></script>
</head>
<body>
<form action="#">
<!-- add class="tcal" to your input field -->
<div><input type="text" name="date" class="tcal" value="" /></div>
</form>
</body>
</html>