Dotclear

source: admin/js/date-picker.js @ 3922:97da59a8f577

Revision 3922:97da59a8f577, 12.4 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

Switching from inline JS variables to JSON script. Date picker is on the way

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

Sites map