1 /**
2
3 @Name : layDate v1.1 日期控件
4 @Author: 贤心
5 @Date: 2014-06-25
6 @QQ群:176047195
7 @Site:http://sentsin.com/layui/laydate
8
9 */
10
11 ;!function(win){
12
13 //全局配置,如果采用默认均不需要改动
14 var config = {
15 path: '', //laydate所在路径
16 defSkin: 'default', //初始化皮肤
17 format: 'YYYY-MM-DD', //日期格式
18 min: '1900-01-01 00:00:00', //最小日期
19 max: '2099-12-31 23:59:59', //最大日期
20 isv: false
21 };
22
23 var Dates = {}, doc = document, creat = 'createElement', byid = 'getElementById', tags = 'getElementsByTagName';
24 var as = ['laydate_box', 'laydate_void', 'laydate_click', 'LayDateSkin', 'skins/', '/laydate.css'];
25
26
27 //主接口
28 win.laydate = function(options){
29 options = options || {};
30 try{
31 as.event = win.event ? win.event : laydate.caller.arguments[0];
32 } catch(e){};
33 Dates.run(options);
34 return laydate;
35 };
36
37 laydate.v = '1.1';
38
39 //获取组件存放路径
40 Dates.getPath = (function(){
41 var js = document.scripts, jsPath = js[js.length - 1].src;
42 return config.path ? config.path : jsPath.substring(0, jsPath.lastIndexOf("/") + 1);
43 }());
44
45 Dates.use = function(lib, id){
46 var link = doc[creat]('link');
47 link.type = 'text/css';
48 link.rel = 'stylesheet';
49 link.href = Dates.getPath + lib + as[5];
50 id && (link.id = id);
51 doc[tags]('head')[0].appendChild(link);
52 link = null;
53 };
54
55 Dates.trim = function(str){
56 str = str || '';
57 return str.replace(/^s|s$/g, '').replace(/s+/g, ' ');
58 };
59
60 //补齐数位
61 Dates.digit = function(num){
62 return num < 10 ? '0' + (num|0) : num;
63 };
64
65 Dates.stopmp = function(e){
66 e = e || win.event;
67 e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
68 return this;
69 };
70
71 Dates.each = function(arr, fn){
72 var i = 0, len = arr.length;
73 for(; i < len; i++){
74 if(fn(i, arr[i]) === false){
75 break
76 }
77 }
78 };
79
80 Dates.hasClass = function(elem, cls){
81 elem = elem || {};
82 return new RegExp('\b' + cls +'\b').test(elem.className);
83 };
84
85 Dates.addClass = function(elem, cls){
86 elem = elem || {};
87 Dates.hasClass(elem, cls) || (elem.className += ' ' + cls);
88 elem.className = Dates.trim(elem.className);
89 return this;
90 };
91
92 Dates.removeClass = function(elem, cls) {
93 elem = elem || {};
94 if (Dates.hasClass(elem, cls)) {
95 var reg = new RegExp('\b' + cls +'\b');
96 elem.className = elem.className.replace(reg, '');
97 }
98 return this;
99 };
100
101 //清除css属性
102 Dates.removeCssAttr = function(elem, attr){
103 var s = elem.style;
104 if(s.removeProperty){
105 s.removeProperty(attr);
106 } else {
107 s.removeAttribute(attr);
108 }
109 };
110
111 //显示隐藏
112 Dates.shde = function(elem, type){
113 elem.style.display = type ? 'none' : 'block';
114 };
115
116 //简易选择器
117 Dates.query = function(node){
118 if(node && node.nodeType === 1){
119 if(node.tagName.toLowerCase() !== 'input'){
120 throw new Error('选择器elem错误');
121 }
122 return node;
123 }
124
125 var node = (Dates.trim(node)).split(' '), elemId = doc[byid](node[0].substr(1)), arr;
126 if(!elemId){
127 return;
128 } else if(!node[1]){
129 return elemId;
130 } else if(/^./.test(node[1])){
131 var find, child = node[1].substr(1), exp = new RegExp('\b' + child +'\b');
132 arr = []
133 find = doc.getElementsByClassName ? elemId.getElementsByClassName(child) : elemId[tags]('*');
134 Dates.each(find, function(ii, that){
135 exp.test(that.className) && arr.push(that);
136 });
137 return arr[0] ? arr : '';
138 } else {
139 arr = elemId[tags](node[1]);
140 return arr[0] ? elemId[tags](node[1]) : '';
141 }
142 };
143
144 //事件监听器
145 Dates.on = function(elem, even, fn){
146 elem.attachEvent ? elem.attachEvent('on'+ even, function(){
147 fn.call(elem, win.even);
148 }) : elem.addEventListener(even, fn, false);
149 return Dates;
150 };
151
152 //阻断mouseup
153 Dates.stopMosup = function(evt, elem){
154 if(evt !== 'mouseup'){
155 Dates.on(elem, 'mouseup', function(ev){
156 Dates.stopmp(ev);
157 });
158 }
159 };
160
161 Dates.run = function(options){
162 var S = Dates.query, elem, devt, even = as.event, target;
163 try {
164 target = even.target || even.srcElement || {};
165 } catch(e){
166 target = {};
167 }
168 elem = options.elem ? S(options.elem) : target;
169 if(even && target.tagName){
170 if(!elem || elem === Dates.elem){
171 return;
172 }
173 Dates.stopMosup(even.type, elem);
174 Dates.stopmp(even);
175 Dates.view(elem, options);
176 Dates.reshow();
177 } else {
178 devt = options.event || 'click';
179 Dates.each((elem.length|0) > 0 ? elem : [elem], function(ii, that){
180 Dates.stopMosup(devt, that);
181 Dates.on(that, devt, function(ev){
182 Dates.stopmp(ev);
183 if(that !== Dates.elem){
184 Dates.view(that, options);
185 Dates.reshow();
186 }
187 });
188 });
189 }
190 };
191
192 Dates.scroll = function(type){
193 type = type ? 'scrollLeft' : 'scrollTop';
194 return doc.body[type] | doc.documentElement[type];
195 };
196
197 Dates.winarea = function(type){
198 return document.documentElement[type ? 'clientWidth' : 'clientHeight']
199 };
200
201 //判断闰年
202 Dates.isleap = function(year){
203 return (year%4 === 0 && year%100 !== 0) || year%400 === 0;
204 };
205
206 //检测是否在有效期
207 Dates.checkVoid = function(YY, MM, DD){
208 var back = [];
209 YY = YY|0;
210 MM = MM|0;
211 DD = DD|0;
212 if(YY < Dates.mins[0]){
213 back = ['y'];
214 } else if(YY > Dates.maxs[0]){
215 back = ['y', 1];
216 } else if(YY >= Dates.mins[0] && YY <= Dates.maxs[0]){
217 if(YY == Dates.mins[0]){
218 if(MM < Dates.mins[1]){
219 back = ['m'];
220 } else if(MM == Dates.mins[1]){
221 if(DD < Dates.mins[2]){
222 back = ['d'];
223 }
224 }
225 }
226 if(YY == Dates.maxs[0]){
227 if(MM > Dates.maxs[1]){
228 back = ['m', 1];
229 } else if(MM == Dates.maxs[1]){
230 if(DD > Dates.maxs[2]){
231 back = ['d', 1];
232 }
233 }
234 }
235 }
236 return back;
237 };
238
239 //时分秒的有效检测
240 Dates.timeVoid = function(times, index){
241 if(Dates.ymd[1]+1 == Dates.mins[1] && Dates.ymd[2] == Dates.mins[2]){
242 if(index === 0 && (times < Dates.mins[3])){
243 return 1;
244 } else if(index === 1 && times < Dates.mins[4]){
245 return 1;
246 } else if(index === 2 && times < Dates.mins[5]){
247 return 1;
248 }
249 } else if(Dates.ymd[1]+1 == Dates.maxs[1] && Dates.ymd[2] == Dates.maxs[2]){
250 if(index === 0 && times > Dates.maxs[3]){
251 return 1;
252 } else if(index === 1 && times > Dates.maxs[4]){
253 return 1;
254 } else if(index === 2 && times > Dates.maxs[5]){
255 return 1;
256 }
257 }
258 if(times > (index ? 59 : 23)){
259 return 1;
260 }
261 };
262
263 //检测日期是否合法
264 Dates.check = function(){
265 var reg = Dates.options.format.replace(/YYYY|MM|DD|hh|mm|ss/g,'\d+\').replace(/\$/g, '');
266 var exp = new RegExp(reg), value = Dates.elem[as.elemv];
267 var arr = value.match(/d+/g) || [], isvoid = Dates.checkVoid(arr[0], arr[1], arr[2]);
268 if(value.replace(/s/g, '') !== ''){
269 if(!exp.test(value)){
270 Dates.elem[as.elemv] = '';
271 Dates.msg('日期不符合格式,请重新选择。');
272 return 1;
273 } else if(isvoid[0]){
274 Dates.elem[as.elemv] = '';
275 Dates.msg('日期不在有效期内,请重新选择。');
276 return 1;
277 } else {
278 isvoid.value = Dates.elem[as.elemv].match(exp).join();
279 arr = isvoid.value.match(/d+/g);
280 if(arr[1] < 1){
281 arr[1] = 1;
282 isvoid.auto = 1;
283 } else if(arr[1] > 12){
284 arr[1] = 12;
285 isvoid.auto = 1;
286 } else if(arr[1].length < 2){
287 isvoid.auto = 1;
288 }
289 if(arr[2] < 1){
290 arr[2] = 1;
291 isvoid.auto = 1;
292 } else if(arr[2] > Dates.months[(arr[1]|0)-1]){
293 arr[2] = 31;
294 isvoid.auto = 1;
295 } else if(arr[2].length < 2){
296 isvoid.auto = 1;
297 }
298 if(arr.length > 3){
299 if(Dates.timeVoid(arr[3], 0)){
300 isvoid.auto = 1;
301 };
302 if(Dates.timeVoid(arr[4], 1)){
303 isvoid.auto = 1;
304 };
305 if(Dates.timeVoid(arr[5], 2)){
306 isvoid.auto = 1;
307 };
308 }
309 if(isvoid.auto){
310 Dates.creation([arr[0], arr[1]|0, arr[2]|0], 1);
311 } else if(isvoid.value !== Dates.elem[as.elemv]){
312 Dates.elem[as.elemv] = isvoid.value;
313 }
314 }
315 }
316 };
317
318 //生成日期
319 Dates.months = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
320 Dates.viewDate = function(Y, M, D){
321 var S = Dates.query, log = {}, De = new Date();
322 Y < (Dates.mins[0]|0) && (Y = (Dates.mins[0]|0));
323 Y > (Dates.maxs[0]|0) && (Y = (Dates.maxs[0]|0));
324
325 De.setFullYear(Y, M, D);
326 log.ymd = [De.getFullYear(), De.getMonth(), De.getDate()];
327
328 Dates.months[1] = Dates.isleap(log.ymd[0]) ? 29 : 28;
329
330 De.setFullYear(log.ymd[0], log.ymd[1], 1);
331 log.FDay = De.getDay();
332
333 log.PDay = Dates.months[M === 0 ? 11 : M - 1] - log.FDay + 1;
334 log.NDay = 1;
335
336 //渲染日
337 Dates.each(as.tds, function(i, elem){
338 var YY = log.ymd[0], MM = log.ymd[1] + 1, DD;
339 elem.className = '';
340 if(i < log.FDay){
341 elem.innerHTML = DD = i + log.PDay;
342 Dates.addClass(elem, 'laydate_nothis');
343 MM === 1 && (YY -= 1);
344 MM = MM === 1 ? 12 : MM - 1;
345 } else if(i >= log.FDay && i < log.FDay + Dates.months[log.ymd[1]]){
346 elem.innerHTML = DD = i - log.FDay + 1;
347 if(i - log.FDay + 1 === log.ymd[2]){
348 Dates.addClass(elem, as[2]);
349 log.thisDay = elem;
350 }
351 } else {
352 elem.innerHTML = DD = log.NDay++;
353 Dates.addClass(elem, 'laydate_nothis');
354 MM === 12 && (YY += 1);
355 MM = MM === 12 ? 1 : MM + 1;
356 }
357
358 if(Dates.checkVoid(YY, MM, DD)[0]){
359 Dates.addClass(elem, as[1]);
360 }
361
362 Dates.options.festival && Dates.festival(elem, MM + '.' + DD);
363 elem.setAttribute('y', YY);
364 elem.setAttribute('m', MM);
365 elem.setAttribute('d', DD);
366 YY = MM = DD = null;
367 });
368
369 Dates.valid = !Dates.hasClass(log.thisDay, as[1]);
370 Dates.ymd = log.ymd;
371
372 //锁定年月
373 as.year.value = Dates.ymd[0] + '年';
374 as.month.value = Dates.digit(Dates.ymd[1] + 1) + '月';
375
376 //定位月
377 Dates.each(as.mms, function(i, elem){
378 var getCheck = Dates.checkVoid(Dates.ymd[0], (elem.getAttribute('m')|0) + 1);
379 if(getCheck[0] === 'y' || getCheck[0] === 'm'){
380 Dates.addClass(elem, as[1]);
381 } else {
382 Dates.removeClass(elem, as[1]);
383 }
384 Dates.removeClass(elem, as[2]);
385 getCheck = null
386 });
387 Dates.addClass(as.mms[Dates.ymd[1]], as[2]);
388
389 //定位时分秒
390 log.times = [
391 Dates.inymd[3]|0 || 0,
392 Dates.inymd[4]|0 || 0,
393 Dates.inymd[5]|0 || 0
394 ];
395 Dates.each(new Array(3), function(i){
396 Dates.hmsin[i].value = Dates.digit(Dates.timeVoid(log.times[i], i) ? Dates.mins[i+3]|0 : log.times[i]|0);
397 });
398
399 //确定按钮状态
400 Dates[Dates.valid ? 'removeClass' : 'addClass'](as.ok, as[1]);
401 };
402
403 //节日
404 Dates.festival = function(td, md){
405 var str;
406 switch(md){
407 case '1.1':
408 str = '元旦';
409 break;
410 case '3.8':
411 str = '妇女';
412 break;
413 case '4.5':
414 str = '清明';
415 break;
416 case '5.1':
417 str = '劳动';
418 break;
419 case '6.1':
420 str = '儿童';
421 break;
422 case '9.10':
423 str = '教师';
424 break;
425 case '10.1':
426 str = '国庆';
427 break;
428 };
429 str && (td.innerHTML = str);
430 str = null;
431 };
432
433 //生成年列表
434 Dates.viewYears = function(YY){
435 var S = Dates.query, str = '';
436 Dates.each(new Array(14), function(i){
437 if(i === 7) {
438 str += '<li '+ (parseInt(as.year.value) === YY ? 'class="'+ as[2] +'"' : '') +' y="'+ YY +'">'+ YY +'年</li>';
439 } else {
440 str += '<li y="'+ (YY-7+i) +'">'+ (YY-7+i) +'年</li>';
441 }
442 });
443 S('#laydate_ys').innerHTML = str;
444 Dates.each(S('#laydate_ys li'), function(i, elem){
445 if(Dates.checkVoid(elem.getAttribute('y'))[0] === 'y'){
446 Dates.addClass(elem, as[1]);
447 } else {
448 Dates.on(elem, 'click', function(ev){
449 Dates.stopmp(ev).reshow();
450 Dates.viewDate(this.getAttribute('y')|0, Dates.ymd[1], Dates.ymd[2]);
451 });
452 }
453 });
454 };
455
456 //初始化面板数据
457 Dates.initDate = function(){
458 var S = Dates.query, log = {}, De = new Date();
459 var ymd = Dates.elem[as.elemv].match(/d+/g) || [];
460 if(ymd.length < 3){
461 ymd = Dates.options.start.match(/d+/g) || [];
462 if(ymd.length < 3){
463 ymd = [De.getFullYear(), De.getMonth()+1, De.getDate()];
464 }
465 }
466 Dates.inymd = ymd;
467 Dates.viewDate(ymd[0], ymd[1]-1, ymd[2]);
468 };
469
470 //是否显示零件
471 Dates.iswrite = function(){
472 var S = Dates.query, log = {
473 time: S('#laydate_hms')
474 };
475 Dates.shde(log.time, !Dates.options.istime);
476 Dates.shde(as.oclear, !('isclear' in Dates.options ? Dates.options.isclear : 1));
477 Dates.shde(as.otoday, !('istoday' in Dates.options ? Dates.options.istoday : 1));
478 Dates.shde(as.ok, !('issure' in Dates.options ? Dates.options.issure : 1));
479 };
480
481 //方位辨别
482 Dates.orien = function(obj, pos){
483 var tops, rect = Dates.elem.getBoundingClientRect();
484 obj.style.left = rect.left + (pos ? 0 : Dates.scroll(1)) + 'px';
485 if(rect.bottom + obj.offsetHeight/1.5 <= Dates.winarea()){
486 tops = rect.bottom - 1;
487 } else {
488 tops = rect.top > obj.offsetHeight/1.5 ? rect.top - obj.offsetHeight + 1 : Dates.winarea() - obj.offsetHeight;
489 }
490 obj.style.top = tops + (pos ? 0 : Dates.scroll()) + 'px';
491 };
492
493 //吸附定位
494 Dates.follow = function(obj){
495 if(Dates.options.fixed){
496 obj.style.position = 'fixed';
497 Dates.orien(obj, 1);
498 } else {
499 obj.style.position = 'absolute';
500 Dates.orien(obj);
501 }
502 };
503
504 //生成表格
505 Dates.viewtb = (function(){
506 var tr, view = [], weeks = [ '日', '一', '二', '三', '四', '五', '六'];
507 var log = {}, table = doc[creat]('table'), thead = doc[creat]('thead');
508 thead.appendChild(doc[creat]('tr'));
509 log.creath = function(i){
510 var th = doc[creat]('th');
511 th.innerHTML = weeks[i];
512 thead[tags]('tr')[0].appendChild(th);
513 th = null;
514 };
515
516 Dates.each(new Array(6), function(i){
517 view.push([]);
518 tr = table.insertRow(0);
519 Dates.each(new Array(7), function(j){
520 view[i][j] = 0;
521 i === 0 && log.creath(j);
522 tr.insertCell(j);
523 });
524 });
525
526 table.insertBefore(thead, table.children[0]);
527 table.id = table.className = 'laydate_table';
528 tr = view = null;
529 return table.outerHTML.toLowerCase();
530 }());
531
532 //渲染控件骨架
533 Dates.view = function(elem, options){
534 var S = Dates.query, div, log = {};
535 options = options || elem;
536
537 Dates.elem = elem;
538 Dates.options = options;
539 Dates.options.format || (Dates.options.format = config.format);
540 Dates.options.start = Dates.options.start || '';
541 Dates.mm = log.mm = [Dates.options.min || config.min, Dates.options.max || config.max];
542 Dates.mins = log.mm[0].match(/d+/g);
543 Dates.maxs = log.mm[1].match(/d+/g);
544
545 as.elemv = /textarea|input/.test(Dates.elem.tagName.toLocaleLowerCase()) ? 'value' : 'innerHTML';
546
547 if(!Dates.box){
548 div = doc[creat]('div');
549 div.id = as[0];
550 div.className = as[0];
551 div.style.cssText = 'position: absolute;';
552 div.setAttribute('name', 'laydate-v'+ laydate.v);
553
554 div.innerHTML = log.html = '<div class="laydate_top">'
555 +'<div class="laydate_ym laydate_y" id="laydate_YY">'
556 +'<a class="laydate_choose laydate_chprev laydate_tab"><cite></cite></a>'
557 +'<input id="laydate_y" readonly><label></label>'
558 +'<a class="laydate_choose laydate_chnext laydate_tab"><cite></cite></a>'
559 +'<div class="laydate_yms">'
560 +'<a class="laydate_tab laydate_chtop"><cite></cite></a>'
561 +'<ul id="laydate_ys"></ul>'
562 +'<a class="laydate_tab laydate_chdown"><cite></cite></a>'
563 +'</div>'
564 +'</div>'
565 +'<div class="laydate_ym laydate_m" id="laydate_MM">'
566 +'<a class="laydate_choose laydate_chprev laydate_tab"><cite></cite></a>'
567 +'<input id="laydate_m" readonly><label></label>'
568 +'<a class="laydate_choose laydate_chnext laydate_tab"><cite></cite></a>'
569 +'<div class="laydate_yms" id="laydate_ms">'+ function(){
570 var str = '';
571 Dates.each(new Array(12), function(i){
572 str += '<span m="'+ i +'">'+ Dates.digit(i+1) +'月</span>';
573 });
574 return str;
575 }() +'</div>'
576 +'</div>'
577 +'</div>'
578
579 + Dates.viewtb
580
581 +'<div class="laydate_bottom">'
582 +'<ul id="laydate_hms">'
583 +'<li class="laydate_sj">时间</li>'
584 +'<li><input readonly>:</li>'
585 +'<li><input readonly>:</li>'
586 +'<li><input readonly></li>'
587 +'</ul>'
588 +'<div class="laydate_time" id="laydate_time"></div>'
589 +'<div class="laydate_btn">'
590 +'<a id="laydate_clear">清空</a>'
591 +'<a id="laydate_today">今天</a>'
592 +'<a id="laydate_ok">确认</a>'
593 +'</div>'
594 +(config.isv ? '<a href="http://sentsin.com/layui/laydate/" class="laydate_v" target="_blank">laydate-v'+ laydate.v +'</a>' : '')
595 +'</div>';
596 doc.body.appendChild(div);
597 Dates.box = S('#'+as[0]);
598 Dates.events();
599 div = null;
600 } else {
601 Dates.shde(Dates.box);
602 }
603 Dates.follow(Dates.box);
604 options.zIndex ? Dates.box.style.zIndex = options.zIndex : Dates.removeCssAttr(Dates.box, 'z-index');
605 Dates.stopMosup('click', Dates.box);
606
607 Dates.initDate();
608 Dates.iswrite();
609 Dates.check();
610 };
611
612 //隐藏内部弹出元素
613 Dates.reshow = function(){
614 Dates.each(Dates.query('#'+ as[0] +' .laydate_show'), function(i, elem){
615 Dates.removeClass(elem, 'laydate_show');
616 });
617 return this;
618 };
619
620 //关闭控件
621 Dates.close = function(){
622 Dates.reshow();
623 Dates.shde(Dates.query('#'+ as[0]), 1);
624 Dates.elem = null;
625 };
626
627 //转换日期格式
628 Dates.parse = function(ymd, hms, format){
629 ymd = ymd.concat(hms);
630 format = format || (Dates.options ? Dates.options.format : config.format);
631 return format.replace(/YYYY|MM|DD|hh|mm|ss/g, function(str, index){
632 ymd.index = ++ymd.index|0;
633 return Dates.digit(ymd[ymd.index]);
634 });
635 };
636
637 //返回最终日期
638 Dates.creation = function(ymd, hide){
639 var S = Dates.query, hms = Dates.hmsin;
640 var getDates = Dates.parse(ymd, [hms[0].value, hms[1].value, hms[2].value]);
641 Dates.elem[as.elemv] = getDates;
642 if(!hide){
643 Dates.close();
644 typeof Dates.options.choose === 'function' && Dates.options.choose(getDates);
645 }
646 };
647
648 //事件
649 Dates.events = function(){
650 var S = Dates.query, log = {
651 box: '#'+as[0]
652 };
653
654 Dates.addClass(doc.body, 'laydate_body');
655
656 as.tds = S('#laydate_table td');
657 as.mms = S('#laydate_ms span');
658 as.year = S('#laydate_y');
659 as.month = S('#laydate_m');
660
661 //显示更多年月
662 Dates.each(S(log.box + ' .laydate_ym'), function(i, elem){
663 Dates.on(elem, 'click', function(ev){
664 Dates.stopmp(ev).reshow();
665 Dates.addClass(this[tags]('div')[0], 'laydate_show');
666 if(!i){
667 log.YY = parseInt(as.year.value);
668 Dates.viewYears(log.YY);
669 }
670 });
671 });
672
673 Dates.on(S(log.box), 'click', function(){
674 Dates.reshow();
675 });
676
677 //切换年
678 log.tabYear = function(type){
679 if(type === 0){
680 Dates.ymd[0]--;
681 } else if(type === 1) {
682 Dates.ymd[0]++;
683 } else if(type === 2) {
684 log.YY -= 14;
685 } else {
686 log.YY += 14;
687 }
688 if(type < 2){
689 Dates.viewDate(Dates.ymd[0], Dates.ymd[1], Dates.ymd[2]);
690 Dates.reshow();
691 } else {
692 Dates.viewYears(log.YY);
693 }
694 };
695 Dates.each(S('#laydate_YY .laydate_tab'), function(i, elem){
696 Dates.on(elem, 'click', function(ev){
697 Dates.stopmp(ev);
698 log.tabYear(i);
699 });
700 });
701
702
703 //切换月
704 log.tabMonth = function(type){
705 if(type){
706 Dates.ymd[1]++;
707 if(Dates.ymd[1] === 12){
708 Dates.ymd[0]++;
709 Dates.ymd[1] = 0;
710 }
711 } else {
712 Dates.ymd[1]--;
713 if(Dates.ymd[1] === -1){
714 Dates.ymd[0]--;
715 Dates.ymd[1] = 11;
716 }
717 }
718 Dates.viewDate(Dates.ymd[0], Dates.ymd[1], Dates.ymd[2]);
719 };
720 Dates.each(S('#laydate_MM .laydate_tab'), function(i, elem){
721 Dates.on(elem, 'click', function(ev){
722 Dates.stopmp(ev).reshow();
723 log.tabMonth(i);
724 });
725 });
726
727 //选择月
728 Dates.each(S('#laydate_ms span'), function(i, elem){
729 Dates.on(elem, 'click', function(ev){
730 Dates.stopmp(ev).reshow();
731 if(!Dates.hasClass(this, as[1])){
732 Dates.viewDate(Dates.ymd[0], this.getAttribute('m')|0, Dates.ymd[2]);
733 }
734 });
735 });
736
737 //选择日
738 Dates.each(S('#laydate_table td'), function(i, elem){
739 Dates.on(elem, 'click', function(ev){
740 if(!Dates.hasClass(this, as[1])){
741 Dates.stopmp(ev);
742 Dates.creation([this.getAttribute('y')|0, this.getAttribute('m')|0, this.getAttribute('d')|0]);
743 }
744 });
745 });
746
747 //清空
748 as.oclear = S('#laydate_clear');
749 Dates.on(as.oclear, 'click', function(){
750 Dates.elem[as.elemv] = '';
751 Dates.close();
752 });
753
754 //今天
755 as.otoday = S('#laydate_today');
756 Dates.on(as.otoday, 'click', function(){
757 var now = new Date();
758 Dates.creation([now.getFullYear(), now.getMonth() + 1, now.getDate()]);
759 });
760
761 //确认
762 as.ok = S('#laydate_ok');
763 Dates.on(as.ok, 'click', function(){
764 if(Dates.valid){
765 Dates.creation([Dates.ymd[0], Dates.ymd[1]+1, Dates.ymd[2]]);
766 }
767 });
768
769 //选择时分秒
770 log.times = S('#laydate_time');
771 Dates.hmsin = log.hmsin = S('#laydate_hms input');
772 log.hmss = ['小时', '分钟', '秒数'];
773 log.hmsarr = [];
774
775 //生成时分秒或警告信息
776 Dates.msg = function(i, title){
777 var str = '<div class="laydte_hsmtex">'+ (title || '提示') +'<span>×</span></div>';
778 if(typeof i === 'string'){
779 str += '<p>'+ i +'</p>';
780 Dates.shde(S('#'+as[0]));
781 Dates.removeClass(log.times, 'laydate_time1').addClass(log.times, 'laydate_msg');
782 } else {
783 if(!log.hmsarr[i]){
784 str += '<div id="laydate_hmsno" class="laydate_hmsno">';
785 Dates.each(new Array(i === 0 ? 24 : 60), function(i){
786 str += '<span>'+ i +'</span>';
787 });
788 str += '</div>'
789 log.hmsarr[i] = str;
790 } else {
791 str = log.hmsarr[i];
792 }
793 Dates.removeClass(log.times, 'laydate_msg');
794 Dates[i=== 0 ? 'removeClass' : 'addClass'](log.times, 'laydate_time1');
795 }
796 Dates.addClass(log.times, 'laydate_show');
797 log.times.innerHTML = str;
798 };
799
800 log.hmson = function(input, index){
801 var span = S('#laydate_hmsno span'), set = Dates.valid ? null : 1;
802 Dates.each(span, function(i, elem){
803 if(set){
804 Dates.addClass(elem, as[1]);
805 } else if(Dates.timeVoid(i, index)){
806 Dates.addClass(elem, as[1]);
807 } else {
808 Dates.on(elem, 'click', function(ev){
809 if(!Dates.hasClass(this, as[1])){
810 input.value = Dates.digit(this.innerHTML|0);
811 }
812 });
813 }
814 });
815 Dates.addClass(span[input.value|0], 'laydate_click');
816 };
817
818 //展开选择
819 Dates.each(log.hmsin, function(i, elem){
820 Dates.on(elem, 'click', function(ev){
821 Dates.stopmp(ev).reshow();
822 Dates.msg(i, log.hmss[i]);
823 log.hmson(this, i);
824 });
825 });
826
827 Dates.on(doc, 'mouseup', function(){
828 var box = S('#'+as[0]);
829 if(box && box.style.display !== 'none'){
830 Dates.check() || Dates.close();
831 }
832 }).on(doc, 'keydown', function(event){
833 event = event || win.event;
834 var codes = event.keyCode;
835
836 //如果在日期显示的时候按回车
837 if(codes === 13 && Dates.elem){
838 Dates.creation([Dates.ymd[0], Dates.ymd[1]+1, Dates.ymd[2]]);
839 }
840 });
841 };
842
843 Dates.init = (function(){
844 Dates.use('need');
845 Dates.use(as[4] + config.defSkin, as[3]);
846 Dates.skinLink = Dates.query('#'+as[3]);
847 }());
848
849 //重置定位
850 laydate.reset = function(){
851 (Dates.box && Dates.elem) && Dates.follow(Dates.box);
852 };
853
854 //返回指定日期
855 laydate.now = function(timestamp, format){
856 var De = new Date((timestamp|0) ? function(tamp){
857 return tamp < 86400000 ? (+new Date + tamp*86400000) : tamp;
858 }(parseInt(timestamp)) : +new Date);
859 return Dates.parse(
860 [De.getFullYear(), De.getMonth()+1, De.getDate()],
861 [De.getHours(), De.getMinutes(), De.getSeconds()],
862 format
863 );
864 };
865
866 //皮肤选择
867 laydate.skin = function(lib){
868 Dates.skinLink.href = Dates.getPath + as[4] + lib + as[5];
869 };
870
871 }(window);