www.legu.cc/public/js/datePicker/datePicker.js
2021-09-06 11:50:33 +08:00

840 lines
20 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* PHPWind util Library
* @Copyright : Copyright 2011, phpwind.com
* @Descript : datePicker 日历组件
* @Author : jquerytools (http://jquerytools.org/demos/dateinput/)
* @Modify : chaoren1641@gmail.com
* @Depend : jquery.js(1.7 or later)
* $Id: datePicker.js 22586 2012-12-25 10:54:55Z hao.lin $ :
*/
;(function($, window, document, undefined) {
var pluginName = 'datePicker';
var instances = [];
// h=72, j=74, k=75, l=76, down=40, left=37, up=38, right=39
var KEYS = [75, 76, 38, 39, 74, 72, 40, 37], LABELS = {};
var defaults = {
format : 'yyyy-mm-dd',
selectors : true,
time : false,
yearRange : [-200, 200],
lang : 'zh-CN',
offset : [0, 0],
speed : 0,
firstDay : 0, // The first day of the week, Sun = 0, Mon = 1, ...
min : undefined,
max : undefined,
trigger : false,
css : {
prefix : 'cal',
input : 'date',
// ids
root : 0,
head : 0,
title : 0,
prev : 0,
next : 0,
month : 0,
year : 0,
days : 0,
body : 0,
weeks : 0,
today : 0,
current : 0,
// classnames
week : 0,
off : 0,
sunday : 0,
focus : 0,
disabled : 0,
trigger : 0
}
};
var localize = function(language, labels) {
$.each(labels, function(key, val) {
labels[key] = val.split(",");
});
LABELS[language] = labels;
};
//多语言配置
localize("en", {
months : 'January,February,March,April,May,June,July,August,September,October,November,December',
shortMonths : 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec',
days : 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday',
shortDays : 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'
});
localize("zh-CN", {
months : '一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月',
shortMonths : '一,二,三,四,五,六,七,八,九,十,十一,十二',
days : '周日,周一,周二,周三,周四,周五,周六',
shortDays : '日,一,二,三,四,五,六'
});
//{{{ private functions
//返回某年某月的天数
function dayAm(year, month) {
return 32 - new Date(year, month, 32).getDate();
}
function zeropad(val, len) {
val = '' + val;
len = len || 2;
while(val.length < len) {
val = "0" + val;
}
return val;
}
// thanks: http://stevenlevithan.com/assets/misc/date.format.js
var Re = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, tmpTag = $("<a/>");
//格式化时间
function format(date, fmt, lang) {
var d = date.getDate(), D = date.getDay(), m = date.getMonth(), y = date.getFullYear(),
h = date.getHours(),M = date.getMinutes(),
flags = {
d : d,
dd : zeropad(d),
ddd : LABELS[lang].shortDays[D],
dddd : LABELS[lang].days[D],
m : m + 1,
mm : zeropad(m + 1),
mmm : LABELS[lang].shortMonths[m],
mmmm : LABELS[lang].months[m],
yy : String(y).slice(2),
yyyy : y,
HH: zeropad(h),
MM : zeropad(M)
};
var ret = fmt.replace(Re, function($0) {
return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
});
// a small trick to handle special characters
return tmpTag.html(ret).html();
}
function integer(val) {
return parseInt(val, 10);
}
function isSameDay(d1, d2) {
return d1.getFullYear() === d2.getFullYear() && d1.getMonth() == d2.getMonth() && d1.getDate() == d2.getDate();
}
function parseDate(val) {
if(!val) {
return;
}
if(val.constructor == Date) {
return val;
}
if( typeof val == 'string') {
// rfc3339?
var els = val.split(" ");
var date,time;
var y,m,d,h,s;
date = els[0].split('-');
if(date.length !== 3) {
return;
}
if(els.length === 2) {
time = els[1].split(':');
}else {
time = '00:00'.split(':');
}
y = date[0],m = date[1]-1,d = date[2];
h = time[0],s = time[1];
return new Date(y,m,d,h,s,0);
// invalid offset
if(!/^-?\d+$/.test(val)) {
return;
}
// convert to integer
val = integer(val);
}
var date = new Date();
date.setDate(date.getDate() + val);
return date;
}
function Plugin( input, options ) {
this.options = $.extend( {}, defaults, options) ;
this.input = input;
this.init();
}
Plugin.prototype.init = function() {
var options = this.options,input = this.input;
if(options.time) {
options.format = 'yyyy-mm-dd HH:MM'
}
// CSS prefix
$.each(options.css, function(key, val) {
if(!val && key != 'prefix') {
options.css[key] = (options.css.prefix || '') + (val || key);
}
});
// variables
var self = this, now = new Date(), css = options.css, labels = LABELS[options.lang], root = $("#" + css.root), title = root.find("#" + css.title), trigger, pm, nm, currYear, currMonth, currDay, value = input.attr("data-value") || options.value || input.val(), min = input.attr("min") || options.min, max = input.attr("max") || options.max, opened;
// zero min is not undefined
if(min === 0) {
min = "0";
}
// use sane values for value, min & max
value = parseDate(value) || now;
min = parseDate(min || options.yearRange[0] * 365);
max = parseDate(max || options.yearRange[1] * 365);
// check that language exists
if(!labels) {
throw "不存在的语言: " + options.lang;
}
// Replace built-in date input: NOTE: input.attr("type", "text") throws exception by the browser
if(input.attr("type") === 'date') {
var tmp = $("<input/>");
$.each("class,disabled,id,maxlength,name,readonly,required,size,style,tabindex,title,value".split(","), function(i, attr) {
tmp.attr(attr, input.attr(attr));
});
input.replaceWith(tmp);
input = tmp;
}
input.addClass(css.input);
var fire = input.add(self);
// construct layout
if(!root.length) {
// root
root = $('<div><div><a/><div/><a/></div><div><div/><div/></div></div>').hide().css({
position : 'absolute'
}).attr("id", css.root);
// elements
root.children().eq(0).attr("id", css.head).end().eq(1).attr("id", css.body).children().eq(0).attr("id", css.days).end().eq(1).attr("id", css.weeks).end().end().end().find("a").eq(0).attr("id", css.prev).end().eq(1).attr("id", css.next);
// title
title = root.find("#" + css.head).find("div").attr("id", css.title);
// year & month selectors
if(options.selectors) {
var monthSelector = $("<select/>").attr("id", css.month), yearSelector = $("<select/>").attr("id", css.year);
title.html(monthSelector.add(yearSelector));
}
// day titles
var days = root.find("#" + css.days);
// days of the week
for(var d = 0; d < 7; d++) {
days.append($("<span/>").text(labels.shortDays[(d + options.firstDay) % 7]));
}
var body = root.find("#" + css.body);
$('<div class="caltime"><button type="button" class="btn btn_submit fr" name="submit">确认</button><input id="calHour" type="number" class="input" min="0" max="23" size="2" value="0"><span>点</span><input id="calMin" class="input" type="number" size="2" min="1" max="59" value="0"><span>分</span></div>').appendTo(body);
$("body").append(root);
}
// trigger icon
if(options.trigger) {
trigger = $("<a/>").attr("href", "#").addClass(css.trigger).click(function(e) {
self.show();
return e.preventDefault();
}).insertAfter(input);
}
// layout elements
var weeks = root.find("#" + css.weeks);
yearSelector = root.find("#" + css.year);
monthSelector = root.find("#" + css.month);
//{{{ pick
function select(date, options, e) {
if(!date) return;
// current value
value = date;
currYear = date.getFullYear();
currMonth = date.getMonth();
currDay = date.getDate();
if (e.type == "click" && $.browser && !$.browser.msie) {
input.focus();
}
// select
e = e || $.Event("api");
e.type = "select";
fire.trigger(e, [date]);
if(e.isDefaultPrevented()) {
return;
}
//如果选项有时间,则加上时间
if(options.time) {
var timeInput = root.find('input');
var hour = parseInt(timeInput.eq(0).val(),10);
var min = parseInt(timeInput.eq(1).val(),10);
if(isNaN(hour)) {
hour = 0;
}
if(isNaN(min)) {
min = 0;
}
if(hour < 10) {
hour = '0' + hour;
}else if(hour < 0 || hour > 23) {
hour = '00';
}
if(min < 10) {
min = '0' + min;
}else if(min < 0 || min > 59) {
min = '00';
}
date.setHours(hour);
date.setMinutes(min);
}
// formatting
var date = format(date, options.format, options.lang);
input.val(date);
// store value into input
input.data("date", date);
//设置val后IE导致触发focus事件导致窗口关闭后再次被打开
setTimeout(function() {
self.hide(e);
},100);
}
//}}}
//{{{ onShow
function onShow(ev) {
ev.type = "onShow";
fire.trigger(ev);
//快捷键处理
$(document).bind("keydown.d", function(e) {
if(e.ctrlKey) {
return true;
}
var key = e.keyCode;
// backspace clears the value
if(e.target == input[0]) {//如果是在当前input按back键清除值并隐藏日历
if(key == 8 || key == 46) {
input.val("");
return self.hide(e);
}
}
// esc key
if(key == 27) {
return self.hide(e);
}
//如果有time则不要快捷键
if(options.time) {
return;
}
if($(KEYS).index(key) >= 0) {
if(!opened) {
self.show(e);
return e.preventDefault();
}
var days = $("#" + css.weeks + " a"), el = $("." + css.focus), index = days.index(el);
el.removeClass(css.focus);
if(key == 74 || key == 40) {
index += 7;
} else if(key == 75 || key == 38) {
index -= 7;
} else if(key == 76 || key == 39) {
index += 1;
} else if(key == 72 || key == 37) {
index -= 1;
}
if(index > 41) {
self.addMonth();
el = $("#" + css.weeks + " a:eq(" + (index - 42) + ")");
} else if(index < 0) {
self.addMonth(-1);
el = $("#" + css.weeks + " a:eq(" + (index + 42) + ")");
} else {
el = days.eq(index);
}
el.addClass(css.focus);
return e.preventDefault();
}
// pageUp / pageDown
if(key == 34) {
return self.addMonth();
}
if(key == 33) {
return self.addMonth(-1);
}
// home
if(key == 36) {
return self.today();
}
// enter
if(key == 13) {
if(!$(e.target).is("select")) {
$("." + css.focus).dblclick();
}
}
return $([16, 17, 18, 9]).index(key) >= 0;
});
// 点击外部关闭窗口
/*$(document).bind("mousedown.d", function(e) {
var el = e.target;
if(!$(el).parents("#" + css.root).length && el != input[0] && (!trigger || el != trigger[0])) {
self.hide(e);
}
});*/
$(document.body).on("mousedown.d", function(e) {
if(e.target !== input[0] && !$.contains(root[0],e.target)) {
setTimeout(function(){
self.hide();
},100)
}
});
}
//}}}
$.extend(self, {
//{{{ show
show : function(e) {
if(input.prop("readonly") || input.prop("disabled") || opened) {
return;
}
// onBeforeShow
e = e || $.Event();
e.type = "onBeforeShow";
fire.trigger(e);
if(e.isDefaultPrevented()) {
return;
}
$.each(instances, function() {
this.hide();
});
opened = true;
// 月份下拉菜单
monthSelector.unbind("change").change(function() {
self.setValue(yearSelector.val(), $(this).val());
});
// 年下拉菜单
yearSelector.unbind("change").change(function() {
self.setValue($(this).val(), monthSelector.val());
});
// 上一月/下一月按钮
pm = root.find("#" + css.prev).unbind("click").click(function(e) {
if(!pm.hasClass(css.disabled)) {
self.addMonth(-1);
}
return false;
});
nm = root.find("#" + css.next).unbind("click").click(function(e) {
if(!nm.hasClass(css.disabled)) {
self.addMonth();
}
return false;
});
// 设置日期
self.setValue(value);
//是否显示时间选择
if(options.time) {
root.find('div.caltime').show();
}else{
root.find('div.caltime').hide();
}
// show calendar
var pos = input.offset();
// iPad position fix
if(/iPad/i.test(navigator.userAgent)) {
pos.top -= $(window).scrollTop();
}
var top = pos.top + input.outerHeight() + options.offset[0];
if(top + root.height() > $(window).scrollTop() + $(window).height()) {
top = pos.top - root.height();
}
root.css({
top : top,
left : pos.left + options.offset[1]
});
if(options.speed) {
root.show(options.speed, function() {
onShow(e);
});
} else {
root.show();
onShow(e);
}
return self;
},
//}}}
//{{{ setValue
setValue : function(year, month, day, hour, minute) {
var date = integer(month) >= -1 ? new Date(integer(year), integer(month), integer(day || 1)) : year || value;
if(date < min) {
date = min;
} else if(date > max) {
date = max;
}
year = date.getFullYear();
month = date.getMonth();
day = date.getDate();
hour = date.getHours();
minute = date.getMinutes();
// roll year & month
if(month == -1) {
month = 11;
year--;
} else if(month == 12) {
month = 0;
year++;
}
if(!opened) {
select(date, options);
return self;
}
currMonth = month;
currYear = year;
// variables
var tmp = new Date(year, month, 1 - options.firstDay), begin = tmp.getDay(), days = dayAm(year, month), prevDays = dayAm(year, month - 1), week;
// selectors
if(options.selectors) {
// month selector
monthSelector.empty();
$.each(labels.months, function(i, m) {
if(min < new Date(year, i + 1, -1) && max > new Date(year, i, 0)) {
monthSelector.append($("<option/>").html(m).attr("value", i));
}
});
// year selector
yearSelector.empty();
var yearNow = now.getFullYear();
for(var i = yearNow + options.yearRange[0]; i < yearNow + options.yearRange[1]; i++) {
if(min <= new Date(i + 1, -1, 1) && max > new Date(i, 0, 0)) {
yearSelector.append($("<option/>").text(i));
}
}
monthSelector.val(month);
yearSelector.val(year);
// title
} else {
title.html(labels.months[month] + " " + year);
}
// populate weeks
weeks.empty();
pm.add(nm).removeClass(css.disabled);
// !begin === "sunday"
for(var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) {
a = $("<a/>");
if(j % 7 === 0) {
week = $("<div/>").addClass(css.week);
weeks.append(week);
}
if(j < begin) {
a.addClass(css.off);
num = prevDays - begin + j + 1;
date = new Date(year, month - 1, num);
} else if(j >= begin + days) {
a.addClass(css.off);
num = j - days - begin + 1;
date = new Date(year, month + 1, num);
} else {
num = j - begin + 1;
date = new Date(year, month, num);
// current date
if(isSameDay(value, date)) {
a.attr("id", css.current).addClass(css.focus);
// today
} else if(isSameDay(now, date)) {
a.attr("id", css.today);
}
}
// disabled
if(min && date < min) {
a.add(pm).addClass(css.disabled);
}
if(max && date > max) {
a.add(nm).addClass(css.disabled);
}
a.attr("href", "#" + num).text(num).data("date", date);
week.append(a);
if(options.selectors) {
//console.log(year, month, day, hour, minute)
}
}
//时间选择
//!TODO:chaoren1641增加有待重构
if(options.time) {
//如果有时间选项则点击确定或双击日期输入时间
// date picking
weeks.find("a").on('click',function(e) {
var el = $(this);
if(!el.hasClass(css.disabled)) {
$("#" + css.current).removeAttr("id");
el.attr("id", css.current);
}
return false;
}).off('dblclick').dblclick(function(e) {
var el = $(this);
if(!el.hasClass(css.disabled)) {
select(el.data("date"), options, e);
//在IE下重新赋值会引起focus导致日历控件再次激活打开所以setTimeout下
setTimeout(function() {
self.hide();
},100);
}
return false;
});
var body = root.find("#" + css.body);
body.find('button').off('click.d').on('click.d',function(e) {
var el = root.find('#' + css.current);
select(el.data("date"), options, e);
//在IE下重新赋值会引起focus导致日历控件再次激活打开所以setTimeout下
setTimeout(function() {
self.hide();
},100);
return false;
});
body.find('#calHour').val(hour);
body.find('#calMin').val(minute);
}else{
// date picking
weeks.find("a").click(function(e) {
var el = $(this);
if(!el.hasClass(css.disabled)) {
$("#" + css.current).removeAttr("id");
el.attr("id", css.current);
select(el.data("date"), options, e);
}
return false;
})
}
// sunday
if(css.sunday) {
weeks.find(css.week).each(function() {
var beg = options.firstDay ? 7 - options.firstDay : 0;
$(this).children().slice(beg, beg + 1).addClass(css.sunday);
});
}
return self;
},
//}}}
setMin : function(val, fit) {
min = parseDate(val);
if(fit && value < min) {
self.setValue(min);
}
return self;
},
setMax : function(val, fit) {
max = parseDate(val);
if(fit && value > max) {
self.setValue(max);
}
return self;
},
today : function() {
return self.setValue(now);
},
addDay : function(amount) {
return this.setValue(currYear, currMonth, currDay + (amount || 1));
},
addMonth : function(amount) {
return this.setValue(currYear, currMonth + (amount || 1), currDay);
},
addYear : function(amount) {
return this.setValue(currYear + (amount || 1), currMonth, currDay);
},
hide : function(e) {
if(opened) {
// onHide
e = $.Event();
e.type = "onHide";
fire.trigger(e);
$(document).unbind("click.d").unbind("keydown.d");
// cancelled ?
if(e.isDefaultPrevented()) {
return;
}
// do the hide
root.hide();
opened = false;
}
return self;
},
getConf : function() {
return options;
},
getInput : function() {
return input;
},
getCalendar : function() {
return root;
},
getValue : function(dateFormat) {
return dateFormat ? format(value, dateFormat, options.lang) : value;
},
isOpen : function() {
return opened;
}
});
// callbacks
$.each(['onBeforeShow', 'onShow', 'select', 'onHide'], function(i, name) {
// configuration
if($.isFunction(options[name])) {
$(self).bind(name, options[name]);
}
// API methods
self[name] = function(fn) {
if(fn) {
$(self).bind(name, fn);
}
return self;
};
});
// show dateinput & assign keyboard shortcuts
input.bind("focus click", self.show).keydown(function(e) {
var key = e.keyCode;
// open dateinput with navigation keyw
if(!opened && $(KEYS).index(key) >= 0) {
self.show(e);
return e.preventDefault();
}
// allow tab
return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault();
});
// initial value
if(parseDate(input.val())) {
//!TODO关闭初始化的值这里会出现BUG
//select(value, options);
}
};
$.expr[':'].date = function(el) {
var type = el.getAttribute("type");
return type && type == 'date' || !!$(el).data("dateinput");
};
$.fn[pluginName] = function(options) {
Wind.css('datePicker');
return this.each(function() {
if(!$.data(this, 'plugin_' + pluginName)) {
var instance = new Plugin($(this), options);
instances.push(instance);
$.data(this, 'plugin_' + pluginName, instance);
}
});
};
/*$.fn.dateinput = function(conf) {
// already instantiated
if(this.data("dateinput")) {
return this;
}
// configuration
conf = $.extend(true, {}, tool.conf, conf);
// CSS prefix
$.each(conf.css, function(key, val) {
if(!val && key != 'prefix') {
conf.css[key] = (conf.css.prefix || '') + (val || key);
}
});
var els;
this.each(function() {
var el = new Dateinput($(this), conf);
instances.push(el);
var input = el.getInput().data("dateinput", el);
els = els ? els.add(input) : input;
});
return els ? els : this;
};*/
})(jQuery, window ,document);