mui.dtpicker.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /**
  2. * 日期时间插件
  3. * varstion 1.0.5
  4. * by Houfeng
  5. * Houfeng@DCloud.io
  6. */
  7. (function($, document) {
  8. //创建 DOM
  9. $.dom = function(str) {
  10. if (typeof(str) !== 'string') {
  11. if ((str instanceof Array) || (str[0] && str.length)) {
  12. return [].slice.call(str);
  13. } else {
  14. return [str];
  15. }
  16. }
  17. if (!$.__create_dom_div__) {
  18. $.__create_dom_div__ = document.createElement('div');
  19. }
  20. $.__create_dom_div__.innerHTML = str;
  21. return [].slice.call($.__create_dom_div__.childNodes);
  22. };
  23. var domBuffer = '<div class="mui-dtpicker" data-type="datetime">\
  24. <div class="mui-dtpicker-header">\
  25. <button data-id="btn-cancel" class="mui-btn">取消</button>\
  26. <button data-id="btn-ok" class="mui-btn mui-btn-blue">确定</button>\
  27. </div>\
  28. <div class="mui-dtpicker-title"><h5 data-id="title-y">年</h5><h5 data-id="title-m">月</h5><h5 data-id="title-d">日</h5><h5 data-id="title-h">时</h5><h5 data-id="title-i">分</h5></div>\
  29. <div class="mui-dtpicker-body">\
  30. <div data-id="picker-y" class="mui-picker">\
  31. <div class="mui-picker-inner">\
  32. <div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
  33. <ul class="mui-pciker-list">\
  34. </ul>\
  35. <div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
  36. </div>\
  37. </div>\
  38. <div data-id="picker-m" class="mui-picker">\
  39. <div class="mui-picker-inner">\
  40. <div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
  41. <ul class="mui-pciker-list">\
  42. </ul>\
  43. <div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
  44. </div>\
  45. </div>\
  46. <div data-id="picker-d" class="mui-picker">\
  47. <div class="mui-picker-inner">\
  48. <div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
  49. <ul class="mui-pciker-list">\
  50. </ul>\
  51. <div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
  52. </div>\
  53. </div>\
  54. <div data-id="picker-h" class="mui-picker">\
  55. <div class="mui-picker-inner">\
  56. <div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
  57. <ul class="mui-pciker-list">\
  58. </ul>\
  59. <div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
  60. </div>\
  61. </div>\
  62. <div data-id="picker-i" class="mui-picker">\
  63. <div class="mui-picker-inner">\
  64. <div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
  65. <ul class="mui-pciker-list">\
  66. </ul>\
  67. <div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
  68. </div>\
  69. </div>\
  70. </div>\
  71. </div>';
  72. //plugin
  73. var DtPicker = $.DtPicker = $.Class.extend({
  74. init: function(options) {
  75. var self = this;
  76. var _picker = $.dom(domBuffer)[0];
  77. document.body.appendChild(_picker);
  78. $('[data-id*="picker"]', _picker).picker();
  79. var ui = self.ui = {
  80. picker: _picker,
  81. mask: $.createMask(),
  82. ok: $('[data-id="btn-ok"]', _picker)[0],
  83. cancel: $('[data-id="btn-cancel"]', _picker)[0],
  84. y: $('[data-id="picker-y"]', _picker)[0],
  85. m: $('[data-id="picker-m"]', _picker)[0],
  86. d: $('[data-id="picker-d"]', _picker)[0],
  87. h: $('[data-id="picker-h"]', _picker)[0],
  88. i: $('[data-id="picker-i"]', _picker)[0],
  89. labels: $('[data-id*="title-"]', _picker),
  90. };
  91. ui.cancel.addEventListener('tap', function() {
  92. self.hide();
  93. }, false);
  94. ui.ok.addEventListener('tap', function() {
  95. var rs = self.callback(self.getSelected());
  96. if (rs !== false) {
  97. self.hide();
  98. }
  99. }, false);
  100. ui.y.addEventListener('change', function() {
  101. self._createDay();
  102. }, false);
  103. ui.m.addEventListener('change', function() {
  104. self._createDay();
  105. }, false);
  106. ui.mask[0].addEventListener('tap', function() {
  107. self.hide();
  108. }, false);
  109. self._create(options);
  110. //防止滚动穿透
  111. self.ui.picker.addEventListener('touchstart',function(event){
  112. event.preventDefault();
  113. },false);
  114. self.ui.picker.addEventListener('touchmove',function(event){
  115. event.preventDefault();
  116. },false);
  117. },
  118. getSelected: function() {
  119. var self = this;
  120. var ui = self.ui;
  121. var type = self.options.type;
  122. var selected = {
  123. type: type,
  124. y: ui.y.picker.getSelectedItem(),
  125. m: ui.m.picker.getSelectedItem(),
  126. d: ui.d.picker.getSelectedItem(),
  127. h: ui.h.picker.getSelectedItem(),
  128. i: ui.i.picker.getSelectedItem(),
  129. toString: function() {
  130. return this.value;
  131. }
  132. };
  133. switch (type) {
  134. case 'datetime':
  135. selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value + ' ' + selected.h.value + ':' + selected.i.value;
  136. selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text + ' ' + selected.h.text + ':' + selected.i.text;
  137. break;
  138. case 'date':
  139. selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value;
  140. selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text;
  141. break;
  142. case 'time':
  143. selected.value = selected.h.value + ':' + selected.i.value;
  144. selected.text = selected.h.text + ':' + selected.i.text;
  145. break;
  146. case 'month':
  147. selected.value = selected.y.value + '-' + selected.m.value;
  148. selected.text = selected.y.text + '-' + selected.m.text;
  149. break;
  150. case 'hour':
  151. selected.value = selected.y.value + '-' + selected.m.value + '-' + selected.d.value + ' ' + selected.h.value;
  152. selected.text = selected.y.text + '-' + selected.m.text + '-' + selected.d.text + ' ' + selected.h.text;
  153. break;
  154. }
  155. return selected;
  156. },
  157. setSelectedValue: function(value) {
  158. var self = this;
  159. var ui = self.ui;
  160. var parsedValue = self._parseValue(value);
  161. ui.y.picker.setSelectedValue(parsedValue.y, 0);
  162. ui.m.picker.setSelectedValue(parsedValue.m, 0);
  163. ui.d.picker.setSelectedValue(parsedValue.d, 0);
  164. ui.h.picker.setSelectedValue(parsedValue.h, 0);
  165. ui.i.picker.setSelectedValue(parsedValue.i, 0);
  166. },
  167. isLeapYear: function(year) {
  168. return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
  169. },
  170. _inArray: function(array, item) {
  171. for (var index in array) {
  172. var _item = array[index];
  173. if (_item === item) return true;
  174. }
  175. return false;
  176. },
  177. getDayNum: function(year, month) {
  178. var self = this;
  179. if (self._inArray([1, 3, 5, 7, 8, 10, 12], month)) {
  180. return 31;
  181. } else if (self._inArray([4, 6, 9, 11], month)) {
  182. return 30;
  183. } else if (self.isLeapYear(year)) {
  184. return 29;
  185. } else {
  186. return 28;
  187. }
  188. },
  189. _fill: function(num) {
  190. num = num.toString();
  191. if (num.length < 2) {
  192. num = 0 + num;
  193. }
  194. return num;
  195. },
  196. _createYear: function(current) {
  197. var self = this;
  198. var options = self.options;
  199. var ui = self.ui;
  200. //生成年列表
  201. var yArray = [];
  202. if (options.customData.y) {
  203. yArray = options.customData.y;
  204. } else {
  205. var yBegin = options.beginYear;
  206. var yEnd = options.endYear;
  207. for (var y = yBegin; y <= yEnd; y++) {
  208. yArray.push({
  209. text: y + '',
  210. value: y
  211. });
  212. }
  213. }
  214. ui.y.picker.setItems(yArray);
  215. //ui.y.picker.setSelectedValue(current);
  216. },
  217. _createMonth: function(current) {
  218. var self = this;
  219. var options = self.options;
  220. var ui = self.ui;
  221. //生成月列表
  222. var mArray = [];
  223. if (options.customData.m) {
  224. mArray = options.customData.m;
  225. } else {
  226. for (var m = 1; m <= 12; m++) {
  227. var val = self._fill(m);
  228. mArray.push({
  229. text: val,
  230. value: val
  231. });
  232. }
  233. }
  234. ui.m.picker.setItems(mArray);
  235. //ui.m.picker.setSelectedValue(current);
  236. },
  237. _createDay: function(current) {
  238. var self = this;
  239. var options = self.options;
  240. var ui = self.ui;
  241. //生成日列表
  242. var dArray = [];
  243. if (options.customData.d) {
  244. dArray = options.customData.d;
  245. } else {
  246. var maxDay = self.getDayNum(parseInt(ui.y.picker.getSelectedValue()), parseInt(ui.m.picker.getSelectedValue()));
  247. for (var d = 1; d <= maxDay; d++) {
  248. var val = self._fill(d);
  249. dArray.push({
  250. text: val,
  251. value: val
  252. });
  253. }
  254. }
  255. ui.d.picker.setItems(dArray);
  256. current = current || ui.d.picker.getSelectedValue();
  257. //ui.d.picker.setSelectedValue(current);
  258. },
  259. _createHours: function(current) {
  260. var self = this;
  261. var options = self.options;
  262. var ui = self.ui;
  263. //生成时列表
  264. var hArray = [];
  265. if (options.customData.h) {
  266. hArray = options.customData.h;
  267. } else {
  268. for (var h = 0; h <= 23; h++) {
  269. var val = self._fill(h);
  270. hArray.push({
  271. text: val,
  272. value: val
  273. });
  274. }
  275. }
  276. ui.h.picker.setItems(hArray);
  277. //ui.h.picker.setSelectedValue(current);
  278. },
  279. _createMinutes: function(current) {
  280. var self = this;
  281. var options = self.options;
  282. var ui = self.ui;
  283. //生成分列表
  284. var iArray = [];
  285. if (options.customData.i) {
  286. iArray = options.customData.i;
  287. } else {
  288. for (var i = 0; i <= 59; i++) {
  289. var val = self._fill(i);
  290. iArray.push({
  291. text: val,
  292. value: val
  293. });
  294. }
  295. }
  296. ui.i.picker.setItems(iArray);
  297. //ui.i.picker.setSelectedValue(current);
  298. },
  299. _setLabels: function() {
  300. var self = this;
  301. var options = self.options;
  302. var ui = self.ui;
  303. ui.labels.each(function(i, label) {
  304. label.innerText = options.labels[i];
  305. });
  306. },
  307. _setButtons: function() {
  308. var self = this;
  309. var options = self.options;
  310. var ui = self.ui;
  311. ui.cancel.innerText = options.buttons[0];
  312. ui.ok.innerText = options.buttons[1];
  313. },
  314. _parseValue: function(value) {
  315. var self = this;
  316. var rs = {};
  317. if (value) {
  318. var parts = value.replace(":", "-").replace(" ", "-").split("-");
  319. rs.y = parts[0];
  320. rs.m = parts[1];
  321. rs.d = parts[2];
  322. rs.h = parts[3];
  323. rs.i = parts[4];
  324. } else {
  325. var now = new Date();
  326. rs.y = now.getFullYear();
  327. rs.m = now.getMonth() + 1;
  328. rs.d = now.getDate();
  329. rs.h = now.getHours();
  330. rs.i = now.getMinutes();
  331. }
  332. return rs;
  333. },
  334. _create: function(options) {
  335. var self = this;
  336. options = options || {};
  337. options.labels = options.labels || ['年', '月', '日', '时', '分'];
  338. options.buttons = options.buttons || ['取消', '确定'];
  339. options.type = options.type || 'datetime';
  340. options.customData = options.customData || {};
  341. self.options = options;
  342. var now = new Date();
  343. options.beginYear = options.beginYear || (now.getFullYear() - 5);
  344. options.endYear = options.endYear || (now.getFullYear() + 5);
  345. var ui = self.ui;
  346. //设定label
  347. self._setLabels();
  348. self._setButtons();
  349. //设定类型
  350. ui.picker.setAttribute('data-type', options.type);
  351. //生成
  352. self._createYear();
  353. self._createMonth();
  354. self._createDay();
  355. self._createHours();
  356. self._createMinutes();
  357. //设定默认值
  358. self.setSelectedValue(options.value);
  359. },
  360. //显示
  361. show: function(callback) {
  362. var self = this;
  363. var ui = self.ui;
  364. self.callback = callback || $.noop;
  365. ui.mask.show();
  366. document.body.classList.add($.className('dtpicker-active-for-page'));
  367. ui.picker.classList.add($.className('active'));
  368. //处理物理返回键
  369. self.__back = $.back;
  370. $.back = function() {
  371. self.hide();
  372. };
  373. },
  374. hide: function() {
  375. var self = this;
  376. if (self.disposed) return;
  377. var ui = self.ui;
  378. ui.picker.classList.remove($.className('active'));
  379. ui.mask.close();
  380. document.body.classList.remove($.className('dtpicker-active-for-page'));
  381. //处理物理返回键
  382. $.back=self.__back;
  383. },
  384. dispose: function() {
  385. var self = this;
  386. self.hide();
  387. setTimeout(function() {
  388. self.ui.picker.parentNode.removeChild(self.ui.picker);
  389. for (var name in self) {
  390. self[name] = null;
  391. delete self[name];
  392. };
  393. self.disposed = true;
  394. }, 300);
  395. }
  396. });
  397. })(mui, document);