laydate.dev.js 26 KB

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