datePicker.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  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 : [-200, 200],
  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. if($.browser.msie && $.browser.version < 7 ) {
  217. Wind.use('bgiframe',function() {
  218. root.bgiframe();
  219. });
  220. }
  221. }
  222. // trigger icon
  223. if(options.trigger) {
  224. trigger = $("<a/>").attr("href", "#").addClass(css.trigger).click(function(e) {
  225. self.show();
  226. return e.preventDefault();
  227. }).insertAfter(input);
  228. }
  229. // layout elements
  230. var weeks = root.find("#" + css.weeks);
  231. yearSelector = root.find("#" + css.year);
  232. monthSelector = root.find("#" + css.month);
  233. //{{{ pick
  234. function select(date, options, e) {
  235. // current value
  236. value = date;
  237. currYear = date.getFullYear();
  238. currMonth = date.getMonth();
  239. currDay = date.getDate();
  240. if (e.type == "click" && !$.browser.msie) {
  241. input.focus();
  242. }
  243. // select
  244. e = e || $.Event("api");
  245. e.type = "select";
  246. fire.trigger(e, [date]);
  247. if(e.isDefaultPrevented()) {
  248. return;
  249. }
  250. //如果选项有时间,则加上时间
  251. if(options.time) {
  252. var timeInput = root.find('input');
  253. var hour = parseInt(timeInput.eq(0).val(),10);
  254. var min = parseInt(timeInput.eq(1).val(),10);
  255. if(isNaN(hour)) {
  256. hour = 0;
  257. }
  258. if(isNaN(min)) {
  259. min = 0;
  260. }
  261. if(hour < 10) {
  262. hour = '0' + hour;
  263. }else if(hour < 0 || hour > 23) {
  264. hour = '00';
  265. }
  266. if(min < 10) {
  267. min = '0' + min;
  268. }else if(min < 0 || min > 59) {
  269. min = '00';
  270. }
  271. date.setHours(hour);
  272. date.setMinutes(min);
  273. }
  274. // formatting
  275. var date = format(date, options.format, options.lang);
  276. input.val(date);
  277. // store value into input
  278. input.data("date", date);
  279. //设置val后,IE导致触发focus事件,导致窗口关闭后再次被打开
  280. setTimeout(function() {
  281. self.hide(e);
  282. },100);
  283. }
  284. //}}}
  285. //{{{ onShow
  286. function onShow(ev) {
  287. ev.type = "onShow";
  288. fire.trigger(ev);
  289. //快捷键处理
  290. $(document).bind("keydown.d", function(e) {
  291. if(e.ctrlKey) {
  292. return true;
  293. }
  294. var key = e.keyCode;
  295. // backspace clears the value
  296. if(e.target == input[0]) {//如果是在当前input按back键,清除值并隐藏日历
  297. if(key == 8 || key == 46) {
  298. input.val("");
  299. return self.hide(e);
  300. }
  301. }
  302. // esc key
  303. if(key == 27) {
  304. return self.hide(e);
  305. }
  306. //如果有time,则不要快捷键
  307. if(options.time) {
  308. return;
  309. }
  310. if($(KEYS).index(key) >= 0) {
  311. if(!opened) {
  312. self.show(e);
  313. return e.preventDefault();
  314. }
  315. var days = $("#" + css.weeks + " a"), el = $("." + css.focus), index = days.index(el);
  316. el.removeClass(css.focus);
  317. if(key == 74 || key == 40) {
  318. index += 7;
  319. } else if(key == 75 || key == 38) {
  320. index -= 7;
  321. } else if(key == 76 || key == 39) {
  322. index += 1;
  323. } else if(key == 72 || key == 37) {
  324. index -= 1;
  325. }
  326. if(index > 41) {
  327. self.addMonth();
  328. el = $("#" + css.weeks + " a:eq(" + (index - 42) + ")");
  329. } else if(index < 0) {
  330. self.addMonth(-1);
  331. el = $("#" + css.weeks + " a:eq(" + (index + 42) + ")");
  332. } else {
  333. el = days.eq(index);
  334. }
  335. el.addClass(css.focus);
  336. return e.preventDefault();
  337. }
  338. // pageUp / pageDown
  339. if(key == 34) {
  340. return self.addMonth();
  341. }
  342. if(key == 33) {
  343. return self.addMonth(-1);
  344. }
  345. // home
  346. if(key == 36) {
  347. return self.today();
  348. }
  349. // enter
  350. if(key == 13) {
  351. if(!$(e.target).is("select")) {
  352. $("." + css.focus).dblclick();
  353. }
  354. }
  355. return $([16, 17, 18, 9]).index(key) >= 0;
  356. });
  357. // 点击外部关闭窗口
  358. /*$(document).bind("mousedown.d", function(e) {
  359. var el = e.target;
  360. if(!$(el).parents("#" + css.root).length && el != input[0] && (!trigger || el != trigger[0])) {
  361. self.hide(e);
  362. }
  363. });*/
  364. $(document.body).on("mousedown.d", function(e) {
  365. if(e.target !== input[0] && !$.contains(root[0],e.target)) {
  366. setTimeout(function(){
  367. self.hide();
  368. },100)
  369. }
  370. });
  371. }
  372. //}}}
  373. $.extend(self, {
  374. //{{{ show
  375. show : function(e) {
  376. if(input.attr("readonly") || input.attr("disabled") || opened) {
  377. return;
  378. }
  379. // onBeforeShow
  380. e = e || $.Event();
  381. e.type = "onBeforeShow";
  382. fire.trigger(e);
  383. if(e.isDefaultPrevented()) {
  384. return;
  385. }
  386. $.each(instances, function() {
  387. this.hide();
  388. });
  389. opened = true;
  390. // 月份下拉菜单
  391. monthSelector.unbind("change").change(function() {
  392. self.setValue(yearSelector.val(), $(this).val());
  393. });
  394. // 年下拉菜单
  395. yearSelector.unbind("change").change(function() {
  396. self.setValue($(this).val(), monthSelector.val());
  397. });
  398. // 上一月/下一月按钮
  399. pm = root.find("#" + css.prev).unbind("click").click(function(e) {
  400. if(!pm.hasClass(css.disabled)) {
  401. self.addMonth(-1);
  402. }
  403. return false;
  404. });
  405. nm = root.find("#" + css.next).unbind("click").click(function(e) {
  406. if(!nm.hasClass(css.disabled)) {
  407. self.addMonth();
  408. }
  409. return false;
  410. });
  411. // 设置日期
  412. self.setValue(value);
  413. //是否显示时间选择
  414. if(options.time) {
  415. root.find('div.caltime').show();
  416. }else{
  417. root.find('div.caltime').hide();
  418. }
  419. // show calendar
  420. var pos = input.offset();
  421. // iPad position fix
  422. if(/iPad/i.test(navigator.userAgent)) {
  423. pos.top -= $(window).scrollTop();
  424. }
  425. var top = pos.top + input.outerHeight() + options.offset[0];
  426. if(top + root.height() > $(window).scrollTop() + $(window).height()) {
  427. top = pos.top - root.height();
  428. }
  429. root.css({
  430. top : top,
  431. left : pos.left + options.offset[1]
  432. });
  433. if(options.speed) {
  434. root.show(options.speed, function() {
  435. onShow(e);
  436. });
  437. } else {
  438. root.show();
  439. onShow(e);
  440. }
  441. return self;
  442. },
  443. //}}}
  444. //{{{ setValue
  445. setValue : function(year, month, day, hour, minute) {
  446. var date = integer(month) >= -1 ? new Date(integer(year), integer(month), integer(day || 1)) : year || value;
  447. if(date < min) {
  448. date = min;
  449. } else if(date > max) {
  450. date = max;
  451. }
  452. year = date.getFullYear();
  453. month = date.getMonth();
  454. day = date.getDate();
  455. hour = date.getHours();
  456. minute = date.getMinutes();
  457. // roll year & month
  458. if(month == -1) {
  459. month = 11;
  460. year--;
  461. } else if(month == 12) {
  462. month = 0;
  463. year++;
  464. }
  465. if(!opened) {
  466. select(date, options);
  467. return self;
  468. }
  469. currMonth = month;
  470. currYear = year;
  471. // variables
  472. var tmp = new Date(year, month, 1 - options.firstDay), begin = tmp.getDay(), days = dayAm(year, month), prevDays = dayAm(year, month - 1), week;
  473. // selectors
  474. if(options.selectors) {
  475. // month selector
  476. monthSelector.empty();
  477. $.each(labels.months, function(i, m) {
  478. if(min < new Date(year, i + 1, -1) && max > new Date(year, i, 0)) {
  479. monthSelector.append($("<option/>").html(m).attr("value", i));
  480. }
  481. });
  482. // year selector
  483. yearSelector.empty();
  484. var yearNow = now.getFullYear();
  485. for(var i = yearNow + options.yearRange[0]; i < yearNow + options.yearRange[1]; i++) {
  486. if(min <= new Date(i + 1, -1, 1) && max > new Date(i, 0, 0)) {
  487. yearSelector.append($("<option/>").text(i));
  488. }
  489. }
  490. monthSelector.val(month);
  491. yearSelector.val(year);
  492. // title
  493. } else {
  494. title.html(labels.months[month] + " " + year);
  495. }
  496. // populate weeks
  497. weeks.empty();
  498. pm.add(nm).removeClass(css.disabled);
  499. // !begin === "sunday"
  500. for(var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) {
  501. a = $("<a/>");
  502. if(j % 7 === 0) {
  503. week = $("<div/>").addClass(css.week);
  504. weeks.append(week);
  505. }
  506. if(j < begin) {
  507. a.addClass(css.off);
  508. num = prevDays - begin + j + 1;
  509. date = new Date(year, month - 1, num);
  510. } else if(j >= begin + days) {
  511. a.addClass(css.off);
  512. num = j - days - begin + 1;
  513. date = new Date(year, month + 1, num);
  514. } else {
  515. num = j - begin + 1;
  516. date = new Date(year, month, num);
  517. // current date
  518. if(isSameDay(value, date)) {
  519. a.attr("id", css.current).addClass(css.focus);
  520. // today
  521. } else if(isSameDay(now, date)) {
  522. a.attr("id", css.today);
  523. }
  524. }
  525. // disabled
  526. if(min && date < min) {
  527. a.add(pm).addClass(css.disabled);
  528. }
  529. if(max && date > max) {
  530. a.add(nm).addClass(css.disabled);
  531. }
  532. a.attr("href", "#" + num).text(num).data("date", date);
  533. week.append(a);
  534. if(options.selectors) {
  535. //console.log(year, month, day, hour, minute)
  536. }
  537. }
  538. //时间选择
  539. //!TODO:chaoren1641增加,有待重构
  540. if(options.time) {
  541. //如果有时间选项则点击确定或双击日期输入时间
  542. // date picking
  543. weeks.find("a").on('click',function(e) {
  544. var el = $(this);
  545. if(!el.hasClass(css.disabled)) {
  546. $("#" + css.current).removeAttr("id");
  547. el.attr("id", css.current);
  548. }
  549. return false;
  550. }).off('dblclick').dblclick(function(e) {
  551. var el = $(this);
  552. if(!el.hasClass(css.disabled)) {
  553. select(el.data("date"), options, e);
  554. //在IE下,重新赋值会引起focus,导致日历控件再次激活打开,所以setTimeout下
  555. setTimeout(function() {
  556. self.hide();
  557. },100);
  558. }
  559. return false;
  560. });
  561. var body = root.find("#" + css.body);
  562. body.find('button').off('click.d').on('click.d',function(e) {
  563. var el = root.find('#' + css.current);
  564. select(el.data("date"), options, e);
  565. //在IE下,重新赋值会引起focus,导致日历控件再次激活打开,所以setTimeout下
  566. setTimeout(function() {
  567. self.hide();
  568. },100);
  569. return false;
  570. });
  571. body.find('#calHour').val(hour);
  572. body.find('#calMin').val(minute);
  573. }else{
  574. // date picking
  575. weeks.find("a").click(function(e) {
  576. var el = $(this);
  577. if(!el.hasClass(css.disabled)) {
  578. $("#" + css.current).removeAttr("id");
  579. el.attr("id", css.current);
  580. select(el.data("date"), options, e);
  581. }
  582. return false;
  583. })
  584. }
  585. // sunday
  586. if(css.sunday) {
  587. weeks.find(css.week).each(function() {
  588. var beg = options.firstDay ? 7 - options.firstDay : 0;
  589. $(this).children().slice(beg, beg + 1).addClass(css.sunday);
  590. });
  591. }
  592. return self;
  593. },
  594. //}}}
  595. setMin : function(val, fit) {
  596. min = parseDate(val);
  597. if(fit && value < min) {
  598. self.setValue(min);
  599. }
  600. return self;
  601. },
  602. setMax : function(val, fit) {
  603. max = parseDate(val);
  604. if(fit && value > max) {
  605. self.setValue(max);
  606. }
  607. return self;
  608. },
  609. today : function() {
  610. return self.setValue(now);
  611. },
  612. addDay : function(amount) {
  613. return this.setValue(currYear, currMonth, currDay + (amount || 1));
  614. },
  615. addMonth : function(amount) {
  616. return this.setValue(currYear, currMonth + (amount || 1), currDay);
  617. },
  618. addYear : function(amount) {
  619. return this.setValue(currYear + (amount || 1), currMonth, currDay);
  620. },
  621. hide : function(e) {
  622. if(opened) {
  623. // onHide
  624. e = $.Event();
  625. e.type = "onHide";
  626. fire.trigger(e);
  627. $(document).unbind("click.d").unbind("keydown.d");
  628. // cancelled ?
  629. if(e.isDefaultPrevented()) {
  630. return;
  631. }
  632. // do the hide
  633. root.hide();
  634. opened = false;
  635. }
  636. return self;
  637. },
  638. getConf : function() {
  639. return options;
  640. },
  641. getInput : function() {
  642. return input;
  643. },
  644. getCalendar : function() {
  645. return root;
  646. },
  647. getValue : function(dateFormat) {
  648. return dateFormat ? format(value, dateFormat, options.lang) : value;
  649. },
  650. isOpen : function() {
  651. return opened;
  652. }
  653. });
  654. // callbacks
  655. $.each(['onBeforeShow', 'onShow', 'select', 'onHide'], function(i, name) {
  656. // configuration
  657. if($.isFunction(options[name])) {
  658. $(self).bind(name, options[name]);
  659. }
  660. // API methods
  661. self[name] = function(fn) {
  662. if(fn) {
  663. $(self).bind(name, fn);
  664. }
  665. return self;
  666. };
  667. });
  668. // show dateinput & assign keyboard shortcuts
  669. input.bind("focus click", self.show).keydown(function(e) {
  670. var key = e.keyCode;
  671. // open dateinput with navigation keyw
  672. if(!opened && $(KEYS).index(key) >= 0) {
  673. self.show(e);
  674. return e.preventDefault();
  675. }
  676. // allow tab
  677. return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault();
  678. });
  679. // initial value
  680. if(parseDate(input.val())) {
  681. //!TODO关闭初始化的值,这里会出现BUG
  682. //select(value, options);
  683. }
  684. };
  685. $.expr[':'].date = function(el) {
  686. var type = el.getAttribute("type");
  687. return type && type == 'date' || !!$(el).data("dateinput");
  688. };
  689. $.fn[pluginName] = function(options) {
  690. Wind.css('datePicker');
  691. return this.each(function() {
  692. if(!$.data(this, 'plugin_' + pluginName)) {
  693. var instance = new Plugin($(this), options);
  694. instances.push(instance);
  695. $.data(this, 'plugin_' + pluginName, instance);
  696. }
  697. });
  698. };
  699. /*$.fn.dateinput = function(conf) {
  700. // already instantiated
  701. if(this.data("dateinput")) {
  702. return this;
  703. }
  704. // configuration
  705. conf = $.extend(true, {}, tool.conf, conf);
  706. // CSS prefix
  707. $.each(conf.css, function(key, val) {
  708. if(!val && key != 'prefix') {
  709. conf.css[key] = (conf.css.prefix || '') + (val || key);
  710. }
  711. });
  712. var els;
  713. this.each(function() {
  714. var el = new Dateinput($(this), conf);
  715. instances.push(el);
  716. var input = el.getInput().data("dateinput", el);
  717. els = els ? els.add(input) : input;
  718. });
  719. return els ? els : this;
  720. };*/
  721. })(jQuery, window ,document);