Dotclear

source: admin/js/date-picker.js @ 3930:5007b8ff2be4

Revision 3930:5007b8ff2be4, 12.5 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

Switching from inline JS variables to JSON script. Common js vars and msg

Line 
1/*global getData */
2/*exported datePicker */
3'use strict';
4
5function datePicker(target) {
6  if (!document.getElementById) {
7    return;
8  }
9
10  if (!target || target.nodeName.toLowerCase() != 'input') {
11    return;
12  }
13
14  this.target = target;
15  this.oTable = document.createElement('table');
16  this.oBody = document.createElement('tbody');
17  this.oDates = [];
18  this.oMonth = document.createElement('span');
19  this.oYear = document.createElement('span');
20  this.oHour = document.createElement('input');
21  this.oMinute = document.createElement('input');
22  this.oTable.id = 'dc_datepicker_' + target.id;
23  this.oTable.className = 'date-picker';
24
25  let cur = 1;
26  let oRow;
27  let oHeading;
28  let oSpan;
29
30  // Set title
31  oRow = document.createElement('tr');
32
33  // Month block
34  oHeading = document.createElement('th');
35  oHeading.colSpan = 4;
36  oHeading.className = 'date-picker-month';
37
38  let nav = document.createElement('span');
39  nav.appendChild(document.createTextNode(String.fromCharCode(171)));
40  nav.fn = this.changeMonth;
41  nav.obj = this;
42  nav.onclick = function() {
43    this.fn.call(this.obj, -1);
44  };
45  nav.className = 'date-picker-control';
46  oHeading.appendChild(nav);
47
48  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
49
50  nav = document.createElement('span');
51  nav.appendChild(document.createTextNode(String.fromCharCode(187)));
52  nav.fn = this.changeMonth;
53  nav.obj = this;
54  nav.onclick = function() {
55    this.fn.call(this.obj, +1);
56  };
57  nav.className = 'date-picker-control';
58  oHeading.appendChild(nav);
59
60  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
61
62  oHeading.appendChild(this.oMonth);
63
64  oRow.appendChild(oHeading);
65
66  // Year block
67  oHeading = document.createElement('th');
68  oHeading.colSpan = 3;
69  oHeading.className = 'date-picker-year';
70
71  oHeading.appendChild(this.oYear);
72
73  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
74
75  nav = document.createElement('span');
76  nav.appendChild(document.createTextNode(String.fromCharCode(171)));
77  nav.fn = this.changeYear;
78  nav.obj = this;
79  nav.onclick = function() {
80    this.fn.call(this.obj, -1);
81  };
82  nav.className = 'date-picker-control';
83  oHeading.appendChild(nav);
84
85  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
86
87  nav = document.createElement('span');
88  nav.appendChild(document.createTextNode(String.fromCharCode(187)));
89  nav.fn = this.changeYear;
90  nav.obj = this;
91  nav.onclick = function() {
92    this.fn.call(this.obj, +1);
93  };
94  nav.className = 'date-picker-control';
95  oHeading.appendChild(nav);
96
97  oRow.appendChild(oHeading);
98
99  this.oBody.appendChild(oRow);
100
101  // Create legend
102  oRow = document.createElement('tr');
103  for (let i = 0; i < this.days.length; i++) {
104    const cday = this.days[i].substring(0, 1).toUpperCase();
105    oHeading = document.createElement('th');
106    oHeading.appendChild(document.createTextNode(cday));
107    oHeading.setAttribute('title', this.days[i]);
108    oRow.appendChild(oHeading);
109  }
110  this.oBody.appendChild(oRow);
111
112  // Create 6 rows of 7 cols for days
113  for (let i = 0; i < 6; i++) {
114    oRow = document.createElement('tr');
115
116    for (let j = 0; j < 7; j++) {
117      this.oDates[cur] = document.createElement('td');
118      this.oDates[cur].appendChild(document.createTextNode(
119        String.fromCharCode(160)));
120      oRow.appendChild(this.oDates[cur]);
121      cur++;
122    }
123
124    this.oBody.appendChild(oRow);
125  }
126
127  // Time controls
128  oRow = document.createElement('tr');
129
130  oHeading = document.createElement('th');
131  oHeading.className = 'date-picker-control';
132  oHeading.appendChild(document.createTextNode('!'));
133  oHeading.setAttribute('title', this.now_msg);
134  oHeading.fn = this.sendNow;
135  oHeading.obj = this;
136  oHeading.onclick = function() {
137    this.fn.call(this.obj);
138  };
139
140  oRow.appendChild(oHeading);
141
142  oHeading = document.createElement('th');
143  oHeading.colSpan = 5;
144
145  oSpan = document.createElement('span');
146  oSpan.className = 'date-picker-control';
147  oSpan.appendChild(document.createTextNode('-'));
148  oSpan.fn = this.changeHour;
149  oSpan.obj = this;
150  oSpan.onclick = function() {
151    this.fn.call(this.obj, -1);
152  };
153  oHeading.appendChild(oSpan);
154  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
155  oSpan = document.createElement('span');
156  oSpan.className = 'date-picker-control';
157  oSpan.appendChild(document.createTextNode('+'));
158  oSpan.fn = this.changeHour;
159  oSpan.obj = this;
160  oSpan.onclick = function() {
161    this.fn.call(this.obj, +1);
162  };
163  oHeading.appendChild(oSpan);
164  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
165
166  this.oHour.size = 2;
167  oHeading.appendChild(this.oHour);
168
169  oHeading.appendChild(document.createTextNode(' : '));
170
171  this.oMinute.size = 2;
172  oHeading.appendChild(this.oMinute);
173
174  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
175  oSpan = document.createElement('span');
176  oSpan.className = 'date-picker-control';
177  oSpan.appendChild(document.createTextNode('-'));
178  oSpan.fn = this.changeMinute;
179  oSpan.obj = this;
180  oSpan.onclick = function() {
181    this.fn.call(this.obj, -1);
182  };
183  oHeading.appendChild(oSpan);
184  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
185  oSpan = document.createElement('span');
186  oSpan.className = 'date-picker-control';
187  oSpan.appendChild(document.createTextNode('+'));
188  oSpan.fn = this.changeMinute;
189  oSpan.obj = this;
190  oSpan.onclick = function() {
191    this.fn.call(this.obj, +1);
192  };
193
194  oHeading.appendChild(oSpan);
195
196  oRow.appendChild(oHeading);
197
198  // Close control
199  oHeading = document.createElement('th');
200  oHeading.className = 'date-picker-control';
201  oHeading.appendChild(document.createTextNode('x'));
202  oHeading.setAttribute('title', this.close_msg);
203  oHeading.fn = this.close;
204  oHeading.obj = this;
205  oHeading.onclick = function() {
206    this.fn.call(this.obj);
207  };
208
209  oRow.appendChild(oHeading);
210
211  this.oBody.appendChild(oRow);
212}
213
214datePicker.prototype = {
215  year: 0,
216  month: 0,
217  day: 0,
218  hour: 0,
219  minute: 0,
220
221  img_src: '',
222  img_top: '0.2em',
223  now_msg: 'now',
224  close_msg: 'close',
225
226  days: new Array('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
227    'Saturday', 'Sunday'),
228
229  months: new Array('January', 'February', 'March', 'April', 'May', 'June',
230    'July', 'August', 'September', 'October', 'November', 'December'),
231
232  setDate: function() {
233    if (this.numberOfDays() < this.day) {
234      this.day = this.numberOfDays();
235    }
236
237    while (this.oYear.hasChildNodes()) {
238      this.oYear.removeChild(this.oYear.firstChild);
239    }
240    this.oYear.appendChild(document.createTextNode(this.year));
241
242    while (this.oMonth.hasChildNodes()) {
243      this.oMonth.removeChild(this.oMonth.firstChild);
244    }
245    this.oMonth.appendChild(document.createTextNode(
246      this.months[this.month - 1]));
247
248    const firstDay = this.firstDay();
249    const nbDays = this.numberOfDays();
250
251    // Empty days
252    for (let i = 1; i <= 42; i++) {
253      while (this.oDates[i].hasChildNodes()) {
254        this.oDates[i].removeChild(this.oDates[i].firstChild);
255      }
256      this.oDates[i].appendChild(document.createTextNode('-'));
257      this.oDates[i].className = '';
258      this.oDates[i].onclick = function() {
259        return;
260      };
261    }
262
263    // Insert days from the first day to the last
264    for (let i = 1; i <= nbDays; i++) {
265      const j = firstDay + i - 1;
266
267      while (this.oDates[j].hasChildNodes()) {
268        this.oDates[j].removeChild(this.oDates[j].firstChild);
269      }
270
271      this.oDates[j].appendChild(document.createTextNode(i));
272      this.oDates[j].index = i;
273      this.oDates[j].fn = this.sendDate;
274      this.oDates[j].obj = this;
275      this.oDates[j].onclick = function() {
276        this.fn.call(this.obj, this.index);
277      };
278      if (i == this.day) {
279        this.oDates[j].className = 'date-picker-today';
280      } else {
281        this.oDates[j].className = 'date-picker-day';
282      }
283    }
284
285    // Set time
286    this.setHour(this.hour);
287    this.setMinute(this.minute);
288  },
289
290  setHour: function(h) {
291    if (h < 0) {
292      h = 23;
293    }
294    if (h > 23) {
295      h = 0;
296    }
297    if (h < 10) {
298      h = '0' + h;
299    }
300
301    this.hour = h * 1;
302    this.oHour.value = h;
303  },
304
305  setMinute: function(m) {
306    if (m < 0) {
307      m = 59;
308    }
309    if (m > 59) {
310      m = 0;
311    }
312    if (m < 10) {
313      m = '0' + m;
314    }
315
316    this.minute = m * 1;
317    this.oMinute.value = m;
318  },
319
320  changeMonth: function(dir) {
321    const m = this.month + dir;
322
323    if (m > 12) {
324      this.month = 1;
325      this.year++;
326    } else if (m < 1) {
327      this.month = 12;
328      this.year--;
329    } else {
330      this.month = m;
331    }
332
333    this.setDate();
334  },
335
336  changeYear: function(dir) {
337    this.year = this.year + dir;
338    this.setDate();
339  },
340
341  changeHour: function(dir) {
342    this.setHour(this.hour * 1 + dir);
343  },
344
345  changeMinute: function(dir) {
346    this.setMinute(this.minute * 1 + dir);
347  },
348
349  sendDate: function(d) {
350    let m = this.month;
351    let hour = this.oHour.value * 1;
352    let minute = this.oMinute.value * 1;
353
354    if (hour < 0 || hour > 23 || isNaN(hour)) {
355      hour = 0;
356    }
357    if (minute < 0 || minute > 59 || isNaN(minute)) {
358      minute = 0;
359    }
360
361    if (m < 10) {
362      m = '0' + m;
363    }
364    if (d < 10) {
365      d = '0' + d;
366    }
367    if (hour < 10) {
368      hour = '0' + hour;
369    }
370    if (minute < 10) {
371      minute = '0' + minute;
372    }
373
374    this.target.value = `${this.year}-${m}-${d} ${hour}:${minute}`;
375    this.close();
376  },
377
378  sendNow: function() {
379    let dt = new Date();
380    const y = dt.getFullYear();
381    let m = dt.getMonth() + 1;
382    let d = dt.getDate();
383    let h = dt.getHours();
384    let i = dt.getMinutes();
385
386    if (m < 10) {
387      m = '0' + m;
388    }
389    if (d < 10) {
390      d = '0' + d;
391    }
392    if (h < 10) {
393      h = '0' + h;
394    }
395    if (i < 10) {
396      i = '0' + i;
397    }
398
399    this.target.value = `${y}-${m}-${d} ${h}:${i}`;
400    this.close();
401  },
402
403  close: function() {
404    document.body.removeChild(this.oTable);
405  },
406
407  numberOfDays: function() {
408    let res = 31;
409    if (this.month == 4 || this.month == 6 || this.month == 9 ||
410      this.month == 11) {
411      res = 30;
412    } else if (this.month == 2) {
413      res = 28;
414      if (this.year % 4 == 0 && (this.year % 100 != 0 ||
415          this.year % 400 == 0)) {
416        res = 29;
417      }
418    }
419
420    return res;
421  },
422
423  firstDay: function() {
424    let dt = new Date(this.year, this.month - 1, 1);
425    let res = dt.getDay();
426
427    if (res == 0) {
428      res = 7;
429    }
430
431    return res;
432  },
433
434  show: function() {
435    // Parsing target value
436    const re = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/;
437    const match = re.exec(this.target.value);
438    if (match) {
439      this.year = match[1] * 1;
440      this.month = match[2] * 1;
441      this.day = match[3] * 1;
442      this.hour = match[4] * 1;
443      this.minute = match[5] * 1;
444    } else {
445      let dt = new Date();
446      this.year = dt.getFullYear();
447      this.month = dt.getMonth() + 1;
448      this.day = dt.getDate();
449      this.hour = dt.getHours();
450      this.minute = dt.getMinutes();
451    }
452
453    this.oTable.appendChild(this.oBody);
454    this.setDate();
455    this.setPosition();
456    document.body.appendChild(this.oTable);
457    this.oHour.focus();
458  },
459
460  setPosition: function() {
461    const t_x = this.findPosX(this.target);
462    const t_y = this.findPosY(this.target);
463
464    this.oTable.style.position = 'absolute';
465    this.oTable.style.zIndex = '100';
466    this.oTable.style.top = t_y + 'px';
467    this.oTable.style.left = t_x + 'px';
468  },
469
470  findPosX: function(obj) {
471    let curleft = 0;
472    if (obj.offsetParent) {
473      while (1) {
474        curleft += obj.offsetLeft;
475        if (!obj.offsetParent) {
476          break;
477        }
478        obj = obj.offsetParent;
479      }
480    } else if (obj.x) {
481      curleft += obj.x;
482    }
483    return curleft;
484  },
485
486  findPosY: function(obj) {
487    let curtop = 0;
488    if (obj.offsetParent) {
489      while (1) {
490        curtop += obj.offsetTop;
491        if (!obj.offsetParent) {
492          break;
493        }
494        obj = obj.offsetParent;
495      }
496    } else if (obj.y) {
497      curtop += obj.y;
498    }
499    return curtop;
500  },
501
502  draw: function() {
503    const imgE = document.createElement('img');
504    imgE.src = this.img_src;
505    imgE.alt = this.img_alt;
506    imgE.style.position = 'absolute';
507    imgE.style.top = this.img_top;
508    imgE.style.left = (this.target.clientWidth + 4) + 'px';
509    imgE.obj = this;
510    imgE.fn = this.show;
511    imgE.onclick = function() {
512      this.fn.apply(this.obj);
513    };
514
515    this.target.parentNode.style.position = 'relative';
516    this.target.parentNode.insertBefore(imgE, this.target.nextSibling);
517  }
518};
519
520// Get some DATA
521Object.assign(datePicker.prototype, getData('date_picker'));
Note: See TracBrowser for help on using the repository browser.

Sites map