laydate-rails 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "layui-laydate",
3
+ "realname": "laydate",
4
+ "version": "5.0.9",
5
+ "description": "日期与时间组件",
6
+ "main": "src/laydate.js",
7
+ "license": "MIT",
8
+ "scripts": {
9
+ "run": "gulp"
10
+ },
11
+ "repository": {
12
+ "type": "https",
13
+ "url": "git+https://github.com/sentsin/laydate.git"
14
+ },
15
+ "author": "贤心",
16
+ "homepage": "http://www.layui.com/laydate/",
17
+ "devDependencies": {
18
+ "gulp": "^3.9.0",
19
+ "gulp-minify-css": "^1.2.4",
20
+ "gulp-uglify": "^1.5.4",
21
+ "gulp-rename": "^1.2.2",
22
+ "gulp-header": "^1.8.8",
23
+ "del": "^2.2.2"
24
+ },
25
+ "bugs": {
26
+ "url": "https://github.com/sentsin/laydate/issues"
27
+ },
28
+ "directories": {
29
+ "test": "test"
30
+ },
31
+ "dependencies": {},
32
+ "keywords": [
33
+ "laydate",
34
+ "date",
35
+ "time",
36
+ "datetime",
37
+ "datepicker",
38
+ "calendar"
39
+ ]
40
+ }
@@ -0,0 +1,1869 @@
1
+ /**
2
+
3
+ @Name : layDate 5.0.9 日期时间控件
4
+ @Author: 贤心
5
+ @Site:http://www.layui.com/laydate/
6
+ @License:MIT
7
+
8
+ */
9
+
10
+ ;!function(){
11
+ "use strict";
12
+
13
+ var isLayui = window.layui && layui.define, ready = {
14
+ getPath: function(){
15
+ var jsPath = document.currentScript ? document.currentScript.src : function(){
16
+ var js = document.scripts
17
+ ,last = js.length - 1
18
+ ,src;
19
+ for(var i = last; i > 0; i--){
20
+ if(js[i].readyState === 'interactive'){
21
+ src = js[i].src;
22
+ break;
23
+ }
24
+ }
25
+ return src || js[last].src;
26
+ }();
27
+ return jsPath.substring(0, jsPath.lastIndexOf('/') + 1);
28
+ }()
29
+
30
+ //获取节点的style属性值
31
+ ,getStyle: function(node, name){
32
+ var style = node.currentStyle ? node.currentStyle : window.getComputedStyle(node, null);
33
+ return style[style.getPropertyValue ? 'getPropertyValue' : 'getAttribute'](name);
34
+ }
35
+
36
+ //载入CSS配件
37
+ ,link: function(href, fn, cssname){
38
+
39
+ //未设置路径,则不主动加载css
40
+ if(!laydate.path) {
41
+ if (typeof fn === 'function') fn();
42
+ return;
43
+ }
44
+
45
+ var head = document.getElementsByTagName("head")[0], link = document.createElement('link');
46
+ if(typeof fn === 'string') cssname = fn;
47
+ var app = (cssname || href).replace(/\.|\//g, '');
48
+ var id = 'layuicss-'+ app, timeout = 0;
49
+
50
+ link.rel = 'stylesheet';
51
+ link.href = laydate.path + href;
52
+ link.id = id;
53
+
54
+ if(!document.getElementById(id)){
55
+ head.appendChild(link);
56
+ }
57
+
58
+ if(typeof fn !== 'function') return;
59
+
60
+ //轮询css是否加载完毕
61
+ (function poll() {
62
+ if(++timeout > 8 * 1000 / 100){
63
+ return window.console && console.error('laydate.css: Invalid');
64
+ };
65
+ parseInt(ready.getStyle(document.getElementById(id), 'width')) === 1989 ? fn() : setTimeout(poll, 100);
66
+ }());
67
+ }
68
+ }
69
+
70
+ ,laydate = {
71
+ v: '5.0.9'
72
+ ,config: {} //全局配置项
73
+ ,index: (window.laydate && window.laydate.v) ? 100000 : 0
74
+ ,path: ''
75
+
76
+ //设置全局项
77
+ ,set: function(options){
78
+ var that = this;
79
+ that.config = lay.extend({}, that.config, options);
80
+ return that;
81
+ }
82
+
83
+ //主体CSS等待事件
84
+ ,ready: function(fn){
85
+ var cssname = 'laydate', ver = ''
86
+ ,path = (isLayui ? 'modules/laydate/' : 'theme/') + 'default/laydate.css?v='+ laydate.v + ver;
87
+ isLayui ? layui.addcss(path, fn, cssname) : ready.link(path, fn, cssname);
88
+ return this;
89
+ }
90
+ }
91
+
92
+ //操作当前实例
93
+ ,thisDate = function(){
94
+ var that = this;
95
+ return {
96
+ //提示框
97
+ hint: function(content){
98
+ that.hint.call(that, content);
99
+ }
100
+ ,config: that.config
101
+ };
102
+ }
103
+
104
+ //字符常量
105
+ ,MOD_NAME = 'laydate', ELEM = '.layui-laydate', THIS = 'layui-this', SHOW = 'layui-show', HIDE = 'layui-hide', DISABLED = 'laydate-disabled', TIPS_OUT = '开始日期超出了结束日期<br>建议重新选择', LIMIT_YEAR = [100, 200000]
106
+
107
+ ,ELEM_STATIC = 'layui-laydate-static', ELEM_LIST = 'layui-laydate-list', ELEM_SELECTED = 'laydate-selected', ELEM_HINT = 'layui-laydate-hint', ELEM_PREV = 'laydate-day-prev', ELEM_NEXT = 'laydate-day-next', ELEM_FOOTER = 'layui-laydate-footer', ELEM_CONFIRM = '.laydate-btns-confirm', ELEM_TIME_TEXT = 'laydate-time-text', ELEM_TIME_BTN = '.laydate-btns-time'
108
+
109
+ //组件构造器
110
+ ,Class = function(options){
111
+ var that = this;
112
+ that.index = ++laydate.index;
113
+ that.config = lay.extend({}, that.config, laydate.config, options);
114
+ laydate.ready(function(){
115
+ that.init();
116
+ });
117
+ }
118
+
119
+ //DOM查找
120
+ ,lay = function(selector){
121
+ return new LAY(selector);
122
+ }
123
+
124
+ //DOM构造器
125
+ ,LAY = function(selector){
126
+ var index = 0
127
+ ,nativeDOM = typeof selector === 'object' ? [selector] : (
128
+ this.selector = selector
129
+ ,document.querySelectorAll(selector || null)
130
+ );
131
+ for(; index < nativeDOM.length; index++){
132
+ this.push(nativeDOM[index]);
133
+ }
134
+ };
135
+
136
+
137
+ /*
138
+ lay对象操作
139
+ */
140
+
141
+ LAY.prototype = [];
142
+ LAY.prototype.constructor = LAY;
143
+
144
+ //普通对象深度扩展
145
+ lay.extend = function(){
146
+ var ai = 1, args = arguments
147
+ ,clone = function(target, obj){
148
+ target = target || (obj.constructor === Array ? [] : {});
149
+ for(var i in obj){
150
+ //如果值为对象,则进入递归,继续深度合并
151
+ target[i] = (obj[i] && (obj[i].constructor === Object))
152
+ ? clone(target[i], obj[i])
153
+ : obj[i];
154
+ }
155
+ return target;
156
+ }
157
+
158
+ args[0] = typeof args[0] === 'object' ? args[0] : {};
159
+
160
+ for(; ai < args.length; ai++){
161
+ if(typeof args[ai] === 'object'){
162
+ clone(args[0], args[ai])
163
+ }
164
+ }
165
+ return args[0];
166
+ };
167
+
168
+ //ie版本
169
+ lay.ie = function(){
170
+ var agent = navigator.userAgent.toLowerCase();
171
+ return (!!window.ActiveXObject || "ActiveXObject" in window) ? (
172
+ (agent.match(/msie\s(\d+)/) || [])[1] || '11' //由于ie11并没有msie的标识
173
+ ) : false;
174
+ }();
175
+
176
+ //中止冒泡
177
+ lay.stope = function(e){
178
+ e = e || window.event;
179
+ e.stopPropagation
180
+ ? e.stopPropagation()
181
+ : e.cancelBubble = true;
182
+ };
183
+
184
+ //对象遍历
185
+ lay.each = function(obj, fn){
186
+ var key
187
+ ,that = this;
188
+ if(typeof fn !== 'function') return that;
189
+ obj = obj || [];
190
+ if(obj.constructor === Object){
191
+ for(key in obj){
192
+ if(fn.call(obj[key], key, obj[key])) break;
193
+ }
194
+ } else {
195
+ for(key = 0; key < obj.length; key++){
196
+ if(fn.call(obj[key], key, obj[key])) break;
197
+ }
198
+ }
199
+ return that;
200
+ };
201
+
202
+ //数字前置补零
203
+ lay.digit = function(num, length, end){
204
+ var str = '';
205
+ num = String(num);
206
+ length = length || 2;
207
+ for(var i = num.length; i < length; i++){
208
+ str += '0';
209
+ }
210
+ return num < Math.pow(10, length) ? str + (num|0) : num;
211
+ };
212
+
213
+ //创建元素
214
+ lay.elem = function(elemName, attr){
215
+ var elem = document.createElement(elemName);
216
+ lay.each(attr || {}, function(key, value){
217
+ elem.setAttribute(key, value);
218
+ });
219
+ return elem;
220
+ };
221
+
222
+ //追加字符
223
+ LAY.addStr = function(str, new_str){
224
+ str = str.replace(/\s+/, ' ');
225
+ new_str = new_str.replace(/\s+/, ' ').split(' ');
226
+ lay.each(new_str, function(ii, item){
227
+ if(!new RegExp('\\b'+ item + '\\b').test(str)){
228
+ str = str + ' ' + item;
229
+ }
230
+ });
231
+ return str.replace(/^\s|\s$/, '');
232
+ };
233
+
234
+ //移除值
235
+ LAY.removeStr = function(str, new_str){
236
+ str = str.replace(/\s+/, ' ');
237
+ new_str = new_str.replace(/\s+/, ' ').split(' ');
238
+ lay.each(new_str, function(ii, item){
239
+ var exp = new RegExp('\\b'+ item + '\\b')
240
+ if(exp.test(str)){
241
+ str = str.replace(exp, '');
242
+ }
243
+ });
244
+ return str.replace(/\s+/, ' ').replace(/^\s|\s$/, '');
245
+ };
246
+
247
+ //查找子元素
248
+ LAY.prototype.find = function(selector){
249
+ var that = this;
250
+ var index = 0, arr = []
251
+ ,isObject = typeof selector === 'object';
252
+
253
+ this.each(function(i, item){
254
+ var nativeDOM = isObject ? [selector] : item.querySelectorAll(selector || null);
255
+ for(; index < nativeDOM.length; index++){
256
+ arr.push(nativeDOM[index]);
257
+ }
258
+ that.shift();
259
+ });
260
+
261
+ if(!isObject){
262
+ that.selector = (that.selector ? that.selector + ' ' : '') + selector
263
+ }
264
+
265
+ lay.each(arr, function(i, item){
266
+ that.push(item);
267
+ });
268
+
269
+ return that;
270
+ };
271
+
272
+ //DOM遍历
273
+ LAY.prototype.each = function(fn){
274
+ return lay.each.call(this, this, fn);
275
+ };
276
+
277
+ //添加css类
278
+ LAY.prototype.addClass = function(className, type){
279
+ return this.each(function(index, item){
280
+ item.className = LAY[type ? 'removeStr' : 'addStr'](item.className, className)
281
+ });
282
+ };
283
+
284
+ //移除css类
285
+ LAY.prototype.removeClass = function(className){
286
+ return this.addClass(className, true);
287
+ };
288
+
289
+ //是否包含css类
290
+ LAY.prototype.hasClass = function(className){
291
+ var has = false;
292
+ this.each(function(index, item){
293
+ if(new RegExp('\\b'+ className +'\\b').test(item.className)){
294
+ has = true;
295
+ }
296
+ });
297
+ return has;
298
+ };
299
+
300
+ //添加或获取属性
301
+ LAY.prototype.attr = function(key, value){
302
+ var that = this;
303
+ return value === undefined ? function(){
304
+ if(that.length > 0) return that[0].getAttribute(key);
305
+ }() : that.each(function(index, item){
306
+ item.setAttribute(key, value);
307
+ });
308
+ };
309
+
310
+ //移除属性
311
+ LAY.prototype.removeAttr = function(key){
312
+ return this.each(function(index, item){
313
+ item.removeAttribute(key);
314
+ });
315
+ };
316
+
317
+ //设置HTML内容
318
+ LAY.prototype.html = function(html){
319
+ return this.each(function(index, item){
320
+ item.innerHTML = html;
321
+ });
322
+ };
323
+
324
+ //设置值
325
+ LAY.prototype.val = function(value){
326
+ return this.each(function(index, item){
327
+ item.value = value;
328
+ });
329
+ };
330
+
331
+ //追加内容
332
+ LAY.prototype.append = function(elem){
333
+ return this.each(function(index, item){
334
+ typeof elem === 'object'
335
+ ? item.appendChild(elem)
336
+ : item.innerHTML = item.innerHTML + elem;
337
+ });
338
+ };
339
+
340
+ //移除内容
341
+ LAY.prototype.remove = function(elem){
342
+ return this.each(function(index, item){
343
+ elem ? item.removeChild(elem) : item.parentNode.removeChild(item);
344
+ });
345
+ };
346
+
347
+ //事件绑定
348
+ LAY.prototype.on = function(eventName, fn){
349
+ return this.each(function(index, item){
350
+ item.attachEvent ? item.attachEvent('on' + eventName, function(e){
351
+ e.target = e.srcElement;
352
+ fn.call(item, e);
353
+ }) : item.addEventListener(eventName, fn, false);
354
+ });
355
+ };
356
+
357
+ //解除事件
358
+ LAY.prototype.off = function(eventName, fn){
359
+ return this.each(function(index, item){
360
+ item.detachEvent
361
+ ? item.detachEvent('on'+ eventName, fn)
362
+ : item.removeEventListener(eventName, fn, false);
363
+ });
364
+ };
365
+
366
+
367
+ /*
368
+ 组件操作
369
+ */
370
+
371
+
372
+ //是否闰年
373
+ Class.isLeapYear = function(year){
374
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
375
+ };
376
+
377
+ //默认配置
378
+ Class.prototype.config = {
379
+ type: 'date' //控件类型,支持:year/month/date/time/datetime
380
+ ,range: false //是否开启范围选择,即双控件
381
+ ,format: 'yyyy-MM-dd' //默认日期格式
382
+ ,value: null //默认日期,支持传入new Date(),或者符合format参数设定的日期格式字符
383
+ ,min: '1900-1-1' //有效最小日期,年月日必须用“-”分割,时分秒必须用“:”分割。注意:它并不是遵循 format 设定的格式。
384
+ ,max: '2099-12-31' //有效最大日期,同上
385
+ ,trigger: 'focus' //呼出控件的事件
386
+ ,show: false //是否直接显示,如果设置true,则默认直接显示控件
387
+ ,showBottom: true //是否显示底部栏
388
+ ,btns: ['clear', 'now', 'confirm'] //右下角显示的按钮,会按照数组顺序排列
389
+ ,lang: 'cn' //语言,只支持cn/en,即中文和英文
390
+ ,theme: 'default' //主题
391
+ ,position: null //控件定位方式定位, 默认absolute,支持:fixed/absolute/static
392
+ ,calendar: false //是否开启公历重要节日,仅支持中文版
393
+ ,mark: {} //日期备注,如重要事件或活动标记
394
+ ,zIndex: null //控件层叠顺序
395
+ ,done: null //控件选择完毕后的回调,点击清空/现在/确定也均会触发
396
+ ,change: null //日期时间改变后的回调
397
+ };
398
+
399
+ //多语言
400
+ Class.prototype.lang = function(){
401
+ var that = this
402
+ ,options = that.config
403
+ ,text = {
404
+ cn: {
405
+ weeks: ['日', '一', '二', '三', '四', '五', '六']
406
+ ,time: ['时', '分', '秒']
407
+ ,timeTips: '选择时间'
408
+ ,startTime: '开始时间'
409
+ ,endTime: '结束时间'
410
+ ,dateTips: '返回日期'
411
+ ,month: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二']
412
+ ,tools: {
413
+ confirm: '确定'
414
+ ,clear: '清空'
415
+ ,now: '现在'
416
+ }
417
+ }
418
+ ,en: {
419
+ weeks: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
420
+ ,time: ['Hours', 'Minutes', 'Seconds']
421
+ ,timeTips: 'Select Time'
422
+ ,startTime: 'Start Time'
423
+ ,endTime: 'End Time'
424
+ ,dateTips: 'Select Date'
425
+ ,month: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
426
+ ,tools: {
427
+ confirm: 'Confirm'
428
+ ,clear: 'Clear'
429
+ ,now: 'Now'
430
+ }
431
+ }
432
+ };
433
+ return text[options.lang] || text['cn'];
434
+ };
435
+
436
+ //初始准备
437
+ Class.prototype.init = function(){
438
+ var that = this
439
+ ,options = that.config
440
+ ,dateType = 'yyyy|y|MM|M|dd|d|HH|H|mm|m|ss|s'
441
+ ,isStatic = options.position === 'static'
442
+ ,format = {
443
+ year: 'yyyy'
444
+ ,month: 'yyyy-MM'
445
+ ,date: 'yyyy-MM-dd'
446
+ ,time: 'HH:mm:ss'
447
+ ,datetime: 'yyyy-MM-dd HH:mm:ss'
448
+ };
449
+
450
+ options.elem = lay(options.elem);
451
+ options.eventElem = lay(options.eventElem);
452
+
453
+ if(!options.elem[0]) return;
454
+
455
+ //日期范围分隔符
456
+ if(options.range === true) options.range = '-';
457
+
458
+ //根据不同type,初始化默认format
459
+ if(options.format === format.date){
460
+ options.format = format[options.type];
461
+ }
462
+
463
+ //将日期格式转化成数组
464
+ that.format = options.format.match(new RegExp(dateType + '|.', 'g')) || [];
465
+
466
+ //生成正则表达式
467
+ that.EXP_IF = '';
468
+ that.EXP_SPLIT = '';
469
+ lay.each(that.format, function(i, item){
470
+ var EXP = new RegExp(dateType).test(item)
471
+ ? '\\d{'+ function(){
472
+ if(new RegExp(dateType).test(that.format[i === 0 ? i + 1 : i - 1]||'')){
473
+ if(/^yyyy|y$/.test(item)) return 4;
474
+ return item.length;
475
+ }
476
+ if(/^yyyy$/.test(item)) return '1,4';
477
+ if(/^y$/.test(item)) return '1,308';
478
+ return '1,2';
479
+ }() +'}'
480
+ : '\\' + item;
481
+ that.EXP_IF = that.EXP_IF + EXP;
482
+ that.EXP_SPLIT = that.EXP_SPLIT + '(' + EXP + ')';
483
+ });
484
+ that.EXP_IF = new RegExp('^'+ (
485
+ options.range ?
486
+ that.EXP_IF + '\\s\\'+ options.range + '\\s' + that.EXP_IF
487
+ : that.EXP_IF
488
+ ) +'$');
489
+ that.EXP_SPLIT = new RegExp('^'+ that.EXP_SPLIT +'$', '');
490
+
491
+ //如果不是input|textarea元素,则默认采用click事件
492
+ if(!that.isInput(options.elem[0])){
493
+ if(options.trigger === 'focus'){
494
+ options.trigger = 'click';
495
+ }
496
+ }
497
+
498
+ //设置唯一KEY
499
+ if(!options.elem.attr('lay-key')){
500
+ options.elem.attr('lay-key', that.index);
501
+ options.eventElem.attr('lay-key', that.index);
502
+ }
503
+
504
+ //记录重要日期
505
+ options.mark = lay.extend({}, (options.calendar && options.lang === 'cn') ? {
506
+ '0-1-1': '元旦'
507
+ ,'0-2-14': '情人'
508
+ ,'0-3-8': '妇女'
509
+ ,'0-3-12': '植树'
510
+ ,'0-4-1': '愚人'
511
+ ,'0-5-1': '劳动'
512
+ ,'0-5-4': '青年'
513
+ ,'0-6-1': '儿童'
514
+ ,'0-9-10': '教师'
515
+ ,'0-9-18': '国耻'
516
+ ,'0-10-1': '国庆'
517
+ ,'0-12-25': '圣诞'
518
+ } : {}, options.mark);
519
+
520
+ //获取限制内日期
521
+ lay.each(['min', 'max'], function(i, item){
522
+ var ymd = [], hms = [];
523
+ if(typeof options[item] === 'number'){ //如果为数字
524
+ var day = options[item]
525
+ ,time = new Date().getTime()
526
+ ,STAMP = 86400000 //代表一天的时间戳
527
+ ,thisDate = new Date(
528
+ day ? (
529
+ day < STAMP ? time + day*STAMP : day //如果数字小于一天的时间戳,则数字为天数,否则为时间戳
530
+ ) : time
531
+ );
532
+ ymd = [thisDate.getFullYear(), thisDate.getMonth() + 1, thisDate.getDate()];
533
+ day < STAMP || (hms = [thisDate.getHours(), thisDate.getMinutes(), thisDate.getSeconds()]);
534
+ } else {
535
+ ymd = (options[item].match(/\d+-\d+-\d+/) || [''])[0].split('-');
536
+ hms = (options[item].match(/\d+:\d+:\d+/) || [''])[0].split(':');
537
+ }
538
+ options[item] = {
539
+ year: ymd[0] | 0 || new Date().getFullYear()
540
+ ,month: ymd[1] ? (ymd[1] | 0) - 1 : new Date().getMonth()
541
+ ,date: ymd[2] | 0 || new Date().getDate()
542
+ ,hours: hms[0] | 0
543
+ ,minutes: hms[1] | 0
544
+ ,seconds: hms[2] | 0
545
+ };
546
+ });
547
+
548
+ that.elemID = 'layui-laydate'+ options.elem.attr('lay-key');
549
+
550
+ if(options.show || isStatic) that.render();
551
+ isStatic || that.events();
552
+
553
+ //默认赋值
554
+ if(options.value){
555
+ if(options.value.constructor === Date){
556
+ that.setValue(that.parse(0, that.systemDate(options.value)));
557
+ } else {
558
+ that.setValue(options.value);
559
+ }
560
+ }
561
+ };
562
+
563
+ //控件主体渲染
564
+ Class.prototype.render = function(){
565
+ var that = this
566
+ ,options = that.config
567
+ ,lang = that.lang()
568
+ ,isStatic = options.position === 'static'
569
+
570
+ //主面板
571
+ ,elem = that.elem = lay.elem('div', {
572
+ id: that.elemID
573
+ ,'class': [
574
+ 'layui-laydate'
575
+ ,options.range ? ' layui-laydate-range' : ''
576
+ ,isStatic ? (' '+ ELEM_STATIC) : ''
577
+ ,options.theme && options.theme !== 'default' && !/^#/.test(options.theme) ? (' laydate-theme-' + options.theme) : ''
578
+ ].join('')
579
+ })
580
+
581
+ //主区域
582
+ ,elemMain = that.elemMain = []
583
+ ,elemHeader = that.elemHeader = []
584
+ ,elemCont = that.elemCont = []
585
+ ,elemTable = that.table = []
586
+
587
+ //底部区域
588
+ ,divFooter = that.footer = lay.elem('div', {
589
+ 'class': ELEM_FOOTER
590
+ });
591
+
592
+ if(options.zIndex) elem.style.zIndex = options.zIndex;
593
+
594
+ //单双日历区域
595
+ lay.each(new Array(2), function(i){
596
+ if(!options.range && i > 0){
597
+ return true;
598
+ }
599
+
600
+ //头部区域
601
+ var divHeader = lay.elem('div', {
602
+ 'class': 'layui-laydate-header'
603
+ })
604
+
605
+ //左右切换
606
+ ,headerChild = [function(){ //上一年
607
+ var elem = lay.elem('i', {
608
+ 'class': 'layui-icon laydate-icon laydate-prev-y'
609
+ });
610
+ elem.innerHTML = '&#xe65a;';
611
+ return elem;
612
+ }(), function(){ //上一月
613
+ var elem = lay.elem('i', {
614
+ 'class': 'layui-icon laydate-icon laydate-prev-m'
615
+ });
616
+ elem.innerHTML = '&#xe603;';
617
+ return elem;
618
+ }(), function(){ //年月选择
619
+ var elem = lay.elem('div', {
620
+ 'class': 'laydate-set-ym'
621
+ }), spanY = lay.elem('span'), spanM = lay.elem('span');
622
+ elem.appendChild(spanY);
623
+ elem.appendChild(spanM);
624
+ return elem;
625
+ }(), function(){ //下一月
626
+ var elem = lay.elem('i', {
627
+ 'class': 'layui-icon laydate-icon laydate-next-m'
628
+ });
629
+ elem.innerHTML = '&#xe602;';
630
+ return elem;
631
+ }(), function(){ //下一年
632
+ var elem = lay.elem('i', {
633
+ 'class': 'layui-icon laydate-icon laydate-next-y'
634
+ });
635
+ elem.innerHTML = '&#xe65b;';
636
+ return elem;
637
+ }()]
638
+
639
+ //日历内容区域
640
+ ,divContent = lay.elem('div', {
641
+ 'class': 'layui-laydate-content'
642
+ })
643
+ ,table = lay.elem('table')
644
+ ,thead = lay.elem('thead'), theadTr = lay.elem('tr');
645
+
646
+ //生成年月选择
647
+ lay.each(headerChild, function(i, item){
648
+ divHeader.appendChild(item);
649
+ });
650
+
651
+ //生成表格
652
+ thead.appendChild(theadTr);
653
+ lay.each(new Array(6), function(i){ //表体
654
+ var tr = table.insertRow(0);
655
+ lay.each(new Array(7), function(j){
656
+ if(i === 0){
657
+ var th = lay.elem('th');
658
+ th.innerHTML = lang.weeks[j];
659
+ theadTr.appendChild(th);
660
+ }
661
+ tr.insertCell(j);
662
+ });
663
+ });
664
+ table.insertBefore(thead, table.children[0]); //表头
665
+ divContent.appendChild(table);
666
+
667
+ elemMain[i] = lay.elem('div', {
668
+ 'class': 'layui-laydate-main laydate-main-list-'+ i
669
+ });
670
+
671
+ elemMain[i].appendChild(divHeader);
672
+ elemMain[i].appendChild(divContent);
673
+
674
+ elemHeader.push(headerChild);
675
+ elemCont.push(divContent);
676
+ elemTable.push(table);
677
+ });
678
+
679
+ //生成底部栏
680
+ lay(divFooter).html(function(){
681
+ var html = [], btns = [];
682
+ if(options.type === 'datetime'){
683
+ html.push('<span lay-type="datetime" class="laydate-btns-time">'+ lang.timeTips +'</span>');
684
+ }
685
+ lay.each(options.btns, function(i, item){
686
+ var title = lang.tools[item] || 'btn';
687
+ if(options.range && item === 'now') return;
688
+ if(isStatic && item === 'clear') title = options.lang === 'cn' ? '重置' : 'Reset';
689
+ btns.push('<span lay-type="'+ item +'" class="laydate-btns-'+ item +'">'+ title +'</span>');
690
+ });
691
+ html.push('<div class="laydate-footer-btns">'+ btns.join('') +'</div>');
692
+ return html.join('');
693
+ }());
694
+
695
+ //插入到主区域
696
+ lay.each(elemMain, function(i, main){
697
+ elem.appendChild(main);
698
+ });
699
+ options.showBottom && elem.appendChild(divFooter);
700
+
701
+ //生成自定义主题
702
+ if(/^#/.test(options.theme)){
703
+ var style = lay.elem('style')
704
+ ,styleText = [
705
+ '#{{id}} .layui-laydate-header{background-color:{{theme}};}'
706
+ ,'#{{id}} .layui-this{background-color:{{theme}} !important;}'
707
+ ].join('').replace(/{{id}}/g, that.elemID).replace(/{{theme}}/g, options.theme);
708
+
709
+ if('styleSheet' in style){
710
+ style.setAttribute('type', 'text/css');
711
+ style.styleSheet.cssText = styleText;
712
+ } else {
713
+ style.innerHTML = styleText;
714
+ }
715
+
716
+ lay(elem).addClass('laydate-theme-molv');
717
+ elem.appendChild(style);
718
+ }
719
+
720
+ //移除上一个控件
721
+ that.remove(Class.thisElemDate);
722
+
723
+ //如果是静态定位,则插入到指定的容器中,否则,插入到body
724
+ isStatic ? options.elem.append(elem) : (
725
+ document.body.appendChild(elem)
726
+ ,that.position() //定位
727
+ );
728
+
729
+ that.checkDate().calendar(); //初始校验
730
+ that.changeEvent(); //日期切换
731
+
732
+ Class.thisElemDate = that.elemID;
733
+
734
+ typeof options.ready === 'function' && options.ready(lay.extend({}, options.dateTime, {
735
+ month: options.dateTime.month + 1
736
+ }));
737
+ };
738
+
739
+ //控件移除
740
+ Class.prototype.remove = function(prev){
741
+ var that = this
742
+ ,options = that.config
743
+ ,elem = lay('#'+ (prev || that.elemID));
744
+ if(!elem.hasClass(ELEM_STATIC)){
745
+ that.checkDate(function(){
746
+ elem.remove();
747
+ });
748
+ }
749
+ return that;
750
+ };
751
+
752
+ //定位算法
753
+ Class.prototype.position = function(){
754
+ var that = this
755
+ ,options = that.config
756
+ ,elem = that.bindElem || options.elem[0]
757
+ ,rect = elem.getBoundingClientRect() //绑定元素的坐标
758
+ ,elemWidth = that.elem.offsetWidth //控件的宽度
759
+ ,elemHeight = that.elem.offsetHeight //控件的高度
760
+
761
+ //滚动条高度
762
+ ,scrollArea = function(type){
763
+ type = type ? 'scrollLeft' : 'scrollTop';
764
+ return document.body[type] | document.documentElement[type];
765
+ }
766
+ ,winArea = function(type){
767
+ return document.documentElement[type ? 'clientWidth' : 'clientHeight']
768
+ }, margin = 5, left = rect.left, top = rect.bottom;
769
+
770
+ //如果右侧超出边界
771
+ if(left + elemWidth + margin > winArea('width')){
772
+ left = winArea('width') - elemWidth - margin;
773
+ }
774
+
775
+ //如果底部超出边界
776
+ if(top + elemHeight + margin > winArea()){
777
+ top = rect.top > elemHeight //顶部是否有足够区域显示完全
778
+ ? rect.top - elemHeight
779
+ : winArea() - elemHeight;
780
+ top = top - margin*2;
781
+ }
782
+
783
+ if(options.position){
784
+ that.elem.style.position = options.position;
785
+ }
786
+ that.elem.style.left = left + (options.position === 'fixed' ? 0 : scrollArea(1)) + 'px';
787
+ that.elem.style.top = top + (options.position === 'fixed' ? 0 : scrollArea()) + 'px';
788
+ };
789
+
790
+ //提示
791
+ Class.prototype.hint = function(content){
792
+ var that = this
793
+ ,options = that.config
794
+ ,div = lay.elem('div', {
795
+ 'class': ELEM_HINT
796
+ });
797
+
798
+ div.innerHTML = content || '';
799
+ lay(that.elem).find('.'+ ELEM_HINT).remove();
800
+ that.elem.appendChild(div);
801
+
802
+ clearTimeout(that.hinTimer);
803
+ that.hinTimer = setTimeout(function(){
804
+ lay(that.elem).find('.'+ ELEM_HINT).remove();
805
+ }, 3000);
806
+ };
807
+
808
+ //获取递增/减后的年月
809
+ Class.prototype.getAsYM = function(Y, M, type){
810
+ type ? M-- : M++;
811
+ if(M < 0){
812
+ M = 11;
813
+ Y--;
814
+ }
815
+ if(M > 11){
816
+ M = 0;
817
+ Y++;
818
+ }
819
+ return [Y, M];
820
+ };
821
+
822
+ //系统消息
823
+ Class.prototype.systemDate = function(newDate){
824
+ var thisDate = newDate || new Date();
825
+ return {
826
+ year: thisDate.getFullYear() //年
827
+ ,month: thisDate.getMonth() //月
828
+ ,date: thisDate.getDate() //日
829
+ ,hours: newDate ? newDate.getHours() : 0 //时
830
+ ,minutes: newDate ? newDate.getMinutes() : 0 //分
831
+ ,seconds: newDate ? newDate.getSeconds() : 0 //秒
832
+ }
833
+ };
834
+
835
+ //日期校验
836
+ Class.prototype.checkDate = function(fn){
837
+ var that = this
838
+ ,thisDate = new Date()
839
+ ,options = that.config
840
+ ,dateTime = options.dateTime = options.dateTime || that.systemDate()
841
+ ,thisMaxDate, error
842
+
843
+ ,elem = that.bindElem || options.elem[0]
844
+ ,valType = that.isInput(elem) ? 'val' : 'html'
845
+ ,value = that.isInput(elem) ? elem.value : (options.position === 'static' ? '' : elem.innerHTML)
846
+
847
+ //校验日期有效数字
848
+ ,checkValid = function(dateTime){
849
+ if(dateTime.year > LIMIT_YEAR[1]) dateTime.year = LIMIT_YEAR[1], error = true; //不能超过20万年
850
+ if(dateTime.month > 11) dateTime.month = 11, error = true;
851
+ if(dateTime.hours > 23) dateTime.hours = 0, error = true;
852
+ if(dateTime.minutes > 59) dateTime.minutes = 0, dateTime.hours++, error = true;
853
+ if(dateTime.seconds > 59) dateTime.seconds = 0, dateTime.minutes++, error = true;
854
+
855
+ //计算当前月的最后一天
856
+ thisMaxDate = laydate.getEndDate(dateTime.month + 1, dateTime.year);
857
+ if(dateTime.date > thisMaxDate) dateTime.date = thisMaxDate, error = true;
858
+ }
859
+
860
+ //获得初始化日期值
861
+ ,initDate = function(dateTime, value, index){
862
+ var startEnd = ['startTime', 'endTime'];
863
+ value = (value.match(that.EXP_SPLIT) || []).slice(1);
864
+ index = index || 0;
865
+ if(options.range){
866
+ that[startEnd[index]] = that[startEnd[index]] || {};
867
+ }
868
+ lay.each(that.format, function(i, item){
869
+ var thisv = parseFloat(value[i]);
870
+ if(value[i].length < item.length) error = true;
871
+ if(/yyyy|y/.test(item)){ //年
872
+ if(thisv < LIMIT_YEAR[0]) thisv = LIMIT_YEAR[0], error = true; //年不能低于100年
873
+ dateTime.year = thisv;
874
+ } else if(/MM|M/.test(item)){ //月
875
+ if(thisv < 1) thisv = 1, error = true;
876
+ dateTime.month = thisv - 1;
877
+ } else if(/dd|d/.test(item)){ //日
878
+ if(thisv < 1) thisv = 1, error = true;
879
+ dateTime.date = thisv;
880
+ } else if(/HH|H/.test(item)){ //时
881
+ if(thisv < 1) thisv = 0, error = true;
882
+ dateTime.hours = thisv;
883
+ options.range && (that[startEnd[index]].hours = thisv);
884
+ } else if(/mm|m/.test(item)){ //分
885
+ if(thisv < 1) thisv = 0, error = true;
886
+ dateTime.minutes = thisv;
887
+ options.range && (that[startEnd[index]].minutes = thisv);
888
+ } else if(/ss|s/.test(item)){ //秒
889
+ if(thisv < 1) thisv = 0, error = true;
890
+ dateTime.seconds = thisv;
891
+ options.range && (that[startEnd[index]].seconds = thisv);
892
+ }
893
+ });
894
+ checkValid(dateTime)
895
+ };
896
+
897
+ if(fn === 'limit') return checkValid(dateTime), that;
898
+
899
+ value = value || options.value;
900
+ if(typeof value === 'string'){
901
+ value = value.replace(/\s+/g, ' ').replace(/^\s|\s$/g, '');
902
+ }
903
+
904
+ //如果点击了开始,单未选择结束就关闭,则重新选择开始
905
+ if(that.startState && !that.endState){
906
+ delete that.startState;
907
+ that.endState = true;
908
+ };
909
+
910
+ if(typeof value === 'string' && value){
911
+ if(that.EXP_IF.test(value)){ //校验日期格式
912
+ if(options.range){
913
+ value = value.split(' '+ options.range +' ');
914
+ that.startDate = that.startDate || that.systemDate();
915
+ that.endDate = that.endDate || that.systemDate();
916
+ options.dateTime = lay.extend({}, that.startDate);
917
+ lay.each([that.startDate, that.endDate], function(i, item){
918
+ initDate(item, value[i], i);
919
+ });
920
+ } else {
921
+ initDate(dateTime, value)
922
+ }
923
+ } else {
924
+ that.hint('日期格式不合法<br>必须遵循下述格式:<br>'+ (
925
+ options.range ? (options.format + ' '+ options.range +' ' + options.format) : options.format
926
+ ) + '<br>已为你重置');
927
+ error = true;
928
+ }
929
+ } else if(value && value.constructor === Date){ //如果值为日期对象时
930
+ options.dateTime = that.systemDate(value);
931
+ } else {
932
+ options.dateTime = that.systemDate();
933
+ delete that.startState;
934
+ delete that.endState;
935
+ delete that.startDate;
936
+ delete that.endDate;
937
+ delete that.startTime;
938
+ delete that.endTime;
939
+ }
940
+
941
+ checkValid(dateTime);
942
+
943
+ if(error && value){
944
+ that.setValue(
945
+ options.range ? (that.endDate ? that.parse() : '') : that.parse()
946
+ );
947
+ }
948
+ fn && fn();
949
+ return that;
950
+ };
951
+
952
+ //公历重要日期与自定义备注
953
+ Class.prototype.mark = function(td, YMD){
954
+ var that = this
955
+ ,mark, options = that.config;
956
+ lay.each(options.mark, function(key, title){
957
+ var keys = key.split('-');
958
+ if((keys[0] == YMD[0] || keys[0] == 0) //每年的每月
959
+ && (keys[1] == YMD[1] || keys[1] == 0) //每月的每日
960
+ && keys[2] == YMD[2]){ //特定日
961
+ mark = title || YMD[2];
962
+ }
963
+ });
964
+ mark && td.html('<span class="laydate-day-mark">'+ mark +'</span>');
965
+
966
+ return that;
967
+ };
968
+
969
+ //无效日期范围的标记
970
+ Class.prototype.limit = function(elem, date, index, time){
971
+ var that = this
972
+ ,options = that.config, timestrap = {}
973
+ ,dateTime = options[index > 41 ? 'endDate' : 'dateTime']
974
+ ,isOut, thisDateTime = lay.extend({}, dateTime, date || {});
975
+ lay.each({
976
+ now: thisDateTime
977
+ ,min: options.min
978
+ ,max: options.max
979
+ }, function(key, item){
980
+ timestrap[key] = that.newDate(lay.extend({
981
+ year: item.year
982
+ ,month: item.month
983
+ ,date: item.date
984
+ }, function(){
985
+ var hms = {};
986
+ lay.each(time, function(i, keys){
987
+ hms[keys] = item[keys];
988
+ });
989
+ return hms;
990
+ }())).getTime(); //time:是否比较时分秒
991
+ });
992
+
993
+ isOut = timestrap.now < timestrap.min || timestrap.now > timestrap.max;
994
+ elem && elem[isOut ? 'addClass' : 'removeClass'](DISABLED);
995
+ return isOut;
996
+ };
997
+
998
+ //日历表
999
+ Class.prototype.calendar = function(value){
1000
+ var that = this
1001
+ ,options = that.config
1002
+ ,dateTime = value || options.dateTime
1003
+ ,thisDate = new Date(), startWeek, prevMaxDate, thisMaxDate
1004
+ ,lang = that.lang()
1005
+
1006
+ ,isAlone = options.type !== 'date' && options.type !== 'datetime'
1007
+ ,index = value ? 1 : 0
1008
+ ,tds = lay(that.table[index]).find('td')
1009
+ ,elemYM = lay(that.elemHeader[index][2]).find('span');
1010
+
1011
+ if(dateTime.year < LIMIT_YEAR[0]) dateTime.year = LIMIT_YEAR[0], that.hint('最低只能支持到公元'+ LIMIT_YEAR[0] +'年');
1012
+ if(dateTime.year > LIMIT_YEAR[1]) dateTime.year = LIMIT_YEAR[1], that.hint('最高只能支持到公元'+ LIMIT_YEAR[1] +'年');
1013
+
1014
+ //记录初始值
1015
+ if(!that.firstDate){
1016
+ that.firstDate = lay.extend({}, dateTime);
1017
+ }
1018
+
1019
+ //计算当前月第一天的星期
1020
+ thisDate.setFullYear(dateTime.year, dateTime.month, 1);
1021
+ startWeek = thisDate.getDay();
1022
+
1023
+ prevMaxDate = laydate.getEndDate(dateTime.month || 12, dateTime.year); //计算上个月的最后一天
1024
+ thisMaxDate = laydate.getEndDate(dateTime.month + 1, dateTime.year); //计算当前月的最后一天
1025
+
1026
+ //赋值日
1027
+ lay.each(tds, function(index, item){
1028
+ var YMD = [dateTime.year, dateTime.month], st = 0;
1029
+ item = lay(item);
1030
+ item.removeAttr('class');
1031
+ if(index < startWeek){
1032
+ st = prevMaxDate - startWeek + index;
1033
+ item.addClass('laydate-day-prev');
1034
+ YMD = that.getAsYM(dateTime.year, dateTime.month, 'sub');
1035
+ } else if(index >= startWeek && index < thisMaxDate + startWeek){
1036
+ st = index - startWeek;
1037
+ if(!options.range){
1038
+ st + 1 === dateTime.date && item.addClass(THIS);
1039
+ }
1040
+ } else {
1041
+ st = index - thisMaxDate - startWeek;
1042
+ item.addClass('laydate-day-next');
1043
+ YMD = that.getAsYM(dateTime.year, dateTime.month);
1044
+ }
1045
+ YMD[1]++;
1046
+ YMD[2] = st + 1;
1047
+ item.attr('lay-ymd', YMD.join('-')).html(YMD[2]);
1048
+ that.mark(item, YMD).limit(item, {
1049
+ year: YMD[0]
1050
+ ,month: YMD[1] - 1
1051
+ ,date: YMD[2]
1052
+ }, index);
1053
+ });
1054
+
1055
+ //同步头部年月
1056
+ lay(elemYM[0]).attr('lay-ym', dateTime.year + '-' + (dateTime.month + 1));
1057
+ lay(elemYM[1]).attr('lay-ym', dateTime.year + '-' + (dateTime.month + 1));
1058
+
1059
+ if(options.lang === 'cn'){
1060
+ lay(elemYM[0]).attr('lay-type', 'year').html(dateTime.year + '年')
1061
+ lay(elemYM[1]).attr('lay-type', 'month').html((dateTime.month + 1) + '月');
1062
+ } else {
1063
+ lay(elemYM[0]).attr('lay-type', 'month').html(lang.month[dateTime.month]);
1064
+ lay(elemYM[1]).attr('lay-type', 'year').html(dateTime.year);
1065
+ }
1066
+
1067
+ //初始默认选择器
1068
+ if(isAlone){
1069
+ if(options.range){
1070
+ value ? that.endDate = (that.endDate || {
1071
+ year: dateTime.year + (options.type === 'year' ? 1 : 0)
1072
+ ,month: dateTime.month + (options.type === 'month' ? 0 : -1)
1073
+ }) : (that.startDate = that.startDate || {
1074
+ year: dateTime.year
1075
+ ,month: dateTime.month
1076
+ });
1077
+ if(value){
1078
+ that.listYM = [
1079
+ [that.startDate.year, that.startDate.month + 1]
1080
+ ,[that.endDate.year, that.endDate.month + 1]
1081
+ ];
1082
+ that.list(options.type, 0).list(options.type, 1);
1083
+ //同步按钮可点状态
1084
+ options.type === 'time' ? that.setBtnStatus('时间'
1085
+ ,lay.extend({}, that.systemDate(), that.startTime)
1086
+ ,lay.extend({}, that.systemDate(), that.endTime)
1087
+ ) : that.setBtnStatus(true);
1088
+ }
1089
+ }
1090
+ if(!options.range){
1091
+ that.listYM = [[dateTime.year, dateTime.month + 1]];
1092
+ that.list(options.type, 0);
1093
+ }
1094
+ }
1095
+
1096
+ //赋值双日历
1097
+ if(options.range && !value){
1098
+ var EYM = that.getAsYM(dateTime.year, dateTime.month)
1099
+ that.calendar(lay.extend({}, dateTime, {
1100
+ year: EYM[0]
1101
+ ,month: EYM[1]
1102
+ }));
1103
+ }
1104
+
1105
+ //通过检测当前有效日期,来设定确定按钮是否可点
1106
+ if(!options.range) that.limit(lay(that.footer).find(ELEM_CONFIRM), null, 0, ['hours', 'minutes', 'seconds']);
1107
+
1108
+ //标记选择范围
1109
+ if(options.range && value && !isAlone) that.stampRange();
1110
+ return that;
1111
+ };
1112
+
1113
+ //生成年月时分秒列表
1114
+ Class.prototype.list = function(type, index){
1115
+ var that = this
1116
+ ,options = that.config
1117
+ ,dateTime = options.dateTime
1118
+ ,lang = that.lang()
1119
+ ,isAlone = options.range && options.type !== 'date' && options.type !== 'datetime' //独立范围选择器
1120
+
1121
+ ,ul = lay.elem('ul', {
1122
+ 'class': ELEM_LIST + ' ' + ({
1123
+ year: 'laydate-year-list'
1124
+ ,month: 'laydate-month-list'
1125
+ ,time: 'laydate-time-list'
1126
+ })[type]
1127
+ })
1128
+ ,elemHeader = that.elemHeader[index]
1129
+ ,elemYM = lay(elemHeader[2]).find('span')
1130
+ ,elemCont = that.elemCont[index || 0]
1131
+ ,haveList = lay(elemCont).find('.'+ ELEM_LIST)[0]
1132
+ ,isCN = options.lang === 'cn'
1133
+ ,text = isCN ? '年' : ''
1134
+
1135
+ ,listYM = that.listYM[index] || {}
1136
+ ,hms = ['hours', 'minutes', 'seconds']
1137
+ ,startEnd = ['startTime', 'endTime'][index];
1138
+
1139
+ if(listYM[0] < 1) listYM[0] = 1;
1140
+
1141
+ if(type === 'year'){ //年列表
1142
+ var yearNum, startY = yearNum = listYM[0] - 7;
1143
+ if(startY < 1) startY = yearNum = 1;
1144
+ lay.each(new Array(15), function(i){
1145
+ var li = lay.elem('li', {
1146
+ 'lay-ym': yearNum
1147
+ }), ymd = {year: yearNum};
1148
+ yearNum == listYM[0] && lay(li).addClass(THIS);
1149
+ li.innerHTML = yearNum + text;
1150
+ ul.appendChild(li);
1151
+ if(yearNum < that.firstDate.year){
1152
+ ymd.month = options.min.month;
1153
+ ymd.date = options.min.date;
1154
+ } else if(yearNum >= that.firstDate.year){
1155
+ ymd.month = options.max.month;
1156
+ ymd.date = options.max.date;
1157
+ }
1158
+ that.limit(lay(li), ymd, index);
1159
+ yearNum++;
1160
+ });
1161
+ lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', (yearNum - 8) + '-' + listYM[1])
1162
+ .html((startY + text) + ' - ' + (yearNum - 1 + text));
1163
+ } else if(type === 'month'){ //月列表
1164
+ lay.each(new Array(12), function(i){
1165
+ var li = lay.elem('li', {
1166
+ 'lay-ym': i
1167
+ }), ymd = {year: listYM[0], month: i};
1168
+ i + 1 == listYM[1] && lay(li).addClass(THIS);
1169
+ li.innerHTML = lang.month[i] + (isCN ? '月' : '');
1170
+ ul.appendChild(li);
1171
+ if(listYM[0] < that.firstDate.year){
1172
+ ymd.date = options.min.date;
1173
+ } else if(listYM[0] >= that.firstDate.year){
1174
+ ymd.date = options.max.date;
1175
+ }
1176
+ that.limit(lay(li), ymd, index);
1177
+ });
1178
+ lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', listYM[0] + '-' + listYM[1])
1179
+ .html(listYM[0] + text);
1180
+ } else if(type === 'time'){ //时间列表
1181
+ //检测时分秒状态是否在有效日期时间范围内
1182
+ var setTimeStatus = function(){
1183
+ lay(ul).find('ol').each(function(i, ol){
1184
+ lay(ol).find('li').each(function(ii, li){
1185
+ that.limit(lay(li), [{
1186
+ hours: ii
1187
+ }, {
1188
+ hours: that[startEnd].hours
1189
+ ,minutes: ii
1190
+ }, {
1191
+ hours: that[startEnd].hours
1192
+ ,minutes: that[startEnd].minutes
1193
+ ,seconds: ii
1194
+ }][i], index, [['hours'], ['hours', 'minutes'], ['hours', 'minutes', 'seconds']][i]);
1195
+ });
1196
+ });
1197
+ if(!options.range) that.limit(lay(that.footer).find(ELEM_CONFIRM), that[startEnd], 0, ['hours', 'minutes', 'seconds']);
1198
+ };
1199
+ if(options.range){
1200
+ if(!that[startEnd]) that[startEnd] = {
1201
+ hours: 0
1202
+ ,minutes: 0
1203
+ ,seconds: 0
1204
+ };
1205
+ } else {
1206
+ that[startEnd] = dateTime;
1207
+ }
1208
+ lay.each([24, 60, 60], function(i, item){
1209
+ var li = lay.elem('li'), childUL = ['<p>'+ lang.time[i] +'</p><ol>'];
1210
+ lay.each(new Array(item), function(ii){
1211
+ childUL.push('<li'+ (that[startEnd][hms[i]] === ii ? ' class="'+ THIS +'"' : '') +'>'+ lay.digit(ii, 2) +'</li>');
1212
+ });
1213
+ li.innerHTML = childUL.join('') + '</ol>';
1214
+ ul.appendChild(li);
1215
+ });
1216
+ setTimeStatus();
1217
+ }
1218
+
1219
+ //插入容器
1220
+ if(haveList) elemCont.removeChild(haveList);
1221
+ elemCont.appendChild(ul);
1222
+
1223
+ //年月
1224
+ if(type === 'year' || type === 'month'){
1225
+ //显示切换箭头
1226
+ lay(that.elemMain[index]).addClass('laydate-ym-show');
1227
+
1228
+ //选中
1229
+ lay(ul).find('li').on('click', function(){
1230
+ var ym = lay(this).attr('lay-ym') | 0;
1231
+ if(lay(this).hasClass(DISABLED)) return;
1232
+
1233
+ if(index === 0){
1234
+ dateTime[type] = ym;
1235
+ if(isAlone) that.startDate[type] = ym;
1236
+ that.limit(lay(that.footer).find(ELEM_CONFIRM), null, 0);
1237
+ } else { //范围选择
1238
+ if(isAlone){ //非date/datetime类型
1239
+ that.endDate[type] = ym;
1240
+ } else { //date/datetime类型
1241
+ var YM = type === 'year'
1242
+ ? that.getAsYM(ym, listYM[1] - 1, 'sub')
1243
+ : that.getAsYM(listYM[0], ym, 'sub');
1244
+ lay.extend(dateTime, {
1245
+ year: YM[0]
1246
+ ,month: YM[1]
1247
+ });
1248
+ }
1249
+ }
1250
+
1251
+ if(options.type === 'year' || options.type === 'month'){
1252
+ lay(ul).find('.'+ THIS).removeClass(THIS);
1253
+ lay(this).addClass(THIS);
1254
+
1255
+ //如果为年月选择器,点击了年列表,则切换到月选择器
1256
+ if(options.type === 'month' && type === 'year'){
1257
+ that.listYM[index][0] = ym;
1258
+ isAlone && (that[['startDate', 'endDate'][index]].year = ym);
1259
+ that.list('month', index);
1260
+ }
1261
+ } else {
1262
+ that.checkDate('limit').calendar();
1263
+ that.closeList();
1264
+ }
1265
+
1266
+ that.setBtnStatus(); //同步按钮可点状态
1267
+ options.range || that.done(null, 'change');
1268
+ lay(that.footer).find(ELEM_TIME_BTN).removeClass(DISABLED);
1269
+ });
1270
+ } else {
1271
+ var span = lay.elem('span', {
1272
+ 'class': ELEM_TIME_TEXT
1273
+ }), scroll = function(){ //滚动条定位
1274
+ lay(ul).find('ol').each(function(i){
1275
+ var ol = this
1276
+ ,li = lay(ol).find('li')
1277
+ ol.scrollTop = 30*(that[startEnd][hms[i]] - 2);
1278
+ if(ol.scrollTop <= 0){
1279
+ li.each(function(ii, item){
1280
+ if(!lay(this).hasClass(DISABLED)){
1281
+ ol.scrollTop = 30*(ii - 2);
1282
+ return true;
1283
+ }
1284
+ });
1285
+ }
1286
+ });
1287
+ }, haveSpan = lay(elemHeader[2]).find('.'+ ELEM_TIME_TEXT);
1288
+ scroll()
1289
+ span.innerHTML = options.range ? [lang.startTime,lang.endTime][index] : lang.timeTips
1290
+ lay(that.elemMain[index]).addClass('laydate-time-show');
1291
+ if(haveSpan[0]) haveSpan.remove();
1292
+ elemHeader[2].appendChild(span);
1293
+
1294
+ lay(ul).find('ol').each(function(i){
1295
+ var ol = this;
1296
+ //选择时分秒
1297
+ lay(ol).find('li').on('click', function(){
1298
+ var value = this.innerHTML | 0;
1299
+ if(lay(this).hasClass(DISABLED)) return;
1300
+ if(options.range){
1301
+ that[startEnd][hms[i]] = value;
1302
+ } else {
1303
+ dateTime[hms[i]] = value;
1304
+ }
1305
+ lay(ol).find('.'+ THIS).removeClass(THIS);
1306
+ lay(this).addClass(THIS);
1307
+
1308
+ setTimeStatus();
1309
+ scroll();
1310
+ (that.endDate || options.type === 'time') && that.done(null, 'change');
1311
+
1312
+ //同步按钮可点状态
1313
+ that.setBtnStatus();
1314
+ });
1315
+ });
1316
+ }
1317
+
1318
+ return that;
1319
+ };
1320
+
1321
+ //记录列表切换后的年月
1322
+ Class.prototype.listYM = [];
1323
+
1324
+ //关闭列表
1325
+ Class.prototype.closeList = function(){
1326
+ var that = this
1327
+ ,options = that.config;
1328
+
1329
+ lay.each(that.elemCont, function(index, item){
1330
+ lay(this).find('.'+ ELEM_LIST).remove();
1331
+ lay(that.elemMain[index]).removeClass('laydate-ym-show laydate-time-show');
1332
+ });
1333
+ lay(that.elem).find('.'+ ELEM_TIME_TEXT).remove();
1334
+ };
1335
+
1336
+ //检测结束日期是否超出开始日期
1337
+ Class.prototype.setBtnStatus = function(tips, start, end){
1338
+ var that = this
1339
+ ,options = that.config
1340
+ ,isOut, elemBtn = lay(that.footer).find(ELEM_CONFIRM)
1341
+ ,isAlone = options.range && options.type !== 'date' && options.type !== 'time';
1342
+ if(isAlone){
1343
+ start = start || that.startDate;
1344
+ end = end || that.endDate;
1345
+ isOut = that.newDate(start).getTime() > that.newDate(end).getTime();
1346
+
1347
+ //如果不在有效日期内,直接禁用按钮,否则比较开始和结束日期
1348
+ (that.limit(null, start) || that.limit(null, end))
1349
+ ? elemBtn.addClass(DISABLED)
1350
+ : elemBtn[isOut ? 'addClass' : 'removeClass'](DISABLED);
1351
+
1352
+ //是否异常提示
1353
+ if(tips && isOut) that.hint(
1354
+ typeof tips === 'string' ? TIPS_OUT.replace(/日期/g, tips) : TIPS_OUT
1355
+ );
1356
+ }
1357
+ };
1358
+
1359
+ //转义为规定格式的日期字符
1360
+ Class.prototype.parse = function(state, date){
1361
+ var that = this
1362
+ ,options = that.config
1363
+ ,dateTime = date || (state
1364
+ ? lay.extend({}, that.endDate, that.endTime)
1365
+ : (options.range ? lay.extend({}, that.startDate, that.startTime) : options.dateTime))
1366
+ ,format = that.format.concat();
1367
+
1368
+ //转义为规定格式
1369
+ lay.each(format, function(i, item){
1370
+ if(/yyyy|y/.test(item)){ //年
1371
+ format[i] = lay.digit(dateTime.year, item.length);
1372
+ } else if(/MM|M/.test(item)){ //月
1373
+ format[i] = lay.digit(dateTime.month + 1, item.length);
1374
+ } else if(/dd|d/.test(item)){ //日
1375
+ format[i] = lay.digit(dateTime.date, item.length);
1376
+ } else if(/HH|H/.test(item)){ //时
1377
+ format[i] = lay.digit(dateTime.hours, item.length);
1378
+ } else if(/mm|m/.test(item)){ //分
1379
+ format[i] = lay.digit(dateTime.minutes, item.length);
1380
+ } else if(/ss|s/.test(item)){ //秒
1381
+ format[i] = lay.digit(dateTime.seconds, item.length);
1382
+ }
1383
+ });
1384
+
1385
+ //返回日期范围字符
1386
+ if(options.range && !state){
1387
+ return format.join('') + ' '+ options.range +' ' + that.parse(1);
1388
+ }
1389
+
1390
+ return format.join('');
1391
+ };
1392
+
1393
+ //创建指定日期时间对象
1394
+ Class.prototype.newDate = function(dateTime){
1395
+ dateTime = dateTime || {};
1396
+ return new Date(
1397
+ dateTime.year || 1
1398
+ ,dateTime.month || 0
1399
+ ,dateTime.date || 1
1400
+ ,dateTime.hours || 0
1401
+ ,dateTime.minutes || 0
1402
+ ,dateTime.seconds || 0
1403
+ );
1404
+ };
1405
+
1406
+ //赋值
1407
+ Class.prototype.setValue = function(value){
1408
+ var that = this
1409
+ ,options = that.config
1410
+ ,elem = that.bindElem || options.elem[0]
1411
+ ,valType = that.isInput(elem) ? 'val' : 'html'
1412
+
1413
+ options.position === 'static' || lay(elem)[valType](value || '');
1414
+ return this;
1415
+ };
1416
+
1417
+ //标记范围内的日期
1418
+ Class.prototype.stampRange = function(){
1419
+ var that = this
1420
+ ,options = that.config
1421
+ ,startTime, endTime
1422
+ ,tds = lay(that.elem).find('td');
1423
+
1424
+ if(options.range && !that.endDate) lay(that.footer).find(ELEM_CONFIRM).addClass(DISABLED);
1425
+ if(!that.endDate) return;
1426
+
1427
+ startTime = that.newDate({
1428
+ year: that.startDate.year
1429
+ ,month: that.startDate.month
1430
+ ,date: that.startDate.date
1431
+ }).getTime();
1432
+
1433
+ endTime = that.newDate({
1434
+ year: that.endDate.year
1435
+ ,month: that.endDate.month
1436
+ ,date: that.endDate.date
1437
+ }).getTime();
1438
+
1439
+ if(startTime > endTime) return that.hint(TIPS_OUT);
1440
+
1441
+ lay.each(tds, function(i, item){
1442
+ var ymd = lay(item).attr('lay-ymd').split('-')
1443
+ ,thisTime = that.newDate({
1444
+ year: ymd[0]
1445
+ ,month: ymd[1] - 1
1446
+ ,date: ymd[2]
1447
+ }).getTime();
1448
+ lay(item).removeClass(ELEM_SELECTED + ' ' + THIS);
1449
+ if(thisTime === startTime || thisTime === endTime){
1450
+ lay(item).addClass(
1451
+ lay(item).hasClass(ELEM_PREV) || lay(item).hasClass(ELEM_NEXT)
1452
+ ? ELEM_SELECTED
1453
+ : THIS
1454
+ );
1455
+ }
1456
+ if(thisTime > startTime && thisTime < endTime){
1457
+ lay(item).addClass(ELEM_SELECTED);
1458
+ }
1459
+ });
1460
+ };
1461
+
1462
+ //执行done/change回调
1463
+ Class.prototype.done = function(param, type){
1464
+ var that = this
1465
+ ,options = that.config
1466
+ ,start = lay.extend({}, that.startDate ? lay.extend(that.startDate, that.startTime) : options.dateTime)
1467
+ ,end = lay.extend({}, lay.extend(that.endDate, that.endTime))
1468
+
1469
+ lay.each([start, end], function(i, item){
1470
+ if(!('month' in item)) return;
1471
+ lay.extend(item, {
1472
+ month: item.month + 1
1473
+ });
1474
+ });
1475
+
1476
+ param = param || [that.parse(), start, end];
1477
+ typeof options[type || 'done'] === 'function' && options[type || 'done'].apply(options, param);
1478
+
1479
+ return that;
1480
+ };
1481
+
1482
+ //选择日期
1483
+ Class.prototype.choose = function(td){
1484
+ var that = this
1485
+ ,options = that.config
1486
+ ,dateTime = options.dateTime
1487
+
1488
+ ,tds = lay(that.elem).find('td')
1489
+ ,YMD = td.attr('lay-ymd').split('-')
1490
+
1491
+ ,setDateTime = function(one){
1492
+ var thisDate = new Date();
1493
+
1494
+ //同步dateTime
1495
+ one && lay.extend(dateTime, YMD);
1496
+
1497
+ //记录开始日期
1498
+ if(options.range){
1499
+ that.startDate ? lay.extend(that.startDate, YMD) : (
1500
+ that.startDate = lay.extend({}, YMD, that.startTime)
1501
+ );
1502
+ that.startYMD = YMD;
1503
+ }
1504
+ };
1505
+
1506
+ YMD = {
1507
+ year: YMD[0] | 0
1508
+ ,month: (YMD[1] | 0) - 1
1509
+ ,date: YMD[2] | 0
1510
+ };
1511
+
1512
+ if(td.hasClass(DISABLED)) return;
1513
+
1514
+ //范围选择
1515
+ if(options.range){
1516
+
1517
+ lay.each(['startTime', 'endTime'], function(i, item){
1518
+ that[item] = that[item] || {
1519
+ hours: 0
1520
+ ,minutes: 0
1521
+ ,seconds: 0
1522
+ };
1523
+ });
1524
+
1525
+ if(that.endState){ //重新选择
1526
+ setDateTime();
1527
+ delete that.endState;
1528
+ delete that.endDate;
1529
+ that.startState = true;
1530
+ tds.removeClass(THIS + ' ' + ELEM_SELECTED);
1531
+ td.addClass(THIS);
1532
+ } else if(that.startState){ //选中截止
1533
+ td.addClass(THIS);
1534
+
1535
+ that.endDate ? lay.extend(that.endDate, YMD) : (
1536
+ that.endDate = lay.extend({}, YMD, that.endTime)
1537
+ );
1538
+
1539
+ //判断是否顺时或逆时选择
1540
+ if(that.newDate(YMD).getTime() < that.newDate(that.startYMD).getTime()){
1541
+ var startDate = lay.extend({}, that.endDate, {
1542
+ hours: that.startDate.hours
1543
+ ,minutes: that.startDate.minutes
1544
+ ,seconds: that.startDate.seconds
1545
+ });
1546
+ lay.extend(that.endDate, that.startDate, {
1547
+ hours: that.endDate.hours
1548
+ ,minutes: that.endDate.minutes
1549
+ ,seconds: that.endDate.seconds
1550
+ });
1551
+ that.startDate = startDate;
1552
+ }
1553
+
1554
+ options.showBottom || that.done();
1555
+ that.stampRange(); //标记范围内的日期
1556
+ that.endState = true;
1557
+ that.done(null, 'change');
1558
+ } else { //选中开始
1559
+ td.addClass(THIS);
1560
+ setDateTime();
1561
+ that.startState = true;
1562
+ }
1563
+ lay(that.footer).find(ELEM_CONFIRM)[that.endDate ? 'removeClass' : 'addClass'](DISABLED);
1564
+ } else if(options.position === 'static'){ //直接嵌套的选中
1565
+ setDateTime(true);
1566
+ that.calendar().done().done(null, 'change');
1567
+ } else if(options.type === 'date'){
1568
+ setDateTime(true);
1569
+ that.setValue(that.parse()).remove().done();
1570
+ } else if(options.type === 'datetime'){
1571
+ setDateTime(true);
1572
+ that.calendar().done(null, 'change');
1573
+ }
1574
+ };
1575
+
1576
+ //底部按钮
1577
+ Class.prototype.tool = function(btn, type){
1578
+ var that = this
1579
+ ,options = that.config
1580
+ ,dateTime = options.dateTime
1581
+ ,isStatic = options.position === 'static'
1582
+ ,active = {
1583
+ //选择时间
1584
+ datetime: function(){
1585
+ if(lay(btn).hasClass(DISABLED)) return;
1586
+ that.list('time', 0);
1587
+ options.range && that.list('time', 1);
1588
+ lay(btn).attr('lay-type', 'date').html(that.lang().dateTips);
1589
+ }
1590
+
1591
+ //选择日期
1592
+ ,date: function(){
1593
+ that.closeList();
1594
+ lay(btn).attr('lay-type', 'datetime').html(that.lang().timeTips);
1595
+ }
1596
+
1597
+ //清空、重置
1598
+ ,clear: function(){
1599
+ that.setValue('').remove();
1600
+ isStatic && (
1601
+ lay.extend(dateTime, that.firstDate)
1602
+ ,that.calendar()
1603
+ )
1604
+ options.range && (
1605
+ delete that.startState
1606
+ ,delete that.endState
1607
+ ,delete that.endDate
1608
+ ,delete that.startTime
1609
+ ,delete that.endTime
1610
+ );
1611
+ that.done(['', {}, {}]);
1612
+ }
1613
+
1614
+ //现在
1615
+ ,now: function(){
1616
+ var thisDate = new Date();
1617
+ lay.extend(dateTime, that.systemDate(), {
1618
+ hours: thisDate.getHours()
1619
+ ,minutes: thisDate.getMinutes()
1620
+ ,seconds: thisDate.getSeconds()
1621
+ });
1622
+ that.setValue(that.parse()).remove();
1623
+ isStatic && that.calendar();
1624
+ that.done();
1625
+ }
1626
+
1627
+ //确定
1628
+ ,confirm: function(){
1629
+ if(options.range){
1630
+ if(!that.endDate) return that.hint('请先选择日期范围');
1631
+ if(lay(btn).hasClass(DISABLED)) return that.hint(
1632
+ options.type === 'time' ? TIPS_OUT.replace(/日期/g, '时间') : TIPS_OUT
1633
+ );
1634
+ } else {
1635
+ if(lay(btn).hasClass(DISABLED)) return that.hint('不在有效日期或时间范围内');
1636
+ }
1637
+ that.done();
1638
+ that.setValue(that.parse()).remove()
1639
+ }
1640
+ };
1641
+ active[type] && active[type]();
1642
+ };
1643
+
1644
+ //统一切换处理
1645
+ Class.prototype.change = function(index){
1646
+ var that = this
1647
+ ,options = that.config
1648
+ ,dateTime = options.dateTime
1649
+ ,isAlone = options.range && (options.type === 'year' || options.type === 'month')
1650
+
1651
+ ,elemCont = that.elemCont[index || 0]
1652
+ ,listYM = that.listYM[index]
1653
+ ,addSubYeay = function(type){
1654
+ var startEnd = ['startDate', 'endDate'][index]
1655
+ ,isYear = lay(elemCont).find('.laydate-year-list')[0]
1656
+ ,isMonth = lay(elemCont).find('.laydate-month-list')[0];
1657
+
1658
+ //切换年列表
1659
+ if(isYear){
1660
+ listYM[0] = type ? listYM[0] - 15 : listYM[0] + 15;
1661
+ that.list('year', index);
1662
+ }
1663
+
1664
+ if(isMonth){ //切换月面板中的年
1665
+ type ? listYM[0]-- : listYM[0]++;
1666
+ that.list('month', index);
1667
+ }
1668
+
1669
+ if(isYear || isMonth){
1670
+ lay.extend(dateTime, {
1671
+ year: listYM[0]
1672
+ });
1673
+ if(isAlone) that[startEnd].year = listYM[0];
1674
+ options.range || that.done(null, 'change');
1675
+ that.setBtnStatus();
1676
+ options.range || that.limit(lay(that.footer).find(ELEM_CONFIRM), {
1677
+ year: listYM[0]
1678
+ });
1679
+ }
1680
+ return isYear || isMonth;
1681
+ };
1682
+
1683
+ return {
1684
+ prevYear: function(){
1685
+ if(addSubYeay('sub')) return;
1686
+ dateTime.year--;
1687
+ that.checkDate('limit').calendar();
1688
+ options.range || that.done(null, 'change');
1689
+ }
1690
+ ,prevMonth: function(){
1691
+ var YM = that.getAsYM(dateTime.year, dateTime.month, 'sub');
1692
+ lay.extend(dateTime, {
1693
+ year: YM[0]
1694
+ ,month: YM[1]
1695
+ });
1696
+ that.checkDate('limit').calendar();
1697
+ options.range || that.done(null, 'change');
1698
+ }
1699
+ ,nextMonth: function(){
1700
+ var YM = that.getAsYM(dateTime.year, dateTime.month);
1701
+ lay.extend(dateTime, {
1702
+ year: YM[0]
1703
+ ,month: YM[1]
1704
+ });
1705
+ that.checkDate('limit').calendar();
1706
+ options.range || that.done(null, 'change');
1707
+ }
1708
+ ,nextYear: function(){
1709
+ if(addSubYeay()) return;
1710
+ dateTime.year++
1711
+ that.checkDate('limit').calendar();
1712
+ options.range || that.done(null, 'change');
1713
+ }
1714
+ };
1715
+ };
1716
+
1717
+ //日期切换事件
1718
+ Class.prototype.changeEvent = function(){
1719
+ var that = this
1720
+ ,options = that.config;
1721
+
1722
+ //日期选择事件
1723
+ lay(that.elem).on('click', function(e){
1724
+ lay.stope(e);
1725
+ });
1726
+
1727
+ //年月切换
1728
+ lay.each(that.elemHeader, function(i, header){
1729
+ //上一年
1730
+ lay(header[0]).on('click', function(e){
1731
+ that.change(i).prevYear();
1732
+ });
1733
+
1734
+ //上一月
1735
+ lay(header[1]).on('click', function(e){
1736
+ that.change(i).prevMonth();
1737
+ });
1738
+
1739
+ //选择年月
1740
+ lay(header[2]).find('span').on('click', function(e){
1741
+ var othis = lay(this)
1742
+ ,layYM = othis.attr('lay-ym')
1743
+ ,layType = othis.attr('lay-type');
1744
+
1745
+ if(!layYM) return;
1746
+
1747
+ layYM = layYM.split('-');
1748
+
1749
+ that.listYM[i] = [layYM[0] | 0, layYM[1] | 0];
1750
+ that.list(layType, i);
1751
+ lay(that.footer).find(ELEM_TIME_BTN).addClass(DISABLED);
1752
+ });
1753
+
1754
+ //下一月
1755
+ lay(header[3]).on('click', function(e){
1756
+ that.change(i).nextMonth();
1757
+ });
1758
+
1759
+ //下一年
1760
+ lay(header[4]).on('click', function(e){
1761
+ that.change(i).nextYear();
1762
+ });
1763
+ });
1764
+
1765
+ //点击日期
1766
+ lay.each(that.table, function(i, table){
1767
+ var tds = lay(table).find('td');
1768
+ tds.on('click', function(){
1769
+ that.choose(lay(this));
1770
+ });
1771
+ });
1772
+
1773
+ //点击底部按钮
1774
+ lay(that.footer).find('span').on('click', function(){
1775
+ var type = lay(this).attr('lay-type');
1776
+ that.tool(this, type);
1777
+ });
1778
+ };
1779
+
1780
+ //是否输入框
1781
+ Class.prototype.isInput = function(elem){
1782
+ return /input|textarea/.test(elem.tagName.toLocaleLowerCase());
1783
+ };
1784
+
1785
+ //绑定的元素事件处理
1786
+ Class.prototype.events = function(){
1787
+ var that = this
1788
+ ,options = that.config
1789
+
1790
+ //绑定呼出控件事件
1791
+ ,showEvent = function(elem, bind){
1792
+ elem.on(options.trigger, function(){
1793
+ bind && (that.bindElem = this);
1794
+ that.render();
1795
+ });
1796
+ };
1797
+
1798
+ if(!options.elem[0] || options.elem[0].eventHandler) return;
1799
+
1800
+ showEvent(options.elem, 'bind');
1801
+ showEvent(options.eventElem);
1802
+
1803
+ //绑定关闭控件事件
1804
+ lay(document).on('click', function(e){
1805
+ if(e.target === options.elem[0]
1806
+ || e.target === options.eventElem[0]
1807
+ || e.target === lay(options.closeStop)[0]){
1808
+ return;
1809
+ }
1810
+ that.remove();
1811
+ }).on('keydown', function(e){
1812
+ if(e.keyCode === 13){
1813
+ if(lay('#'+ that.elemID)[0] && that.elemID === Class.thisElem){
1814
+ e.preventDefault();
1815
+ lay(that.footer).find(ELEM_CONFIRM)[0].click();
1816
+ }
1817
+ }
1818
+ });
1819
+
1820
+ //自适应定位
1821
+ lay(window).on('resize', function(){
1822
+ if(!that.elem || !lay(ELEM)[0]){
1823
+ return false;
1824
+ }
1825
+ that.position();
1826
+ });
1827
+
1828
+ options.elem[0].eventHandler = true;
1829
+ };
1830
+
1831
+
1832
+ //核心接口
1833
+ laydate.render = function(options){
1834
+ var inst = new Class(options);
1835
+ return thisDate.call(inst);
1836
+ };
1837
+
1838
+ //得到某月的最后一天
1839
+ laydate.getEndDate = function(month, year){
1840
+ var thisDate = new Date();
1841
+ //设置日期为下个月的第一天
1842
+ thisDate.setFullYear(
1843
+ year || thisDate.getFullYear()
1844
+ ,month || (thisDate.getMonth() + 1)
1845
+ ,1);
1846
+ //减去一天,得到当前月最后一天
1847
+ return new Date(thisDate.getTime() - 1000*60*60*24).getDate();
1848
+ };
1849
+
1850
+ //暴露lay
1851
+ window.lay = window.lay || lay;
1852
+
1853
+ //加载方式
1854
+ isLayui ? (
1855
+ laydate.ready()
1856
+ ,layui.define(function(exports){ //layui加载
1857
+ laydate.path = layui.cache.dir;
1858
+ exports(MOD_NAME, laydate);
1859
+ })
1860
+ ) : (
1861
+ (typeof define === 'function' && define.amd) ? define(function(){ //requirejs加载
1862
+ return laydate;
1863
+ }) : function(){ //普通script标签加载
1864
+ laydate.ready();
1865
+ window.laydate = laydate
1866
+ }()
1867
+ );
1868
+
1869
+ }();