dustin@892: /* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz
dustin@892:  * Software engineering by Intevation GmbH
dustin@892:  *
dustin@892:  * This file is Free Software under the GNU GPL (v>=3)
dustin@892:  * and comes with ABSOLUTELY NO WARRANTY! Check out
dustin@892:  * the documentation coming with IMIS-Labordaten-Application for details.
dustin@892:  */
dustin@892: 
dustin@892: /**
dustin@892:  * This Widget extends a DateTimePicker in order to create a
dustin@892:  * something like a DateTimePicker
dustin@892:  */
raimund@649: Ext.define('Lada.view.widget.base.DateTimePicker', {
raimund@649:     extend: 'Ext.picker.Date',
raimund@649:     alias: 'widget.datetimepicker',
raimund@649:     requires: [
raimund@649:         'Ext.picker.Date',
raimund@649:         'Ext.form.field.Number'
raimund@649:     ],
raimund@649: 
raimund@649:     todayText: 'Jetzt',
raimund@649: 
raimund@649:     renderTpl: [
raimund@649:         '<div id="{id}-innerEl" role="grid">',
raimund@649:             '<div role="presentation" class="{baseCls}-header">',
raimund@649:                  // the href attribute is required for the :hover selector to work in IE6/7/quirks
raimund@649:                 '<a id="{id}-prevEl" class="{baseCls}-prev {baseCls}-arrow" href="#" role="button" title="{prevText}" hidefocus="on" ></a>',
raimund@649:                 '<div class="{baseCls}-month" id="{id}-middleBtnEl">{%this.renderMonthBtn(values, out)%}</div>',
raimund@649:                  // the href attribute is required for the :hover selector to work in IE6/7/quirks
raimund@649:                 '<a id="{id}-nextEl" class="{baseCls}-next {baseCls}-arrow" href="#" role="button" title="{nextText}" hidefocus="on" ></a>',
raimund@649:             '</div>',
raimund@649:             '<table id="{id}-eventEl" class="{baseCls}-inner" cellspacing="0" role="grid">',
raimund@649:                 '<thead role="presentation"><tr role="row">',
raimund@649:                     '<tpl for="dayNames">',
raimund@649:                         '<th role="columnheader" class="{parent.baseCls}-column-header" title="{.}">',
raimund@649:                             '<div class="{parent.baseCls}-column-header-inner">{.:this.firstInitial}</div>',
raimund@649:                         '</th>',
raimund@649:                     '</tpl>',
raimund@649:                 '</tr></thead>',
raimund@649:                 '<tbody role="presentation"><tr role="row">',
raimund@649:                     '<tpl for="days">',
raimund@649:                         '{#:this.isEndOfWeek}',
raimund@649:                         '<td role="gridcell" id="{[Ext.id()]}">',
raimund@649:                             // the href attribute is required for the :hover selector to work in IE6/7/quirks
raimund@649:                             '<a role="presentation" hidefocus="on" class="{parent.baseCls}-date" href="#"></a>',
raimund@649:                         '</td>',
raimund@649:                     '</tpl>',
raimund@649:                 '</tr></tbody>',
raimund@649:             '</table>',
raimund@649:             '<div id="{id}-timeEl" role="presentation" class="{baseCls}-footer">',
raimund@649:             '<table cellspacing="0">',
raimund@649:                 '<colgroup><col width="70"><col width="40"><col width="40"></colgroup>',
raimund@649:                 '<tr>',
raimund@649:                     '<td>',
raimund@649:                         '<div id="{id}-timeLabelEl" role="presentation">{%this.renderTimeLabel(values, out)%}</div>',
raimund@649:                     '</td><td>',
raimund@649:                         '<div id="{id}-timeHourEl" role="presentation">{%this.renderTimeHour(values, out)%}</div>',
raimund@649:                     '</td><td>',
raimund@649:                         '<div id="{id}-timeMinuteEl" role="presentation">{%this.renderTimeMinute(values, out)%}</div>',
raimund@649:                     '</td>',
raimund@649:                 '</tr>',
raimund@649:             '</table>',
raimund@649:             '<table cellspacing="0">',
raimund@649:                 '<colgroup width="75"></colgroup>',
raimund@649:                 '<tr>',
raimund@649:                     '<td>',
raimund@649:                         '<div id="{id}-footerNowEl" role="presentation">{%this.renderTodayBtn(values, out)%}</div>',
raimund@649:                     '</td><td>',
raimund@649:                         '<div id="{id}-footerAcceptEl" role="presentation">{%this.renderAcceptBtn(values, out)%}</div>',
raimund@649:                     '</td>',
raimund@649:                 '</tr>',
raimund@649:             '</table>',
raimund@649:             '</div>',
raimund@649:         '</div>',
raimund@649:         {
raimund@649:             firstInitial: function(value) {
raimund@649:                 return Ext.picker.Date.prototype.getDayInitial(value);
raimund@649:             },
raimund@649:             isEndOfWeek: function(value) {
raimund@649:                 // convert from 1 based index to 0 based
raimund@649:                 // by decrementing value once.
raimund@649:                 value--;
raimund@649:                 var end = value % 7 === 0 && value !== 0;
raimund@649:                 return end ? '</tr><tr role="row">' : '';
raimund@649:             },
raimund@649:             renderTodayBtn: function(values, out) {
raimund@649:                 Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out);
raimund@649:             },
raimund@649:             renderMonthBtn: function(values, out) {
raimund@649:                 Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out);
raimund@649:             },
raimund@649:             renderTimeLabel: function(values, out) {
raimund@649:                 Ext.DomHelper.generateMarkup(values.$comp.timeLabel.getRenderTree(), out);
raimund@649:             },
raimund@649:             renderTimeHour: function(values, out) {
raimund@649:                 Ext.DomHelper.generateMarkup(values.$comp.hourField.getRenderTree(), out);
raimund@649:             },
raimund@649:             renderTimeMinute: function(values, out) {
raimund@649:                 Ext.DomHelper.generateMarkup(values.$comp.minuteField.getRenderTree(), out);
raimund@649:             },
raimund@649:             renderAcceptBtn: function(values, out) {
raimund@649:                 Ext.DomHelper.generateMarkup(values.$comp.acceptBtn.getRenderTree(), out);
raimund@649:             }
raimund@649:         }
raimund@649:     ],
raimund@649: 
raimund@649:     beforeRender: function () {
raimund@649:         var me = this;
dustin@667:         me.hourField = new Ext.form.field.Number({
raimund@649:             ownerCt: me,
raimund@649:             ownerLayout: me.getComponentLayout(),
raimund@649:             value: 0,
dustin@667:             valueToRaw: function (value) {
dustin@667:                 return (value < 10 ? '0' : '') + value; // add leading Zero
dustin@667:             },
raimund@655:             maxValue: 23,
dustin@667:             maxLength: 2,
dustin@667:             enforceMaxLength: true,
raimund@651:             onSpinUp: function() {
raimund@651:                 var value = parseInt(this.getValue());
raimund@651:                 if (value === 23) {
raimund@651:                     return;
raimund@651:                 }
raimund@651:                 var newValue = value + 1;
dustin@667:                 this.setValue(newValue);
raimund@651:             },
raimund@651:             onSpinDown: function() {
raimund@651:                 var value = parseInt(this.getValue());
raimund@651:                 if (value === 0) {
raimund@651:                     return;
raimund@651:                 }
raimund@651:                 var newValue = value - 1;
dustin@667:                 this.setValue(newValue);
raimund@651:             },
raimund@649:             listeners: {
raimund@649:                 change: me.changeTimeValue,
raimund@649:                 scope: me
dustin@667:             },
dustin@667:             checkChangeEvents: ['change']
raimund@649:         });
raimund@649: 
dustin@667:         me.minuteField = new Ext.form.field.Number({
raimund@649:             ownerCt: me,
raimund@649:             ownerLayout: me.getComponentLayout(),
raimund@649:             value: 0,
raimund@655:             maxValue: 59,
dustin@667:             valueToRaw: function (value) {
dustin@667:                 return (value < 10 ? '0' : '') + value; // add leading Zero
dustin@667:             },
dustin@667:             maxLength: 2,
dustin@667:             enforceMaxLength: true,
raimund@651:             onSpinUp: function() {
raimund@651:                 var value = parseInt(this.getValue());
raimund@651:                 if (value === 59) {
raimund@651:                     return;
raimund@651:                 }
raimund@651:                 var newValue = value + 1;
dustin@667:                 this.setValue(newValue);
raimund@651:             },
raimund@651:             onSpinDown: function() {
raimund@651:                 var value = parseInt(this.getValue());
raimund@651:                 if (value === 0) {
raimund@651:                     return;
raimund@651:                 }
raimund@651:                 var newValue = value - 1;
dustin@667:                 this.setValue(newValue);
raimund@651:             },
raimund@649:             listeners: {
raimund@649:                 change: me.changeTimeValue,
raimund@649:                 scope: me
dustin@667:             },
dustin@667:             checkChangeEvents: ['change']
raimund@649:         });
raimund@649: 
raimund@649:         me.timeLabel = new Ext.form.Label({
raimund@649:             ownerCt: me,
raimund@649:             ownerLayout: me.getComponentLayout(),
raimund@649:             text: 'Zeit'
raimund@649:         });
raimund@649:         me.acceptBtn = new Ext.button.Button({
raimund@649:             ownerCt: me,
raimund@649:             ownerLayout: me.getComponentLayout(),
raimund@649:             text: 'Übernehmen',
raimund@649:             handler: me.acceptDate,
raimund@649:             scope: me
raimund@649:         });
raimund@649:         me.callParent();
raimund@649:     },
raimund@649: 
raimund@649:     finishRenderChildren: function() {
raimund@649:         var me = this;
raimund@649:         me.callParent();
raimund@649:         me.timeLabel.finishRender();
raimund@649:         me.hourField.finishRender();
raimund@649:         me.minuteField.finishRender();
raimund@649:         me.acceptBtn.finishRender();
raimund@649:     },
raimund@649: 
raimund@649:     showTimePicker: function() {
raimund@649:         var me = this;
raimund@649:         var el = me.el;
raimund@649:         Ext.defer(function() {
raimund@649:             var xPos = el.getX();
raimund@649:             var yPos = el.getY() + el.getHeight();
raimund@649:             me.timePicker.setHeight(30);
raimund@649:             me.timePicker.setWidth(el.getWidth());
raimund@649:             me.timePicker.setPosition(xPos, yPos);
raimund@649:             me.timePicker.show();
raimund@649:         },1);
raimund@649:     },
raimund@649: 
raimund@649:     beforeDestroy: function() {
raimund@649:         var me = this;
raimund@649:         if (me.rendered) {
raimund@649:             Ext.destroy(
raimund@649:                 me.minuteField,
raimund@649:                 me.hourField
raimund@649:             );
raimund@649:         }
raimund@649:         me.callParent();
raimund@649:     },
raimund@649: 
raimund@655:     changeTimeValue: function (field, nValue) {
raimund@655:         var value = parseInt(nValue);
raimund@655:         if (value > field.maxValue) {
raimund@655:             field.setValue(field.maxValue);
raimund@655:         }
dustin@667:         if (value == null || value == "" || isNaN(value)) {
dustin@667:             field.setValue('0');
raimund@655:         }
raimund@649:     },
raimund@649: 
raimund@649:     setValue: function(value) {
raimund@649:         value.setSeconds(0);
raimund@649:         this.value = new Date(value);
raimund@649:         return this.update(this.value);
raimund@649:     },
raimund@649: 
raimund@649:     selectToday: function() {
raimund@649:         var me = this;
raimund@649:         var btn = me.todayBtn;
raimund@649:         var handler = me.handler;
raimund@649:         var auxDate = new Date();
raimund@649: 
raimund@649:         if (btn && !btn.disabled) {
raimund@649:             me.pickerField.setValue(new Date(auxDate.setSeconds(0)));
raimund@649:             me.setValue(new Date(auxDate.setSeconds(0)));
raimund@649:             if (handler) {
raimund@649:                 handler.call(me.scope || me, me, me.value);
raimund@649:             }
raimund@649:             me.onSelect();
raimund@649:         }
raimund@649:         return me;
raimund@649:     },
raimund@649: 
raimund@649:     acceptDate: function() {
raimund@649:         var me = this;
raimund@649:         var hourSet = me.hourField.getValue();
raimund@649:         var minuteSet = me.minuteField.getValue();
raimund@649:         var currentDate = me.value;
raimund@649:         currentDate.setHours(hourSet);
raimund@649:         currentDate.setMinutes(minuteSet);
raimund@649:         me.setValue(currentDate);
raimund@649:         me.fireEvent('select', me, currentDate);
raimund@649:     },
raimund@649: 
raimund@649:     handleDateClick: function(e, t) {
raimund@649:         var me = this;
raimund@649:         var handler = me.handler;
raimund@649:         var hourSet = me.hourField.getValue();
raimund@649:         var minuteSet = me.minuteField.getValue();
raimund@649:         var auxDate = new Date(t.dateValue);
raimund@649:         e.stopEvent();
raimund@649:         if (!me.disabled &&
raimund@649:             t.dateValue &&
raimund@649:             !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)
raimund@649:         ) {
raimund@649:             me.doCancelFocus = me.focusOnSelect === false;
raimund@649:             auxDate.setHours(hourSet, minuteSet, 0);
raimund@649:             me.setValue(new Date(auxDate));
raimund@649:             delete me.doCancelFocus;
raimund@649:             if (handler) {
raimund@649:                 handler.call(me.scope || me, me, me.value);
raimund@649:             }
raimund@649:             // event handling is turned off on hide
raimund@649:             // when we are using the picker in a field
raimund@649:             // therefore onSelect comes AFTER the select
raimund@649:             // event.
raimund@649:             me.onSelect();
raimund@649:         }
raimund@649:     },
raimund@649: 
raimund@649:     selectedUpdate: function(date) {
raimund@649:         var me = this;
raimund@649:         var dateOnly = Ext.Date.clearTime(date, true);
raimund@649:         var t = dateOnly.getTime();
raimund@649:         var currentDate = (me.pickerField && me.pickerField.getValue()) || new Date();
raimund@649:         var cells = me.cells;
raimund@649:         var cls = me.selectedCls;
raimund@649:         var cellItems = cells.elements;
raimund@649:         var c;
raimund@649:         var cLen = cellItems.length;
raimund@649:         var cell;
raimund@649: 
raimund@649:         cells.removeCls(cls);
raimund@649: 
raimund@649:         for (c = 0; c < cLen; c++) {
raimund@649:             cell = Ext.fly(cellItems[c]);
raimund@649: 
raimund@649:             if (cell.dom.firstChild.dateValue == t) {
raimund@649:                 me.fireEvent('highlightitem', me, cell);
raimund@649:                 cell.addCls(cls);
raimund@649: 
raimund@649:                 if (me.isVisible() && !me.doCancelFocus) {
raimund@649:                     Ext.fly(cell.dom.firstChild).focus(50);
raimund@649:                 }
raimund@649: 
raimund@649:                 break;
raimund@649:             }
raimund@649:         }
raimund@649:         if (currentDate) {
raimund@649:             me.hourField.setValue(currentDate.getHours());
raimund@649:             me.minuteField.setValue(currentDate.getMinutes());
raimund@649:         }
raimund@649:     }
raimund@649: });