0aca555426f6f9d5587199e8e3d2122e649dacd5
[roojs1] / Roo / bootstrap / form / TimeField.js
1 /*
2  * - LGPL
3  *
4  * TimeField
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.form.TimeField
10  * @extends Roo.bootstrap.form.Input
11  * Bootstrap DateField class
12  * @cfg {Number} minuteStep the minutes is always the multiple of a fixed number, default 1
13  * 
14  * 
15  * @constructor
16  * Create a new TimeField
17  * @param {Object} config The config object
18  */
19
20 Roo.bootstrap.form.TimeField = function(config){
21     Roo.bootstrap.form.TimeField.superclass.constructor.call(this, config);
22     this.addEvents({
23             /**
24              * @event show
25              * Fires when this field show.
26              * @param {Roo.bootstrap.form.DateField} thisthis
27              * @param {Mixed} date The date value
28              */
29             show : true,
30             /**
31              * @event show
32              * Fires when this field hide.
33              * @param {Roo.bootstrap.form.DateField} this
34              * @param {Mixed} date The date value
35              */
36             hide : true,
37             /**
38              * @event select
39              * Fires when select a date.
40              * @param {Roo.bootstrap.form.DateField} this
41              * @param {Mixed} date The date value
42              */
43             select : true
44         });
45 };
46
47 Roo.extend(Roo.bootstrap.form.TimeField, Roo.bootstrap.form.Input,  {
48     
49     /**
50      * @cfg {String} format
51      * The default time format string which can be overriden for localization support.  The format must be
52      * valid according to {@link Date#parseDate} (defaults to 'H:i').
53      */
54     format : "H:i",
55     minuteStep : 1,
56
57     getAutoCreate : function()
58     {
59         this.after = '<i class="fa far fa-clock"></i>';
60         return Roo.bootstrap.form.TimeField.superclass.getAutoCreate.call(this);
61         
62          
63     },
64     onRender: function(ct, position)
65     {
66         
67         Roo.bootstrap.form.TimeField.superclass.onRender.call(this, ct, position);
68                 
69         this.pickerEl = Roo.get(document.body).createChild(Roo.bootstrap.form.TimeField.template);
70         
71         this.picker().setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
72         
73         this.pop = this.picker().select('>.datepicker-time',true).first();
74         this.pop.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
75         
76         this.picker().on('mousedown', this.onMousedown, this);
77         this.picker().on('click', this.onClick, this);
78         
79         this.picker().addClass('datepicker-dropdown');
80     
81         this.fillTime();
82         this.update();
83             
84         this.pop.select('.hours-up', true).first().on('click', this.onIncrementHours, this);
85         this.pop.select('.hours-down', true).first().on('click', this.onDecrementHours, this);
86         this.pop.select('.minutes-up', true).first().on('click', this.onIncrementMinutes, this);
87         this.pop.select('.minutes-down', true).first().on('click', this.onDecrementMinutes, this);
88         this.pop.select('button.period', true).first().on('click', this.onTogglePeriod, this);
89         this.pop.select('button.ok', true).first().on('click', this.setTime, this);
90
91     },
92     
93     fireKey: function(e){
94         if (!this.picker().isVisible()){
95             if (e.keyCode == 27) { // allow escape to hide and re-show picker
96                 this.show();
97             }
98             return;
99         }
100
101         e.preventDefault();
102         
103         switch(e.keyCode){
104             case 27: // escape
105                 this.hide();
106                 break;
107             case 37: // left
108             case 39: // right
109                 this.onTogglePeriod();
110                 break;
111             case 38: // up
112                 this.onIncrementMinutes();
113                 break;
114             case 40: // down
115                 this.onDecrementMinutes();
116                 break;
117             case 13: // enter
118             case 9: // tab
119                 this.setTime();
120                 break;
121         }
122     },
123     
124     onClick: function(e) {
125         e.stopPropagation();
126         e.preventDefault();
127     },
128     
129     picker : function()
130     {
131         return this.pickerEl;
132     },
133     
134     fillTime: function()
135     {    
136         var time = this.pop.select('tbody', true).first();
137         
138         time.dom.innerHTML = '';
139         
140         time.createChild({
141             tag: 'tr',
142             cn: [
143                 {
144                     tag: 'td',
145                     cn: [
146                         {
147                             tag: 'a',
148                             href: '#',
149                             cls: 'btn',
150                             cn: [
151                                 {
152                                     tag: 'i',
153                                     cls: 'hours-up fa fas fa-chevron-up'
154                                 }
155                             ]
156                         } 
157                     ]
158                 },
159                 {
160                     tag: 'td',
161                     cls: 'separator'
162                 },
163                 {
164                     tag: 'td',
165                     cn: [
166                         {
167                             tag: 'a',
168                             href: '#',
169                             cls: 'btn',
170                             cn: [
171                                 {
172                                     tag: 'i',
173                                     cls: 'minutes-up fa fas fa-chevron-up'
174                                 }
175                             ]
176                         }
177                     ]
178                 },
179                 {
180                     tag: 'td',
181                     cls: 'separator'
182                 }
183             ]
184         });
185         
186         time.createChild({
187             tag: 'tr',
188             cn: [
189                 {
190                     tag: 'td',
191                     cn: [
192                         {
193                             tag: 'span',
194                             cls: 'timepicker-hour',
195                             html: '00'
196                         }  
197                     ]
198                 },
199                 {
200                     tag: 'td',
201                     cls: 'separator',
202                     html: ':'
203                 },
204                 {
205                     tag: 'td',
206                     cn: [
207                         {
208                             tag: 'span',
209                             cls: 'timepicker-minute',
210                             html: '00'
211                         }  
212                     ]
213                 },
214                 {
215                     tag: 'td',
216                     cls: 'separator'
217                 },
218                 {
219                     tag: 'td',
220                     cn: [
221                         {
222                             tag: 'button',
223                             type: 'button',
224                             cls: 'btn btn-primary period',
225                             html: 'AM'
226                             
227                         }
228                     ]
229                 }
230             ]
231         });
232         
233         time.createChild({
234             tag: 'tr',
235             cn: [
236                 {
237                     tag: 'td',
238                     cn: [
239                         {
240                             tag: 'a',
241                             href: '#',
242                             cls: 'btn',
243                             cn: [
244                                 {
245                                     tag: 'span',
246                                     cls: 'hours-down fa fas fa-chevron-down'
247                                 }
248                             ]
249                         }
250                     ]
251                 },
252                 {
253                     tag: 'td',
254                     cls: 'separator'
255                 },
256                 {
257                     tag: 'td',
258                     cn: [
259                         {
260                             tag: 'a',
261                             href: '#',
262                             cls: 'btn',
263                             cn: [
264                                 {
265                                     tag: 'span',
266                                     cls: 'minutes-down fa fas fa-chevron-down'
267                                 }
268                             ]
269                         }
270                     ]
271                 },
272                 {
273                     tag: 'td',
274                     cls: 'separator'
275                 }
276             ]
277         });
278         
279     },
280     
281     update: function()
282     {
283         
284         if(typeof(this.time) === 'undefined') {
285             this.time = new Date();
286             var oldMinute = parseInt(this.time.format('i'));
287             var newMinute = Math.round(parseInt(this.time.format('i')) / this.minuteStep) * this.minuteStep;
288             this.time = this.time.add(Date.MINUTE, newMinute - oldMinute);
289         }
290         this.time = (typeof(this.time) === 'undefined') ? new Date() : this.time;
291         
292         this.fill();
293     },
294     
295     fill: function() 
296     {
297         var hours = this.time.getHours();
298         var minutes = this.time.getMinutes();
299         var period = 'AM';
300         
301         if(hours > 11){
302             period = 'PM';
303         }
304         
305         if(hours == 0){
306             hours = 12;
307         }
308         
309         
310         if(hours > 12){
311             hours = hours - 12;
312         }
313         
314         if(hours < 10){
315             hours = '0' + hours;
316         }
317         
318         if(minutes < 10){
319             minutes = '0' + minutes;
320         }
321         
322         this.pop.select('.timepicker-hour', true).first().dom.innerHTML = hours;
323         this.pop.select('.timepicker-minute', true).first().dom.innerHTML = minutes;
324         this.pop.select('button', true).first().dom.innerHTML = period;
325         
326     },
327     
328     place: function()
329     {   
330         this.picker().removeClass(['bottom-left', 'bottom-right', 'top-left', 'top-right']);
331         
332         var cls = ['bottom'];
333         
334         if((Roo.lib.Dom.getViewHeight() + Roo.get(document.body).getScroll().top) - (this.inputEl().getBottom() + this.picker().getHeight()) < 0){ // top
335             cls.pop();
336             cls.push('top');
337         }
338         
339         cls.push('right');
340         
341         if((Roo.lib.Dom.getViewWidth() + Roo.get(document.body).getScroll().left) - (this.inputEl().getLeft() + this.picker().getWidth()) < 0){ // left
342             cls.pop();
343             cls.push('left');
344         }
345         //this.picker().setXY(20000,20000);
346         this.picker().addClass(cls.join('-'));
347         
348         var _this = this;
349         
350         Roo.each(cls, function(c){
351             if(c == 'bottom'){
352                 (function() {
353                  //  
354                 }).defer(200);
355                  _this.picker().alignTo(_this.inputEl(),   "tr-br", [0, 10], false);
356                 //_this.picker().setTop(_this.inputEl().getHeight());
357                 return;
358             }
359             if(c == 'top'){
360                  _this.picker().alignTo(_this.inputEl(),   "br-tr", [0, 10], false);
361                 
362                 //_this.picker().setTop(0 - _this.picker().getHeight());
363                 return;
364             }
365             /*
366             if(c == 'left'){
367                 _this.picker().setLeft(_this.inputEl().getLeft() + _this.inputEl().getWidth() - _this.el.getLeft() - _this.picker().getWidth());
368                 return;
369             }
370             if(c == 'right'){
371                 _this.picker().setLeft(_this.inputEl().getLeft() - _this.el.getLeft());
372                 return;
373             }
374             */
375         });
376         
377     },
378   
379     onFocus : function()
380     {
381         Roo.bootstrap.form.TimeField.superclass.onFocus.call(this);
382         this.show();
383     },
384     
385     onBlur : function()
386     {
387         Roo.bootstrap.form.TimeField.superclass.onBlur.call(this);
388         this.hide();
389     },
390     
391     show : function()
392     {
393         this.picker().show();
394         this.pop.show();
395         this.update();
396         this.place();
397         
398         this.fireEvent('show', this, this.date);
399     },
400     
401     hide : function()
402     {
403         this.picker().hide();
404         this.pop.hide();
405         
406         this.fireEvent('hide', this, this.date);
407     },
408     
409     setTime : function()
410     {
411         this.hide();
412         this.setValue(this.time.format(this.format));
413         
414         this.fireEvent('select', this, this.date);
415         
416         
417     },
418     
419     onMousedown: function(e){
420         e.stopPropagation();
421         e.preventDefault();
422     },
423     
424     onIncrementHours: function()
425     {
426         Roo.log('onIncrementHours');
427         this.time = this.time.add(Date.HOUR, 1);
428         this.update();
429         
430     },
431     
432     onDecrementHours: function()
433     {
434         Roo.log('onDecrementHours');
435         this.time = this.time.add(Date.HOUR, -1);
436         this.update();
437     },
438     
439     onIncrementMinutes: function()
440     {
441         Roo.log('onIncrementMinutes');
442         var minutesToAdd = Math.round((parseInt(this.time.format('i')) + this.minuteStep) / this.minuteStep) * this.minuteStep - parseInt(this.time.format('i'));
443         this.time = this.time.add(Date.MINUTE, minutesToAdd);
444         this.update();
445     },
446     
447     onDecrementMinutes: function()
448     {
449         Roo.log('onDecrementMinutes');
450         var minutesToSubtract = parseInt(this.time.format('i')) - Math.round((parseInt(this.time.format('i')) - this.minuteStep) / this.minuteStep) * this.minuteStep;
451         this.time = this.time.add(Date.MINUTE, -1 * minutesToSubtract);
452         this.update();
453     },
454     
455     onTogglePeriod: function()
456     {
457         Roo.log('onTogglePeriod');
458         this.time = this.time.add(Date.HOUR, 12);
459         this.update();
460     }
461     
462    
463 });
464  
465
466 Roo.apply(Roo.bootstrap.form.TimeField,  {
467   
468     template : {
469         tag: 'div',
470         cls: 'datepicker dropdown-menu',
471         cn: [
472             {
473                 tag: 'div',
474                 cls: 'datepicker-time',
475                 cn: [
476                 {
477                     tag: 'table',
478                     cls: 'table-condensed',
479                     cn:[
480                         {
481                             tag: 'tbody',
482                             cn: [
483                                 {
484                                     tag: 'tr',
485                                     cn: [
486                                     {
487                                         tag: 'td',
488                                         colspan: '7'
489                                     }
490                                     ]
491                                 }
492                             ]
493                         },
494                         {
495                             tag: 'tfoot',
496                             cn: [
497                                 {
498                                     tag: 'tr',
499                                     cn: [
500                                     {
501                                         tag: 'th',
502                                         colspan: '7',
503                                         cls: '',
504                                         cn: [
505                                             {
506                                                 tag: 'button',
507                                                 cls: 'btn btn-info ok',
508                                                 html: 'OK'
509                                             }
510                                         ]
511                                     }
512                     
513                                     ]
514                                 }
515                             ]
516                         }
517                     ]
518                 }
519                 ]
520             }
521         ]
522     }
523 });
524
525  
526
527