tom@1199: /* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz tom@1199: * Software engineering by Intevation GmbH tom@1199: * tom@1199: * This file is Free Software under the GNU GPL (v>=3) tom@1199: * and comes with ABSOLUTELY NO WARRANTY! Check out tom@1199: * the documentation coming with IMIS-Labordaten-Application for details. tom@1199: */ tom@1199: tom@1199: /** tom@1199: * Panel to select month and day of month, tom@1199: * that can be serialized to day of year tom@1199: */ tom@1199: Ext.define('Lada.view.widget.DayOfYear', { tom@1199: extend: 'Ext.panel.Panel', tom@1199: alias: 'widget.dayofyear', tom@1199: tom@1199: layout: { tom@1199: type: 'hbox', tom@1199: pack: 'end', tom@1199: defaultMargins: '3' tom@1199: }, tom@1199: tom@1199: initComponent: function() { tom@1199: var me = this; tom@1199: tom@1211: var monthsStore = Ext.create('Ext.data.Store', { tom@1211: fields: ['id', 'name'], tom@1211: data: [{ tom@1211: 'id': 0, tom@1211: 'name': 'Januar' tom@1211: }, { tom@1211: 'id': 1, tom@1211: 'name': 'Februar' tom@1211: }, { tom@1211: 'id': 2, tom@1211: 'name': 'März' tom@1211: }, { tom@1211: 'id': 3, tom@1211: 'name': 'April' tom@1211: }, { tom@1211: 'id': 4, tom@1211: 'name': 'Mai' tom@1211: }, { tom@1211: 'id': 5, tom@1211: 'name': 'Juni' tom@1211: }, { tom@1211: 'id': 6, tom@1211: 'name': 'Juli' tom@1211: }, { tom@1211: 'id': 7, tom@1211: 'name': 'August' tom@1211: }, { tom@1211: 'id': 8, tom@1211: 'name': 'September' tom@1211: }, { tom@1211: 'id': 9, tom@1211: 'name': 'Oktober' tom@1211: }, { tom@1211: 'id': 10, tom@1211: 'name': 'November' tom@1211: }, { tom@1211: 'id': 11, tom@1211: 'name': 'Dezember' tom@1211: }] tom@1211: }); tom@1211: tom@1199: /* tom@1199: * Create hidden field to hold the day of year value tom@1199: * for/of the record of the form. tom@1199: */ tom@1199: var DOYField = Ext.create('Ext.form.field.Number', { tom@1199: name: this.name, tom@1199: hidden: true, tom@1212: allowBlank: this.allowBlank, tom@1199: listeners: this.listeners tom@1199: }); tom@1199: /* Use dirtychange to avoid endless loop with change listeners on tom@1199: * visible items. This one is for initialisation by the form. */ tom@1199: DOYField.addListener('dirtychange', me.setFields); tom@1212: DOYField.addListener('validitychange', me.validityChange); tom@1199: tom@1199: /* tom@1199: * Add hidden field and visible fields to let the user choose tom@1199: * day and month to the panel. tom@1199: */ tom@1199: this.items = [{ tom@1199: xtype: 'numberfield', tom@1199: isFormField: false, tom@1199: fieldLabel: this.fieldLabel, tom@1199: labelWidth: this.labelWidth, tom@1199: width: 50 + this.labelWidth, tom@1199: msgTarget: 'none', tom@1199: allowDecimals: false, tom@1199: maxLength: 2, tom@1199: enforceMaxLength: true, tom@1199: allowBlank: this.allowBlank, tom@1199: minValue: 1, tom@1199: maxValue: 31, tom@1199: emptyText: 'Tag', tom@1199: listeners: { tom@1199: /* we have to listen on change because checkMaxDay() might tom@1199: * change the value. UI events like blur do not track this. */ tom@1199: change: { fn: me.setDOY } tom@1199: } tom@1199: }, { tom@1199: xtype: 'combobox', tom@1199: isFormField: false, tom@1199: width: 100, tom@1199: msgTarget: 'none', tom@1199: store: monthsStore, tom@1199: allowBlank: this.allowBlank, tom@1199: forceSelection: true, tom@1199: valueField: 'id', tom@1199: displayField: 'name', tom@1199: emptyText: 'Monat', tom@1199: queryMode: 'local', tom@1199: listeners: { tom@1199: collapse: { fn: me.setDOY }, tom@1199: change: { fn: me.checkMaxDay } tom@1199: } tom@1199: }, { tom@1199: xtype: 'image', tom@1199: name: 'warnImg', tom@1199: src: 'resources/img/dialog-warning.png', tom@1199: width: 14, tom@1199: height: 14, tom@1199: hidden: true tom@1199: }, { tom@1199: xtype: 'image', tom@1199: name: 'errorImg', tom@1199: src: 'resources/img/emblem-important.png', tom@1199: width: 14, tom@1199: height: 14, tom@1199: hidden: true tom@1199: }, DOYField]; tom@1199: tom@1199: this.callParent(arguments); tom@1199: }, tom@1199: tom@1199: /* tom@1199: * Set values in panel items for day and month tom@1199: * from hidden day of year field tom@1199: */ tom@1199: setFields: function() { tom@1199: var panel = this.up('panel'); tom@1199: tom@1199: // create a date object with arbitrary non-leap year tom@1199: var doy = panel.down('numberfield[hidden]').getValue(); tom@1199: tom@1199: if (doy != null) { tom@1207: // day of year is 0-based in ExtJS, but 1-based in the model tom@1207: doy -= 1; tom@1199: var date = Ext.Date.subtract( tom@1199: new Date(1970, 0, 1), Ext.Date.DAY, -doy); tom@1199: var month = date.getMonth(); tom@1199: var day = date.getDate(); tom@1199: panel.down('combobox').setValue(month); tom@1199: panel.down('numberfield[hidden=false]').setValue(day); tom@1199: } tom@1199: }, tom@1199: tom@1199: /* tom@1199: * Function to be called from listeners of visible items tom@1199: * to set the value of the hidden day of year field. tom@1199: */ tom@1199: setDOY: function() { tom@1199: var panel = this.up('panel'); tom@1199: var month = panel.down('combobox').getValue(); tom@1199: var day = panel.down('numberfield[hidden=false]').getValue(); tom@1199: var maxDay = panel.down('numberfield[hidden=false]').maxValue; tom@1212: var doy = null; tom@1199: tom@1199: if (month != null && day != null && day <= maxDay) { tom@1199: // create a date object with arbitrary non-leap year tom@1199: var date = new Date(1970, month, day); tom@1207: tom@1207: // day of year is 0-based in ExtJS, but 1-based in the model tom@1212: doy = Ext.Date.getDayOfYear(date) + 1; tom@1199: } tom@1212: panel.down('numberfield[hidden]').setValue(doy); tom@1199: }, tom@1199: tom@1199: /* tom@1199: * Call from listener of month selection widget to set maximum and tom@1199: * validate associated day value. tom@1199: */ tom@1199: checkMaxDay: function() { tom@1199: // create a date object with arbitrary non-leap year tom@1199: var maxDay = Ext.Date.getDaysInMonth( tom@1199: new Date(1970, this.getValue())); tom@1199: this.up('panel').down('numberfield[hidden=false]') tom@1199: .setMaxValue(maxDay); tom@1199: tom@1199: var curDay = this.up('panel') tom@1199: .down('numberfield[hidden=false]').getValue(); tom@1212: if (curDay) { tom@1212: if (curDay > maxDay) { tom@1212: this.up('panel').down('numberfield[hidden=false]') tom@1212: .setValue(maxDay); tom@1212: } tom@1199: this.up('panel').down('numberfield[hidden=false]') tom@1212: .clearInvalid(); tom@1199: } tom@1199: }, tom@1199: tom@1199: tom@1199: showWarnings: function(warnings) { tom@1199: var img = this.down('image[name=warnImg]'); tom@1199: Ext.create('Ext.tip.ToolTip', { tom@1199: target: img.getEl(), tom@1199: html: warnings tom@1199: }); tom@1199: img.show(); tom@1199: this.down('numberfield[hidden=false]').invalidCls = 'x-lada-warning'; tom@1199: this.down('numberfield[hidden=false]').markInvalid(''); tom@1199: this.down('combobox').markInvalid(''); tom@1199: var fieldset = this.up('fieldset[collapsible=true]'); tom@1199: if (fieldset) { tom@1199: var i18n = Lada.getApplication().bundle; tom@1199: var warningText = i18n.getMsg(this.name) + ': ' + warnings; tom@1199: fieldset.showWarningOrError(true, warningText); tom@1199: } tom@1199: }, tom@1199: tom@1199: showErrors: function(errors) { tom@1199: var img = this.down('image[name=errorImg]'); tom@1199: var warnImg = this.down('image[name=warnImg]'); tom@1199: warnImg.hide(); tom@1199: Ext.create('Ext.tip.ToolTip', { tom@1199: target: img.getEl(), tom@1199: html: errors tom@1199: }); tom@1199: this.down('numberfield[hidden=false]').invalidCls = 'x-lada-error'; tom@1199: this.down('numberfield[hidden=false]').markInvalid(''); tom@1199: this.down('combobox').markInvalid(''); tom@1199: img.show(); tom@1199: var fieldset = this.up('fieldset[collapsible=true]'); tom@1199: if (fieldset) { tom@1199: var i18n = Lada.getApplication().bundle; tom@1199: var errorText = i18n.getMsg(this.name) + ': ' + errors; tom@1199: fieldset.showWarningOrError(false, '', true, errorText); tom@1199: } tom@1199: }, tom@1199: tom@1212: /* tom@1212: * When the hidden field is validated as part of a form, make the result tom@1212: * user visible. tom@1212: */ tom@1212: validityChange: function(field, isValid) { tom@1212: if (!isValid) { tom@1212: var errors = field.getActiveErrors() tom@1212: field.up('panel').down('combobox').markInvalid(errors); tom@1212: field.up('panel').down('numberfield[hidden=false]') tom@1212: .markInvalid(errors); tom@1212: } else { tom@1212: field.up('panel').down('combobox').clearInvalid(); tom@1212: field.up('panel').down('numberfield[hidden=false]').clearInvalid(); tom@1212: } tom@1212: }, tom@1212: tom@1199: clearWarningOrError: function() { tom@1199: this.down('image[name=errorImg]').hide(); tom@1199: this.down('image[name=warnImg]').hide(); tom@1199: }, tom@1199: tom@1199: getValue: function() { tom@1199: this.down('numberfield[hidden]').getValue(); tom@1199: }, tom@1199: tom@1199: setValue: function(value) { tom@1199: this.down('numberfield[hidden]').setValue(value); tom@1199: } tom@1199: });