datePicker.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. /*
  2. * PHPWind util Library
  3. * @Copyright : Copyright 2011, phpwind.com
  4. * @Descript : datePicker 日历组件
  5. * @Author : jquerytools (http://jquerytools.org/demos/dateinput/)
  6. * @Modify : chaoren1641@gmail.com
  7. * @Depend : jquery.js(1.7 or later)
  8. * $Id: datePicker.js 22586 2012-12-25 10:54:55Z hao.lin $ :
  9. */
  10. ;(function($, window, document, undefined) {
  11. var pluginName = 'datePicker';
  12. var instances = [];
  13. // h=72, j=74, k=75, l=76, down=40, left=37, up=38, right=39
  14. var KEYS = [75, 76, 38, 39, 74, 72, 40, 37], LABELS = {};
  15. var defaults = {
  16. format : 'yyyy-mm-dd',
  17. selectors : true,
  18. time : false,
  19. yearRange : [-50, 20],
  20. lang : 'zh-CN',
  21. offset : [0, 0],
  22. speed : 0,
  23. firstDay : 0, // The first day of the week, Sun = 0, Mon = 1, ...
  24. min : undefined,
  25. max : undefined,
  26. trigger : false,
  27. css : {
  28. prefix : 'cal',
  29. input : 'date',
  30. // ids
  31. root : 0,
  32. head : 0,
  33. title : 0,
  34. prev : 0,
  35. next : 0,
  36. month : 0,
  37. year : 0,
  38. days : 0,
  39. body : 0,
  40. weeks : 0,
  41. today : 0,
  42. current : 0,
  43. // classnames
  44. week : 0,
  45. off : 0,
  46. sunday : 0,
  47. focus : 0,
  48. disabled : 0,
  49. trigger : 0
  50. }
  51. };
  52. var localize = function(language, labels) {
  53. $.each(labels, function(key, val) {
  54. labels[key] = val.split(",");
  55. });
  56. LABELS[language] = labels;
  57. };
  58. //多语言配置
  59. localize("en", {
  60. months : 'January,February,March,April,May,June,July,August,September,October,November,December',
  61. shortMonths : 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec',
  62. days : 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday',
  63. shortDays : 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'
  64. });
  65. localize("zh-CN", {
  66. months : '一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月',
  67. shortMonths : '一,二,三,四,五,六,七,八,九,十,十一,十二',
  68. days : '周日,周一,周二,周三,周四,周五,周六',
  69. shortDays : '日,一,二,三,四,五,六'
  70. });
  71. //{{{ private functions
  72. //返回某年某月的天数
  73. function dayAm(year, month) {
  74. return 32 - new Date(year, month, 32).getDate();
  75. }
  76. function zeropad(val, len) {
  77. val = '' + val;
  78. len = len || 2;
  79. while(val.length < len) {
  80. val = "0" + val;
  81. }
  82. return val;
  83. }
  84. // thanks: http://stevenlevithan.com/assets/misc/date.format.js
  85. var Re = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, tmpTag = $("<a/>");
  86. //格式化时间
  87. function format(date, fmt, lang) {
  88. var d = date.getDate(), D = date.getDay(), m = date.getMonth(), y = date.getFullYear(),
  89. h = date.getHours(),M = date.getMinutes(),
  90. flags = {
  91. d : d,
  92. dd : zeropad(d),
  93. ddd : LABELS[lang].shortDays[D],
  94. dddd : LABELS[lang].days[D],
  95. m : m + 1,
  96. mm : zeropad(m + 1),
  97. mmm : LABELS[lang].shortMonths[m],
  98. mmmm : LABELS[lang].months[m],
  99. yy : String(y).slice(2),
  100. yyyy : y,
  101. HH: zeropad(h),
  102. MM : zeropad(M)
  103. };
  104. var ret = fmt.replace(Re, function($0) {
  105. return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
  106. });
  107. // a small trick to handle special characters
  108. return tmpTag.html(ret).html();
  109. }
  110. function integer(val) {
  111. return parseInt(val, 10);
  112. }
  113. function isSameDay(d1, d2) {
  114. return d1.getFullYear() === d2.getFullYear() && d1.getMonth() == d2.getMonth() && d1.getDate() == d2.getDate();
  115. }
  116. function parseDate(val) {
  117. if(!val) {
  118. return;
  119. }
  120. if(val.constructor == Date) {
  121. return val;
  122. }
  123. if( typeof val == 'string') {
  124. // rfc3339?
  125. var els = val.split(" ");
  126. var date,time;
  127. var y,m,d,h,s;
  128. date = els[0].split('-');
  129. if(date.length !== 3) {
  130. return;
  131. }
  132. if(els.length === 2) {
  133. time = els[1].split(':');
  134. }else {
  135. time = '00:00'.split(':');
  136. }
  137. y = date[0],m = date[1]-1,d = date[2];
  138. h = time[0],s = time[1];
  139. return new Date(y,m,d,h,s,0);
  140. // invalid offset
  141. if(!/^-?\d+$/.test(val)) {
  142. return;
  143. }
  144. // convert to integer
  145. val = integer(val);
  146. }
  147. var date = new Date();
  148. date.setDate(date.getDate() + val);
  149. return date;
  150. }
  151. function Plugin( input, options ) {
  152. this.options = $.extend( {}, defaults, options) ;
  153. this.input = input;
  154. this.init();
  155. }
  156. Plugin.prototype.init = function() {
  157. var options = this.options,input = this.input;
  158. if(options.time) {
  159. options.format = 'yyyy-mm-dd HH:MM'
  160. }
  161. // CSS prefix
  162. $.each(options.css, function(key, val) {
  163. if(!val && key != 'prefix') {
  164. options.css[key] = (options.css.prefix || '') + (val || key);
  165. }
  166. });
  167. // variables
  168. var self = this, now = new Date(), css = options.css, labels = LABELS[options.lang], root = $("#" + css.root), title = root.find("#" + css.title), trigger, pm, nm, currYear, currMonth, currDay, value = input.attr("data-value") || options.value || input.val(), min = input.attr("min") || options.min, max = input.attr("max") || options.max, opened;
  169. // zero min is not undefined
  170. if(min === 0) {
  171. min = "0";
  172. }
  173. // use sane values for value, min & max
  174. value = parseDate(value) || now;
  175. min = parseDate(min || options.yearRange[0] * 365);
  176. max = parseDate(max || options.yearRange[1] * 365);
  177. // check that language exists
  178. if(!labels) {
  179. throw "不存在的语言: " + options.lang;
  180. }
  181. // Replace built-in date input: NOTE: input.attr("type", "text") throws exception by the browser
  182. if(input.attr("type") === 'date') {
  183. var tmp = $("<input/>");
  184. $.each("class,disabled,id,maxlength,name,readonly,required,size,style,tabindex,title,value".split(","), function(i, attr) {
  185. tmp.attr(attr, input.attr(attr));
  186. });
  187. input.replaceWith(tmp);
  188. input = tmp;
  189. }
  190. input.addClass(css.input);
  191. var fire = input.add(self);
  192. // construct layout
  193. if(!root.length) {
  194. // root
  195. root = $('<div><div><a/><div/><a/></div><div><div/><div/></div></div>').hide().css({
  196. position : 'absolute'
  197. }).attr("id", css.root);
  198. // elements
  199. root.children().eq(0).attr("id", css.head).end().eq(1).attr("id", css.body).children().eq(0).attr("id", css.days).end().eq(1).attr("id", css.weeks).end().end().end().find("a").eq(0).attr("id", css.prev).end().eq(1).attr("id", css.next);
  200. // title
  201. title = root.find("#" + css.head).find("div").attr("id", css.title);
  202. // year & month selectors
  203. if(options.selectors) {
  204. var monthSelector = $("<select/>").attr("id", css.month), yearSelector = $("<select/>").attr("id", css.year);
  205. title.html(monthSelector.add(yearSelector));
  206. }
  207. // day titles
  208. var days = root.find("#" + css.days);
  209. // days of the week
  210. for(var d = 0; d < 7; d++) {
  211. days.append($("<span/>").text(labels.shortDays[(d + options.firstDay) % 7]));
  212. }
  213. var body = root.find("#" + css.body);
  214. $('<div class="caltime"><button type="button" class="btn btn_submit fr" name="submit">确认</button><input id="calHour" type="number" class="input" min="0" max="23" size="2" value="0"><span>点</span><input id="calMin" class="input" type="number" size="2" min="1" max="59" value="0"><span>分</span></div>').appendTo(body);
  215. $("body").append(root);
  216. }
  217. // trigger icon
  218. if(options.trigger) {
  219. trigger = $("<a/>").attr("href", "#").addClass(css.trigger).click(function(e) {
  220. self.show();
  221. return e.preventDefault();
  222. }).insertAfter(input);
  223. }
  224. // layout elements
  225. var weeks = root.find("#" + css.weeks);
  226. yearSelector = root.find("#" + css.year);
  227. monthSelector = root.find("#" + css.month);
  228. //{{{ pick
  229. function select(date, options, e) {
  230. if(!date) return;
  231. // current value
  232. value = date;
  233. currYear = date.getFullYear();
  234. currMonth = date.getMonth();
  235. currDay = date.getDate();
  236. if (e.type == "click" && $.browser && !$.browser.msie) {
  237. input.focus();
  238. }
  239. // select
  240. e = e || $.Event("api");
  241. e.type = "select";
  242. fire.trigger(e, [date]);
  243. if(e.isDefaultPrevented()) {
  244. return;
  245. }
  246. //如果选项有时间,则加上时间
  247. if(options.time) {
  248. var timeInput = root.find('input');
  249. var hour = parseInt(timeInput.eq(0).val(),10);
  250. var min = parseInt(timeInput.eq(1).val(),10);
  251. if(isNaN(hour)) {
  252. hour = 0;
  253. }
  254. if(isNaN(min)) {
  255. min = 0;
  256. }
  257. if(hour < 10) {
  258. hour = '0' + hour;
  259. }else if(hour < 0 || hour > 23) {
  260. hour = '00';
  261. }
  262. if(min < 10) {
  263. min = '0' + min;
  264. }else if(min < 0 || min > 59) {
  265. min = '00';
  266. }
  267. date.setHours(hour);
  268. date.setMinutes(min);
  269. }
  270. // formatting
  271. var date = format(date, options.format, options.lang);
  272. input.val(date);
  273. // store value into input
  274. input.data("date", date);
  275. //设置val后,IE导致触发focus事件,导致窗口关闭后再次被打开
  276. setTimeout(function() {
  277. self.hide(e);
  278. },100);
  279. }
  280. //}}}
  281. //{{{ onShow
  282. function onShow(ev) {
  283. ev.type = "onShow";
  284. fire.trigger(ev);
  285. //快捷键处理
  286. $(document).bind("keydown.d", function(e) {
  287. if(e.ctrlKey) {
  288. return true;
  289. }
  290. var key = e.keyCode;
  291. // backspace clears the value
  292. if(e.target == input[0]) {//如果是在当前input按back键,清除值并隐藏日历
  293. if(key == 8 || key == 46) {
  294. input.val("");
  295. return self.hide(e);
  296. }
  297. }
  298. // esc key
  299. if(key == 27) {
  300. return self.hide(e);
  301. }
  302. //如果有time,则不要快捷键
  303. if(options.time) {
  304. return;
  305. }
  306. if($(KEYS).index(key) >= 0) {
  307. if(!opened) {
  308. self.show(e);
  309. return e.preventDefault();
  310. }
  311. var days = $("#" + css.weeks + " a"), el = $("." + css.focus), index = days.index(el);
  312. el.removeClass(css.focus);
  313. if(key == 74 || key == 40) {
  314. index += 7;
  315. } else if(key == 75 || key == 38) {
  316. index -= 7;
  317. } else if(key == 76 || key == 39) {
  318. index += 1;
  319. } else if(key == 72 || key == 37) {
  320. index -= 1;
  321. }
  322. if(index > 41) {
  323. self.addMonth();
  324. el = $("#" + css.weeks + " a:eq(" + (index - 42) + ")");
  325. } else if(index < 0) {
  326. self.addMonth(-1);
  327. el = $("#" + css.weeks + " a:eq(" + (index + 42) + ")");
  328. } else {
  329. el = days.eq(index);
  330. }
  331. el.addClass(css.focus);
  332. return e.preventDefault();
  333. }
  334. // pageUp / pageDown
  335. if(key == 34) {
  336. return self.addMonth();
  337. }
  338. if(key == 33) {
  339. return self.addMonth(-1);
  340. }
  341. // home
  342. if(key == 36) {
  343. return self.today();
  344. }
  345. // enter
  346. if(key == 13) {
  347. if(!$(e.target).is("select")) {
  348. $("." + css.focus).dblclick();
  349. }
  350. }
  351. return $([16, 17, 18, 9]).index(key) >= 0;
  352. });
  353. // 点击外部关闭窗口
  354. /*$(document).bind("mousedown.d", function(e) {
  355. var el = e.target;
  356. if(!$(el).parents("#" + css.root).length && el != input[0] && (!trigger || el != trigger[0])) {
  357. self.hide(e);
  358. }
  359. });*/
  360. $(document.body).on("mousedown.d", function(e) {
  361. if(e.target !== input[0] && !$.contains(root[0],e.target)) {
  362. setTimeout(function(){
  363. self.hide();
  364. },100)
  365. }
  366. });
  367. }
  368. //}}}
  369. $.extend(self, {
  370. //{{{ show
  371. show : function(e) {
  372. if(input.prop("readonly") || input.prop("disabled") || opened) {
  373. return;
  374. }
  375. // onBeforeShow
  376. e = e || $.Event();
  377. e.type = "onBeforeShow";
  378. fire.trigger(e);
  379. if(e.isDefaultPrevented()) {
  380. return;
  381. }
  382. $.each(instances, function() {
  383. this.hide();
  384. });
  385. opened = true;
  386. // 月份下拉菜单
  387. monthSelector.unbind("change").change(function() {
  388. self.setValue(yearSelector.val(), $(this).val());
  389. });
  390. // 年下拉菜单
  391. yearSelector.unbind("change").change(function() {
  392. self.setValue($(this).val(), monthSelector.val());
  393. });
  394. // 上一月/下一月按钮
  395. pm = root.find("#" + css.prev).unbind("click").click(function(e) {
  396. if(!pm.hasClass(css.disabled)) {
  397. self.addMonth(-1);
  398. }
  399. return false;
  400. });
  401. nm = root.find("#" + css.next).unbind("click").click(function(e) {
  402. if(!nm.hasClass(css.disabled)) {
  403. self.addMonth();
  404. }
  405. return false;
  406. });
  407. // 设置日期
  408. self.setValue(value);
  409. //是否显示时间选择
  410. if(options.time) {
  411. root.find('div.caltime').show();
  412. }else{
  413. root.find('div.caltime').hide();
  414. }
  415. // show calendar
  416. var pos = input.offset();
  417. // iPad position fix
  418. if(/iPad/i.test(navigator.userAgent)) {
  419. pos.top -= $(window).scrollTop();
  420. }
  421. var top = pos.top + input.outerHeight() + options.offset[0];
  422. if(top + root.height() > $(window).scrollTop() + $(window).height()) {
  423. top = pos.top - root.height();
  424. }
  425. root.css({
  426. top : top,
  427. left : pos.left + options.offset[1]
  428. });
  429. if(options.speed) {
  430. root.show(options.speed, function() {
  431. onShow(e);
  432. });
  433. } else {
  434. root.show();
  435. onShow(e);
  436. }
  437. return self;
  438. },
  439. //}}}
  440. //{{{ setValue
  441. setValue : function(year, month, day, hour, minute) {
  442. var date = integer(month) >= -1 ? new Date(integer(year), integer(month), integer(day || 1)) : year || value;
  443. if(date < min) {
  444. date = min;
  445. } else if(date > max) {
  446. date = max;
  447. }
  448. year = date.getFullYear();
  449. month = date.getMonth();
  450. day = date.getDate();
  451. hour = date.getHours();
  452. minute = date.getMinutes();
  453. // roll year & month
  454. if(month == -1) {
  455. month = 11;
  456. year--;
  457. } else if(month == 12) {
  458. month = 0;
  459. year++;
  460. }
  461. if(!opened) {
  462. select(date, options);
  463. return self;
  464. }
  465. currMonth = month;
  466. currYear = year;
  467. // variables
  468. var tmp = new Date(year, month, 1 - options.firstDay), begin = tmp.getDay(), days = dayAm(year, month), prevDays = dayAm(year, month - 1), week;
  469. // selectors
  470. if(options.selectors) {
  471. // month selector
  472. monthSelector.empty();
  473. $.each(labels.months, function(i, m) {
  474. if(min < new Date(year, i + 1, -1) && max > new Date(year, i, 0)) {
  475. monthSelector.append($("<option/>").html(m).attr("value", i));
  476. }
  477. });
  478. // year selector
  479. yearSelector.empty();
  480. var yearNow = now.getFullYear();
  481. for(var i = yearNow + options.yearRange[0]; i < yearNow + options.yearRange[1]; i++) {
  482. if(min <= new Date(i + 1, -1, 1) && max > new Date(i, 0, 0)) {
  483. yearSelector.append($("<option/>").text(i));
  484. }
  485. }
  486. monthSelector.val(month);
  487. yearSelector.val(year);
  488. // title
  489. } else {
  490. title.html(labels.months[month] + " " + year);
  491. }
  492. // populate weeks
  493. weeks.empty();
  494. pm.add(nm).removeClass(css.disabled);
  495. // !begin === "sunday"
  496. for(var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) {
  497. a = $("<a/>");
  498. if(j % 7 === 0) {
  499. week = $("<div/>").addClass(css.week);
  500. weeks.append(week);
  501. }
  502. if(j < begin) {
  503. a.addClass(css.off);
  504. num = prevDays - begin + j + 1;
  505. date = new Date(year, month - 1, num);
  506. } else if(j >= begin + days) {
  507. a.addClass(css.off);
  508. num = j - days - begin + 1;
  509. date = new Date(year, month + 1, num);
  510. } else {
  511. num = j - begin + 1;
  512. date = new Date(year, month, num);
  513. // current date
  514. if(isSameDay(value, date)) {
  515. a.attr("id", css.current).addClass(css.focus);
  516. // today
  517. } else if(isSameDay(now, date)) {
  518. a.attr("id", css.today);
  519. }
  520. }
  521. // disabled
  522. if(min && date < min) {
  523. a.add(pm).addClass(css.disabled);
  524. }
  525. if(max && date > max) {
  526. a.add(nm).addClass(css.disabled);
  527. }
  528. a.attr("href", "#" + num).text(num).data("date", date);
  529. week.append(a);
  530. if(options.selectors) {
  531. //console.log(year, month, day, hour, minute)
  532. }
  533. }
  534. //时间选择
  535. //!TODO:chaoren1641增加,有待重构
  536. if(options.time) {
  537. //如果有时间选项则点击确定或双击日期输入时间
  538. // date picking
  539. weeks.find("a").on('click',function(e) {
  540. var el = $(this);
  541. if(!el.hasClass(css.disabled)) {
  542. $("#" + css.current).removeAttr("id");
  543. el.attr("id", css.current);
  544. }
  545. return false;
  546. }).off('dblclick').dblclick(function(e) {
  547. var el = $(this);
  548. if(!el.hasClass(css.disabled)) {
  549. select(el.data("date"), options, e);
  550. //在IE下,重新赋值会引起focus,导致日历控件再次激活打开,所以setTimeout下
  551. setTimeout(function() {
  552. self.hide();
  553. },100);
  554. }
  555. return false;
  556. });
  557. var body = root.find("#" + css.body);
  558. body.find('button').off('click.d').on('click.d',function(e) {
  559. var el = root.find('#' + css.current);
  560. select(el.data("date"), options, e);
  561. //在IE下,重新赋值会引起focus,导致日历控件再次激活打开,所以setTimeout下
  562. setTimeout(function() {
  563. self.hide();
  564. },100);
  565. return false;
  566. });
  567. body.find('#calHour').val(hour);
  568. body.find('#calMin').val(minute);
  569. }else{
  570. // date picking
  571. weeks.find("a").click(function(e) {
  572. var el = $(this);
  573. if(!el.hasClass(css.disabled)) {
  574. $("#" + css.current).removeAttr("id");
  575. el.attr("id", css.current);
  576. select(el.data("date"), options, e);
  577. }
  578. return false;
  579. })
  580. }
  581. // sunday
  582. if(css.sunday) {
  583. weeks.find(css.week).each(function() {
  584. var beg = options.firstDay ? 7 - options.firstDay : 0;
  585. $(this).children().slice(beg, beg + 1).addClass(css.sunday);
  586. });
  587. }
  588. return self;
  589. },
  590. //}}}
  591. setMin : function(val, fit) {
  592. min = parseDate(val);
  593. if(fit && value < min) {
  594. self.setValue(min);
  595. }
  596. return self;
  597. },
  598. setMax : function(val, fit) {
  599. max = parseDate(val);
  600. if(fit && value > max) {
  601. self.setValue(max);
  602. }
  603. return self;
  604. },
  605. today : function() {
  606. return self.setValue(now);
  607. },
  608. addDay : function(amount) {
  609. return this.setValue(currYear, currMonth, currDay + (amount || 1));
  610. },
  611. addMonth : function(amount) {
  612. return this.setValue(currYear, currMonth + (amount || 1), currDay);
  613. },
  614. addYear : function(amount) {
  615. return this.setValue(currYear + (amount || 1), currMonth, currDay);
  616. },
  617. hide : function(e) {
  618. if(opened) {
  619. // onHide
  620. e = $.Event();
  621. e.type = "onHide";
  622. fire.trigger(e);
  623. $(document).unbind("click.d").unbind("keydown.d");
  624. // cancelled ?
  625. if(e.isDefaultPrevented()) {
  626. return;
  627. }
  628. // do the hide
  629. root.hide();
  630. opened = false;
  631. }
  632. return self;
  633. },
  634. getConf : function() {
  635. return options;
  636. },
  637. getInput : function() {
  638. return input;
  639. },
  640. getCalendar : function() {
  641. return root;
  642. },
  643. getValue : function(dateFormat) {
  644. return dateFormat ? format(value, dateFormat, options.lang) : value;
  645. },
  646. isOpen : function() {
  647. return opened;
  648. }
  649. });
  650. // callbacks
  651. $.each(['onBeforeShow', 'onShow', 'select', 'onHide'], function(i, name) {
  652. // configuration
  653. if($.isFunction(options[name])) {
  654. $(self).bind(name, options[name]);
  655. }
  656. // API methods
  657. self[name] = function(fn) {
  658. if(fn) {
  659. $(self).bind(name, fn);
  660. }
  661. return self;
  662. };
  663. });
  664. // show dateinput & assign keyboard shortcuts
  665. input.bind("focus click", self.show).keydown(function(e) {
  666. var key = e.keyCode;
  667. // open dateinput with navigation keyw
  668. if(!opened && $(KEYS).index(key) >= 0) {
  669. self.show(e);
  670. return e.preventDefault();
  671. }
  672. // allow tab
  673. return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault();
  674. });
  675. // initial value
  676. if(parseDate(input.val())) {
  677. //!TODO关闭初始化的值,这里会出现BUG
  678. //select(value, options);
  679. }
  680. };
  681. $.expr[':'].date = function(el) {
  682. var type = el.getAttribute("type");
  683. return type && type == 'date' || !!$(el).data("dateinput");
  684. };
  685. $.fn[pluginName] = function(options) {
  686. Wind.css('datePicker');
  687. return this.each(function() {
  688. if(!$.data(this, 'plugin_' + pluginName)) {
  689. var instance = new Plugin($(this), options);
  690. instances.push(instance);
  691. $.data(this, 'plugin_' + pluginName, instance);
  692. }
  693. });
  694. };
  695. /*$.fn.dateinput = function(conf) {
  696. // already instantiated
  697. if(this.data("dateinput")) {
  698. return this;
  699. }
  700. // configuration
  701. conf = $.extend(true, {}, tool.conf, conf);
  702. // CSS prefix
  703. $.each(conf.css, function(key, val) {
  704. if(!val && key != 'prefix') {
  705. conf.css[key] = (conf.css.prefix || '') + (val || key);
  706. }
  707. });
  708. var els;
  709. this.each(function() {
  710. var el = new Dateinput($(this), conf);
  711. instances.push(el);
  712. var input = el.getInput().data("dateinput", el);
  713. els = els ? els.add(input) : input;
  714. });
  715. return els ? els : this;
  716. };*/
  717. })(jQuery, window ,document);