wdDateTimeRange.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. if (typeof wd == 'undefined') {
  2. wd = {};
  3. }
  4. if (typeof wd.edit == 'undefined') {
  5. wd.edit = {};
  6. }
  7. if (typeof timeRanges == 'undefined') {
  8. timeRanges = {};
  9. }
  10. if (typeof Date.prototype.timeRangeFormat == 'undefined') {
  11. Date.prototype.timeRangeFormat = function (fmt) { //author: meizz
  12. var o = {
  13. "M+": this.getMonth() + 1, //月份
  14. "d+": this.getDate(), //日
  15. "h+": this.getHours(), //小时
  16. "H+": this.getHours(), //小时
  17. "m+": this.getMinutes(), //分
  18. "s+": this.getSeconds(), //秒
  19. "q+": Math.floor((this.getMonth() + 3) / 3), //季度
  20. "S": this.getMilliseconds() //毫秒
  21. };
  22. if (/(y+)/.test(fmt))
  23. fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  24. for (var k in o)
  25. if (new RegExp("(" + k + ")").test(fmt))
  26. fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  27. return fmt;
  28. }
  29. }
  30. var today = new Date().timeRangeFormat('yyyy-MM-dd');
  31. function isBefore(time0, time1) {
  32. try {
  33. return new Date(today + " " + time0).getTime() < new Date(today + " " + time1).getTime();
  34. } catch (error) {
  35. return false;
  36. }
  37. }
  38. function isAfter(time0, time1) {
  39. try {
  40. return new Date(today + " " + time0).getTime() > new Date(today + " " + time1).getTime();
  41. } catch (error) {
  42. return false;
  43. }
  44. }
  45. wd.edit.wdDateTimeRange = function (options) {
  46. var range = new TimeRange(options);
  47. console.log(range);
  48. console.log(range.id);
  49. //console.log(range.kssj.value("fff"));
  50. //console.log(JSON.stringify(range));
  51. }
  52. function notNull(obj, msg) {
  53. if (obj == null || obj == undefined || obj == "") {
  54. throw new Error(msg || "不能为空");
  55. }
  56. return obj;
  57. }
  58. function checkTime(timeStr) {
  59. return checkDate(today + " " + timeStr);
  60. }
  61. function checkDate(dateStr) {
  62. return dateStr == "" || !isNaN(new Date(dateStr).getTime())
  63. }
  64. class TimeRange {
  65. constructor(option) {
  66. this.id = "TimeRange." + new Date().getTime();
  67. timeRanges[this.id] = this;
  68. this.startName = notNull(option.startName, "找不到startName");
  69. this.endName = notNull(option.endName, "找不到endName");
  70. this._option = option;
  71. this.buttons = [];
  72. this.init();
  73. }
  74. init() {
  75. this.kssj = new KssjInput(this.startName, this);
  76. this.jssj = new JssjInput(this.endName, this);
  77. var btns = this._option.button;
  78. var me = this;
  79. for (var key in btns) {
  80. var btn = btns[key];
  81. var _name = btn.name || key;
  82. if (!checkTime(btn.start)) {
  83. console.error("开始时间有误" + btn.start);
  84. } else if (!checkTime(btn.end)) {
  85. console.error("结束时间有误" + btn.end);
  86. }
  87. me.buttons.push(new TimeRangeButton(_name, btn, me));
  88. }
  89. console.log(this.buttons);
  90. this.buttons.sort(function (btn0, btn1) {
  91. function parseTime(time) {
  92. if (!checkTime(time)) {
  93. throw new Error("时间格式有误:“" + time + "”");
  94. }
  95. return new Date(today + " " + time).getTime();
  96. }
  97. var start0 = parseTime(btn0.start);
  98. var start1 = parseTime(btn1.start);
  99. var end0 = parseTime(btn0.end);
  100. var end1 = parseTime(btn1.end);
  101. var compare = start0 - start1;
  102. return compare == 0 ? (end0 - end1) : compare;
  103. })
  104. // TODO 按钮排序
  105. // for (var i = 0; i < this.buttons.length; i++) {
  106. // var button = this.buttons[i];
  107. // var btn = button.buttonElement;
  108. // var ancor = document.createElement("span");
  109. // ancor.setAttribute("ancor", button.timeRange.id + "." + i);
  110. // btn.parentNode.insertBefore(ancor, btn);
  111. // }
  112. // for (var i = 0; i + 1 < this.buttons.length; i++) {
  113. // var button = this.buttons[i];
  114. // var btn = button.buttonElement;
  115. // var q = '[ancor="' + button.timeRange.id + "." + (i + 1) + '"]';
  116. // console.log(q)
  117. // var ancor = document.querySelector(q);
  118. // ancor.parentNode.insertBefore(btn, ancor);
  119. // }
  120. console.log(this.buttons);
  121. this.sortButton();
  122. this.echo()
  123. }
  124. sortButton() {
  125. }
  126. /**
  127. * 回显值
  128. */
  129. echo() {
  130. var k = this.kssj, j = this.jssj;
  131. // if (k.date == '' || k.time == "" || j.date == '' || j.time == "") {
  132. // return;
  133. // }
  134. this.foreachButton(function (button) {
  135. var be = !isAfter(k.time, button.start);
  136. var af = !isBefore(j.time, button.end);
  137. if (be && af) {
  138. button.check();
  139. } else {
  140. button.unCheck();
  141. }
  142. })
  143. }
  144. getKssj() {
  145. return this.kssj.value();
  146. }
  147. getJssj() {
  148. return this.jssj.value();
  149. }
  150. getStartButton() {
  151. var result = null;
  152. this.foreachButton(function (button) {
  153. if (button.isChecked()) {
  154. result = button;
  155. return false;
  156. }
  157. });
  158. return result;
  159. }
  160. getEndButton() {
  161. var result = null;
  162. this.foreachButtonRevise(function (button) {
  163. if (button.isChecked()) {
  164. result = button;
  165. return false;
  166. }
  167. })
  168. return result;
  169. }
  170. foreachButton(fn) {
  171. for (var i = 0; i < this.buttons.length; i++) {
  172. if (fn.apply(this, [this.buttons[i], i]) == false) {
  173. break;
  174. }
  175. }
  176. }
  177. foreachButtonRevise(fn) {
  178. for (var i = this.buttons.length - 1; i >= 0; i--) {
  179. if (fn.apply(this, [this.buttons[i], i]) == false) {
  180. break;
  181. }
  182. }
  183. }
  184. updateInputValue() {
  185. var s = this.getStartButton();
  186. var e = this.getEndButton();
  187. var k = this.kssj;
  188. var j = this.jssj;
  189. k.updateDataFromInputValue();
  190. j.updateDataFromInputValue();
  191. if (s == null || e == null) {
  192. k.time = "";
  193. j.time = "";
  194. } else {
  195. var today = new Date().timeRangeFormat("yyyy-MM-dd");
  196. if (k.date == "" && j.date == "") {
  197. k.date = today;
  198. j.date = today;
  199. } else if (j.date == "") {
  200. j.date = k.date;
  201. } else if (k.date == "") {
  202. k.date = j.date;
  203. }
  204. k.time = s.start;
  205. j.time = e.end;
  206. }
  207. k.value(new Date(k.date + " " + k.time).timeRangeFormat(this._option.format));
  208. j.value(new Date(j.date + " " + j.time).timeRangeFormat(this._option.format));
  209. }
  210. }
  211. class TimeRangeButton {
  212. constructor(inputName, btnOption, timeRange) {
  213. this.buttonElement = notNull(document.querySelector("[name='" + inputName + "']"), "找不到元素“" + inputName + "”");
  214. this.id = timeRange.id + ".btn." + inputName;
  215. if (this.buttonElement.timeRange && this.buttonElement.timeRange.id != timeRange.id) {
  216. throw new Error("这个按钮已经绑定过timerange");
  217. }
  218. var me = this;
  219. this.name = inputName;
  220. this.buttonElement.timeRange = timeRange;
  221. this.buttonElement.timeRangeButton = this;
  222. /* 改 wdValue -- 规范 wdValue= 命名。Lin
  223. this.buttonElement.setAttribute("wdValue", "range-" + inputName);
  224. */ this.buttonElement.setAttribute("ssVal", "range-" + inputName);
  225. this.buttonElement.setAttribute("timerange-id", timeRange.id);
  226. this.buttonElement.setAttribute("range-start", btnOption.start);
  227. this.buttonElement.setAttribute("range-end", btnOption.end);
  228. this.start = btnOption.start;
  229. this.end = btnOption.end;
  230. this.timeRange = timeRange;
  231. wd.edit.onoffInit('radio', inputName, '', true, null, null, function () {
  232. me.click();
  233. }, 'edit');
  234. var selector = "input[name='" + this.name + "'][type='hidden']";
  235. var eles = document.querySelectorAll(selector);
  236. if (eles.length > 1) {
  237. console.error("有多个元素:" + selector)
  238. }
  239. this.onoffelement = notNull(eles[0]);
  240. }
  241. unCheckOthers() {
  242. var me = this;
  243. this.timeRange.foreachButton(function (button) {
  244. if (button != me) {
  245. button.unCheck();
  246. } else if (!me.isChecked()) {
  247. button.check();
  248. }
  249. });
  250. }
  251. unCheck() {
  252. wd.edit.onoffEdit(this.name, "off");
  253. }
  254. check() {
  255. if (!this.isChecked()) {
  256. wd.edit.onoffEdit(this.name, "range-" + this.name);
  257. }
  258. }
  259. click() {
  260. var s = this.timeRange.getStartButton();
  261. var e = this.timeRange.getEndButton();
  262. if (s != e) {
  263. var si = s.indexOfButtons();
  264. var ei = e.indexOfButtons();
  265. var startcheck = false;
  266. var resetOthers = false;
  267. this.timeRange.foreachButton(function (button) {
  268. if (button == s) {
  269. startcheck = true;
  270. return;
  271. } else if (button == e) {
  272. return false;
  273. }
  274. if (startcheck && !button.isChecked()) {
  275. resetOthers = true;
  276. return false;
  277. }
  278. });
  279. if (resetOthers) {
  280. this.unCheckOthers();
  281. }
  282. }
  283. this.timeRange.updateInputValue();
  284. }
  285. indexOfButtons() {
  286. return this.timeRange.buttons.indexOf(this);
  287. }
  288. prevButton() {
  289. return this.timeRange.buttons[this.indexOfButtons() - 1];
  290. }
  291. nextButton() {
  292. return this.timeRange.buttons[this.indexOfButtons() + 1];
  293. }
  294. isChecked() {
  295. return this.onoffelement.value == "range-" + this.name;
  296. }
  297. }
  298. class TimeRangeInput {
  299. constructor(inputName, timeRange) {
  300. var me = this;
  301. this.id = timeRange.id + ".input." + inputName;
  302. this.inputName = inputName;
  303. this.inputElement = notNull(document.querySelector("[name='" + inputName + "']"), "找不到元素" + inputName);
  304. this.inputElement.setAttribute("timerange-id", timeRange.id);
  305. this.timeRange = timeRange;
  306. this.updateDataFromInputValue();
  307. this.inputElement.addEventListener("focus", function () {
  308. me.updateDataFromInputValue();
  309. me.timeRange.echo();
  310. });
  311. this.inputElement.addEventListener("blur", function () {
  312. me.updateDataFromInputValue();
  313. me.timeRange.echo();
  314. });
  315. }
  316. updateDataFromInputValue() {
  317. var val = this.inputElement.value;
  318. var date = "", time = "";
  319. if (val.match(/(\d{4}-\d{2}-\d{2})?\s*?(\d{2}:\d{2}(:\d{2})?)?/)) {
  320. if (checkDate(val)) {
  321. date = val.replace(/\s*(\d{2}:\d{2}(:\d{2})?)/, "");
  322. time = val.replace(/(\d{4}-\d{2}-\d{2})\s*/, "");
  323. } else {
  324. console.error(this.inputName + " “" + val + "” 不是个日期");
  325. this.value("");
  326. }
  327. }
  328. this.date = date;
  329. this.time = time;
  330. this.inputElement.setAttribute("range-date", date);
  331. this.inputElement.setAttribute("range-time", time);
  332. }
  333. value(value) {
  334. var r = this.inputElement.value;
  335. if (value != null) {
  336. if (checkDate(value)) {
  337. this.inputElement.value = value;
  338. this.updateDataFromInputValue();
  339. } else {
  340. throw new Error(" “" + value + "” 不是个日期")
  341. }
  342. }
  343. return r;
  344. }
  345. }
  346. class KssjInput extends TimeRangeInput {
  347. constructor(inputName, inputRange) {
  348. super(inputName, inputRange);
  349. this.type = "KSSJ";
  350. }
  351. isKssj() {
  352. return true;
  353. }
  354. isJssj() {
  355. return false;
  356. }
  357. }
  358. class JssjInput extends TimeRangeInput {
  359. constructor(inputName, inputRange) {
  360. super(inputName, inputRange);
  361. this.type = "KSSJ";
  362. }
  363. isKssj() {
  364. return false;
  365. }
  366. isJssj() {
  367. return true;
  368. }
  369. }
  370. Object.defineProperty(TimeRangeButton, "timeRange", { enumerable: false });
  371. Object.defineProperty(TimeRangeButton, "buttonElement", { enumerable: false });
  372. Object.defineProperty(TimeRangeInput, "timeRange", { enumerable: false });
  373. Object.defineProperty(TimeRangeInput, "inputElement", { enumerable: false });