dwz.datepicker.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /**
  2. * reference dwz.util.date.js
  3. * @author ZhangHuihua@msn.com
  4. *
  5. */
  6. (function($){
  7. $.setRegional("datepicker", {
  8. dayNames:['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
  9. monthNames:['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
  10. });
  11. $.fn.datepicker = function(opts){
  12. var setting = {
  13. box$:"#calendar",
  14. year$:"#calendar [name=year]", month$:"#calendar [name=month]",
  15. tmInputs$:"#calendar .time :text", hour$:"#calendar .time .hh", minute$:"#calendar .time .mm", second$:"#calendar .time .ss",
  16. tmBox$:"#calendar .tm", tmUp$:"#calendar .time .up", tmDown$:"#calendar .time .down",
  17. close$:"#calendar .close", calIcon$:"a.inputDateButton",
  18. main$:"#calendar .main", days$:"#calendar .days", dayNames$:"#calendar .dayNames",
  19. clearBut$:"#calendar .clearBut", okBut$:"#calendar .okBut"
  20. };
  21. function changeTmMenu(sltClass){
  22. var $tm = $(setting.tmBox$);
  23. $tm.removeClass("hh").removeClass("mm").removeClass("ss");
  24. if (sltClass) {
  25. $tm.addClass(sltClass);
  26. $(setting.tmInputs$).removeClass("slt").filter("." + sltClass).addClass("slt");
  27. }
  28. }
  29. function clickTmMenu($input, type){
  30. $(setting.tmBox$).find("."+type+" li").each(function(){
  31. var $li = $(this);
  32. $li.click(function(){
  33. $input.val($li.text());
  34. });
  35. });
  36. }
  37. function keydownInt(e){
  38. if (!((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode == DWZ.keyCode.DELETE || e.keyCode == DWZ.keyCode.BACKSPACE))) { return false; }
  39. }
  40. function changeTm($input, type){
  41. var ivalue = parseInt($input.val()), istart = parseInt($input.attr("start")) || 0, iend = parseInt($input.attr("end"));
  42. var istep = parseInt($input.attr('step') || 1);
  43. if (type == 1) {
  44. if (ivalue <= iend-istep){$input.val(ivalue + istep);}
  45. } else if (type == -1){
  46. if (ivalue >= istart+istep){$input.val(ivalue - istep);}
  47. } else if (ivalue > iend) {
  48. $input.val(iend);
  49. } else if (ivalue < istart) {
  50. $input.val(istart);
  51. }
  52. }
  53. return this.each(function(){
  54. var $this = $(this);
  55. var dp = new Datepicker($this.val(), opts);
  56. function generateCalendar(dp){
  57. var dw = dp.getDateWrap();
  58. var minDate = dp.getMinDate();
  59. var maxDate = dp.getMaxDate();
  60. var monthStart = new Date(dw.year,dw.month-1,1);
  61. var startDay = monthStart.getDay();
  62. var dayStr="";
  63. if (startDay > 0){
  64. monthStart.setMonth(monthStart.getMonth() - 1);
  65. var prevDateWrap = dp.getDateWrap(monthStart);
  66. for(var t=prevDateWrap.days-startDay+1;t<=prevDateWrap.days;t++) {
  67. var _date = new Date(dw.year,dw.month-2,t);
  68. var _ctrClass = (_date >= minDate && _date <= maxDate) ? '' : 'disabled';
  69. dayStr+='<dd class="other '+_ctrClass+'" chMonth="-1" day="' + t + '">'+t+'</dd>';
  70. }
  71. }
  72. for(var t=1;t<=dw.days;t++){
  73. var _date = new Date(dw.year,dw.month-1,t);
  74. var _ctrClass = (_date >= minDate && _date <= maxDate) ? '' : 'disabled';
  75. if(t==dw.day){
  76. dayStr+='<dd class="slt '+_ctrClass+'" day="' + t + '">'+t+'</dd>';
  77. }else{
  78. dayStr+='<dd class="'+_ctrClass+'" day="' + t + '">'+t+'</dd>';
  79. }
  80. }
  81. for(var t=1;t<=42-startDay-dw.days;t++){
  82. var _date = new Date(dw.year,dw.month,t);
  83. var _ctrClass = (_date >= minDate && _date <= maxDate) ? '' : 'disabled';
  84. dayStr+='<dd class="other '+_ctrClass+'" chMonth="1" day="' + t + '">'+t+'</dd>';
  85. }
  86. var $days = $(setting.days$).html(dayStr).find("dd");
  87. $days.not('.disabled').click(function(){
  88. var $day = $(this);
  89. if (!dp.hasTime()) {
  90. $this.val(dp.formatDate(dp.changeDay($day.attr("day"), $day.attr("chMonth"))));
  91. closeCalendar();
  92. } else {
  93. $days.removeClass("slt");
  94. $day.addClass("slt");
  95. }
  96. });
  97. if (!dp.hasDate()) $(setting.main$).addClass('nodate'); // 仅时间,无日期
  98. if (dp.hasTime()) {
  99. $("#calendar .time").show();
  100. var $hour = $(setting.hour$).val(dw.hour).focus(function(){
  101. changeTmMenu("hh");
  102. });
  103. var iMinute = parseInt(dw.minute / dp.opts.mmStep) * dp.opts.mmStep;
  104. var $minute = $(setting.minute$).val(iMinute).attr('step',dp.opts.mmStep).focus(function(){
  105. changeTmMenu("mm");
  106. });
  107. var $second = $(setting.second$).val(dp.hasSecond() ? dw.second : 0).attr('step',dp.opts.ssStep).focus(function(){
  108. changeTmMenu("ss");
  109. });
  110. $hour.add($minute).add($second).click(function(){return false});
  111. clickTmMenu($hour,"hh");
  112. clickTmMenu($minute,"mm");
  113. clickTmMenu($second,"ss");
  114. $(setting.box$).click(function(){
  115. changeTmMenu();
  116. });
  117. var $inputs = $(setting.tmInputs$);
  118. $inputs.keydown(keydownInt).each(function(){
  119. var $input = $(this);
  120. $input.keyup(function(){
  121. changeTm($input, 0);
  122. });
  123. });
  124. $(setting.tmUp$).click(function(){
  125. $inputs.filter(".slt").each(function(){
  126. changeTm($(this), 1);
  127. });
  128. });
  129. $(setting.tmDown$).click(function(){
  130. $inputs.filter(".slt").each(function(){
  131. changeTm($(this), -1);
  132. });
  133. });
  134. if (!dp.hasHour()) $hour.attr("disabled",true);
  135. if (!dp.hasMinute()) $minute.attr("disabled",true);
  136. if (!dp.hasSecond()) $second.attr("disabled",true);
  137. }
  138. }
  139. function closeCalendar() {
  140. $(setting.box$).remove();
  141. $(document).unbind("click", closeCalendar);
  142. }
  143. $this.click(function(event){
  144. closeCalendar();
  145. var dp = new Datepicker($this.val(), opts);
  146. var offset = $this.offset();
  147. var iTop = offset.top+this.offsetHeight;
  148. $(DWZ.frag['calendarFrag']).appendTo("body").css({
  149. left:offset.left+'px',
  150. top:iTop+'px'
  151. }).show().click(function(event){
  152. event.stopPropagation();
  153. });
  154. ($.fn.bgiframe && $(setting.box$).bgiframe());
  155. var dayNames = "";
  156. $.each($.regional.datepicker.dayNames, function(i,v){
  157. dayNames += "<dt>" + v + "</dt>"
  158. });
  159. $(setting.dayNames$).html(dayNames);
  160. var dw = dp.getDateWrap();
  161. var $year = $(setting.year$);
  162. var yearstart = dp.getMinDate().getFullYear();
  163. var yearend = dp.getMaxDate().getFullYear();
  164. for(y=yearstart; y<=yearend; y++){
  165. $year.append('<option value="'+ y +'"'+ (dw.year==y ? 'selected="selected"' : '') +'>'+ y +'</option>');
  166. }
  167. var $month = $(setting.month$);
  168. $.each($.regional.datepicker.monthNames, function(i,v){
  169. var m = i+1;
  170. $month.append('<option value="'+ m +'"'+ (dw.month==m ? 'selected="selected"' : '') +'>'+ v +'</option>');
  171. });
  172. // generate calendar
  173. generateCalendar(dp);
  174. $year.add($month).change(function(){
  175. dp.changeDate($year.val(), $month.val());
  176. generateCalendar(dp);
  177. });
  178. // fix top
  179. var iBoxH = $(setting.box$).outerHeight(true);
  180. if (iTop > iBoxH && iTop > $(window).height()-iBoxH) {
  181. $(setting.box$).css("top", offset.top - iBoxH);
  182. }
  183. $(setting.close$).click(function(){
  184. closeCalendar();
  185. });
  186. $(setting.clearBut$).click(function(){
  187. $this.val("");
  188. closeCalendar();
  189. });
  190. $(setting.okBut$).click(function(){
  191. var $dd = $(setting.days$).find("dd.slt");
  192. if ($dd.hasClass("disabled")) return false;
  193. var date = dp.changeDay($dd.attr("day"), $dd.attr("chMonth"));
  194. if (dp.hasTime()) {
  195. date.setHours(parseInt($(setting.hour$).val()));
  196. date.setMinutes(parseInt($(setting.minute$).val()));
  197. date.setSeconds(parseInt($(setting.second$).val()));
  198. }
  199. $this.val(dp.formatDate(date));
  200. closeCalendar();
  201. });
  202. $(document).bind("click", closeCalendar);
  203. return false;
  204. });
  205. $this.parent().find(setting.calIcon$).click(function(){
  206. $this.trigger("click");
  207. return false;
  208. });
  209. });
  210. }
  211. var Datepicker = function(sDate, opts) {
  212. this.opts = $.extend({
  213. pattern:'yyyy-MM-dd',
  214. minDate:"1900-01-01",
  215. maxDate:"2099-12-31",
  216. mmStep:1,
  217. ssStep:1
  218. }, opts);
  219. //动态minDate、maxDate
  220. var now = new Date();
  221. this.opts.minDate = now.formatDateTm(this.opts.minDate);
  222. this.opts.maxDate = now.formatDateTm(this.opts.maxDate);
  223. this.sDate = sDate.trim();
  224. }
  225. $.extend(Datepicker.prototype, {
  226. get: function(name) {
  227. return this.opts[name];
  228. },
  229. _getDays: function (y,m){//获取某年某月的天数
  230. return m==2?(y%4||!(y%100)&&y%400?28:29):(/4|6|9|11/.test(m)?30:31);
  231. },
  232. _minMaxDate: function(sDate){
  233. var _count = sDate.split('-').length -1;
  234. var _format = 'y-M-d';
  235. if (_count == 1) _format = 'y-M';
  236. else if (_count == 0) _format = 'y';
  237. return sDate.parseDate(_format);
  238. },
  239. getMinDate: function(){
  240. return this._minMaxDate(this.opts.minDate);
  241. },
  242. getMaxDate: function(){
  243. var _sDate = this.opts.maxDate;
  244. var _count = _sDate.split('-').length -1;
  245. var _date = this._minMaxDate(_sDate);
  246. if (_count < 2) { //format:y-M、y
  247. var _day = this._getDays(_date.getFullYear(), _date.getMonth()+1);
  248. _date.setDate(_day);
  249. if (_count == 0) {//format:y
  250. _date.setMonth(11);
  251. }
  252. }
  253. return _date;
  254. },
  255. getDateWrap: function(date){ //得到年,月,日
  256. if (!date) date = this.parseDate(this.sDate) || new Date();
  257. var y = date.getFullYear();
  258. var m = date.getMonth()+1;
  259. var days = this._getDays(y,m);
  260. return {
  261. year:y, month:m, day:date.getDate(),
  262. hour:date.getHours(),minute:date.getMinutes(),second:date.getSeconds(),
  263. days: days, date:date
  264. }
  265. },
  266. /**
  267. * @param {year:2010, month:05, day:24}
  268. */
  269. changeDate: function(y, m, d){
  270. var date = new Date(y, m - 1, d || 1);
  271. this.sDate = this.formatDate(date);
  272. return date;
  273. },
  274. changeDay: function(day, chMonth){
  275. if (!chMonth) chMonth = 0;
  276. var dw = this.getDateWrap();
  277. return this.changeDate(dw.year, dw.month+parseInt(chMonth), day);
  278. },
  279. parseDate: function(sDate){
  280. if (!sDate) return null;
  281. return sDate.parseDate(this.opts.pattern);
  282. },
  283. formatDate: function(date){
  284. return date.formatDate(this.opts.pattern);
  285. },
  286. hasHour: function() {
  287. return this.opts.pattern.indexOf("H") != -1;
  288. },
  289. hasMinute: function() {
  290. return this.opts.pattern.indexOf("m") != -1;
  291. },
  292. hasSecond: function() {
  293. return this.opts.pattern.indexOf("s") != -1;
  294. },
  295. hasTime: function() {
  296. return this.hasHour() || this.hasMinute() || this.hasSecond();
  297. },
  298. hasDate: function() {
  299. var _dateKeys = ['y','M','d','E'];
  300. for (var i=0; i<_dateKeys.length; i++){
  301. if (this.opts.pattern.indexOf(_dateKeys[i]) != -1) return true;
  302. }
  303. return false;
  304. }
  305. });
  306. })(jQuery);