changeset 1199:0a7f0a09151c

Replace date-time picker with appropriate widget to select day of year. Validity period is not specific for a year. The calender widget was not appropriate here.
author Tom Gottfried <tom@intevation.de>
date Fri, 23 Sep 2016 16:49:26 +0200
parents 3b6f40541ac6
children e9efd2edb50f
files app/model/Messprogramm.js app/view/form/Messprogramm.js app/view/widget/DayOfYear.js
diffstat 3 files changed, 260 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/app/model/Messprogramm.js	Fri Sep 23 16:32:30 2016 +0200
+++ b/app/model/Messprogramm.js	Fri Sep 23 16:49:26 2016 +0200
@@ -61,70 +61,9 @@
     }, {
         name: 'intervallOffset'
     }, {
-        name: 'gueltigVon',
-        type: 'date',
-        convert: function(v) {
-            var firstofyeartimestamp = new Date(
-                Date.UTC(
-                    new Date().getFullYear(),0,1))
-                .valueOf();
-            var dayToMilli = 86400000;
-
-            if (!v) {
-                return v;
-            }
-            //check if v might be a date
-            // unless we go back in time this will work
-            if (v < 1000) {
-                v = v * dayToMilli;
-                v = v + firstofyeartimestamp;
-                v = new Date(v);
-            }
-            return v;
-        },
-        serialize: function(value) {
-            if (value instanceof Date && !isNaN(value.valueOf())) {
-                var dayOfYear = Ext.Date.getDayOfYear(value);
-                var offset = value.getTimezoneOffset();
-                if (offset == 0) {
-                    return dayOfYear;
-                }
-                return offset > 0 ? dayOfYear - 1 : dayOfYear + 1;
-            }
-        }
+        name: 'gueltigVon'
     }, {
-        name: 'gueltigBis',
-        type: 'date',
-        convert: function(v) {
-            var firstofyeartimestamp = new Date(
-                Date.UTC(
-                    new Date().getFullYear(),0,1))
-                .valueOf();
-            var dayToMilli = 86400000;
-
-            if (!v) {
-                return v;
-            }
-
-            //check if v might be a date
-            // unless we go back in time this will work
-            if (v < 1000) {
-                v = v * dayToMilli;
-                v = v + firstofyeartimestamp;
-                v = new Date(v);
-            }
-            return v;
-        },
-        serialize: function(value) {
-            if (value instanceof Date && !isNaN(value.valueOf())) {
-                var dayOfYear = Ext.Date.getDayOfYear(value);
-                var offset = value.getTimezoneOffset();
-                if (offset == 0) {
-                    return dayOfYear;
-                }
-                return offset > 0 ? dayOfYear - 1 : dayOfYear + 1;
-            }
-        }
+        name: 'gueltigBis'
     }, {
         name: 'probeNehmerId'
     }, {
--- a/app/view/form/Messprogramm.js	Fri Sep 23 16:32:30 2016 +0200
+++ b/app/view/form/Messprogramm.js	Fri Sep 23 16:49:26 2016 +0200
@@ -28,8 +28,7 @@
         'Lada.view.widget.Probenintervall',
         'Lada.view.widget.Location',
         'Lada.view.widget.ProbenintervallSlider',
-        'Lada.view.widget.base.Datetime',
-        'Lada.view.widget.base.DateField'
+        'Lada.view.widget.DayOfYear'
     ],
 
     model: 'Lada.model.Messprogramm',
@@ -262,23 +261,21 @@
                         },
                         border: 0,
                         items: [{
-                            xtype: 'datetime',
+                            xtype: 'dayofyear',
                             allowBlank: false,
                             fieldLabel: i18n.getMsg('gueltigVon'),
-                            margin: '0, 30, 5, 5',
+                            width: '50%',
                             labelWidth: 90,
                             name: 'gueltigVon',
-                            format: 'd.m.Y',
-                            period: 'start'
+                            border: false
                         }, {
-                            xtype: 'datetime',
+                            xtype: 'dayofyear',
                             allowBlank: false,
                             fieldLabel: i18n.getMsg('gueltigBis'),
-                            margin: '0, 5, 5, 5',
+                            width: '50%',
                             labelWidth: 40,
                             name: 'gueltigBis',
-                            format: 'd.m.Y',
-                            period: 'end'
+                            border: false
                         }]
                     }]
                 }, {
@@ -628,11 +625,10 @@
         // clear messages in intervall definition
         this.down('fset[name=probenIntervallFieldset]').clearMessages();
         this.down('cbox[name=probenintervall]').clearWarningOrError();
-        this.down('fset[name=gueltigPeriodFieldset]').clearMessages();
         this.down('numfield[name=teilintervallVon]').clearWarningOrError();
         this.down('numfield[name=teilintervallBis]').clearWarningOrError();
-        this.down('datetime[name=gueltigVon]').clearWarningOrError();
-        this.down('datetime[name=gueltigBis]').clearWarningOrError();
+        this.down('dayofyear[name=gueltigVon]').clearWarningOrError();
+        this.down('dayofyear[name=gueltigBis]').clearWarningOrError();
         //no clear for probeNehmerId
         // Deskriptoren are missing
         this.down('cbox[name=umwId]').clearWarningOrError();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/view/widget/DayOfYear.js	Fri Sep 23 16:49:26 2016 +0200
@@ -0,0 +1,249 @@
+/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out
+ * the documentation coming with IMIS-Labordaten-Application for details.
+ */
+
+var monthsStore = Ext.create('Ext.data.Store', {
+    fields: ['id', 'name'],
+    data: [{
+        'id': 0,
+        'name': 'Januar'
+    }, {
+        'id': 1,
+        'name': 'Februar'
+    }, {
+        'id': 2,
+        'name': 'März'
+    }, {
+        'id': 3,
+        'name': 'April'
+    }, {
+        'id': 4,
+        'name': 'Mai'
+    }, {
+        'id': 5,
+        'name': 'Juni'
+    }, {
+        'id': 6,
+        'name': 'Juli'
+    }, {
+        'id': 7,
+        'name': 'August'
+    }, {
+        'id': 8,
+        'name': 'September'
+    }, {
+        'id': 9,
+        'name': 'Oktober'
+    }, {
+        'id': 10,
+        'name': 'November'
+    }, {
+        'id': 11,
+        'name': 'Dezember'
+    }]
+});
+
+/**
+ * Panel to select month and day of month,
+ * that can be serialized to day of year
+ */
+Ext.define('Lada.view.widget.DayOfYear', {
+    extend: 'Ext.panel.Panel',
+    alias: 'widget.dayofyear',
+
+    layout: {
+        type: 'hbox',
+        pack: 'end',
+        defaultMargins: '3'
+    },
+
+    initComponent: function() {
+        var me = this;
+
+        /*
+         * Create hidden field to hold the day of year value
+         * for/of the record of the form.
+         */
+        var DOYField = Ext.create('Ext.form.field.Number', {
+            name: this.name,
+            hidden: true,
+            listeners: this.listeners
+        });
+        /* Use dirtychange to avoid endless loop with change listeners on
+         * visible items. This one is for initialisation by the form. */
+        DOYField.addListener('dirtychange', me.setFields);
+
+        /*
+         * Add hidden field and visible fields to let the user choose
+         * day and month to the panel.
+         */
+        this.items = [{
+            xtype: 'numberfield',
+            isFormField: false,
+            fieldLabel: this.fieldLabel,
+            labelWidth: this.labelWidth,
+            width: 50 + this.labelWidth,
+            msgTarget: 'none',
+            allowDecimals: false,
+            maxLength: 2,
+            enforceMaxLength: true,
+            allowBlank: this.allowBlank,
+            minValue: 1,
+            maxValue: 31,
+            emptyText: 'Tag',
+            listeners: {
+                /* we have to listen on change because checkMaxDay() might
+                 * change the value. UI events like blur do not track this. */
+                change: { fn: me.setDOY }
+            }
+        }, {
+            xtype: 'combobox',
+            isFormField: false,
+            width: 100,
+            msgTarget: 'none',
+            store: monthsStore,
+            allowBlank: this.allowBlank,
+            forceSelection: true,
+            valueField: 'id',
+            displayField: 'name',
+            emptyText: 'Monat',
+            queryMode: 'local',
+            listeners: {
+                collapse: { fn: me.setDOY },
+                change: { fn: me.checkMaxDay }
+            }
+        }, {
+            xtype: 'image',
+            name: 'warnImg',
+            src: 'resources/img/dialog-warning.png',
+            width: 14,
+            height: 14,
+            hidden: true
+        }, {
+            xtype: 'image',
+            name: 'errorImg',
+            src: 'resources/img/emblem-important.png',
+            width: 14,
+            height: 14,
+            hidden: true
+        }, DOYField];
+
+        this.callParent(arguments);
+    },
+
+    /*
+     * Set values in panel items for day and month
+     * from hidden day of year field
+     */
+    setFields: function() {
+        var panel = this.up('panel');
+
+        // create a date object with arbitrary non-leap year
+        var doy = panel.down('numberfield[hidden]').getValue();
+
+        if (doy != null) {
+            var date = Ext.Date.subtract(
+                new Date(1970, 0, 1), Ext.Date.DAY, -doy);
+            var month = date.getMonth();
+            var day = date.getDate();
+            panel.down('combobox').setValue(month);
+            panel.down('numberfield[hidden=false]').setValue(day);
+        }
+    },
+
+    /*
+     * Function to be called from listeners of visible items
+     * to set the value of the hidden day of year field.
+     */
+    setDOY: function() {
+        var panel = this.up('panel');
+        var month = panel.down('combobox').getValue();
+        var day = panel.down('numberfield[hidden=false]').getValue();
+        var maxDay = panel.down('numberfield[hidden=false]').maxValue;
+
+        if (month != null && day != null && day <= maxDay) {
+            // create a date object with arbitrary non-leap year
+            var date = new Date(1970, month, day);
+            var doy = Ext.Date.getDayOfYear(date);
+            panel.down('numberfield[hidden]').setValue(doy);
+        }
+    },
+
+    /*
+     * Call from listener of month selection widget to set maximum and
+     * validate associated day value.
+     */
+    checkMaxDay: function() {
+        this.up('panel').down('numberfield[hidden=false]')
+            .clearInvalid();
+
+        // create a date object with arbitrary non-leap year
+        var maxDay = Ext.Date.getDaysInMonth(
+            new Date(1970, this.getValue()));
+        this.up('panel').down('numberfield[hidden=false]')
+            .setMaxValue(maxDay);
+
+        var curDay = this.up('panel')
+            .down('numberfield[hidden=false]').getValue();
+        if (curDay > maxDay) {
+            this.up('panel').down('numberfield[hidden=false]')
+                .setValue(maxDay);
+        }
+    },
+
+
+    showWarnings: function(warnings) {
+        var img = this.down('image[name=warnImg]');
+        Ext.create('Ext.tip.ToolTip', {
+            target: img.getEl(),
+            html: warnings
+        });
+        img.show();
+        this.down('numberfield[hidden=false]').invalidCls = 'x-lada-warning';
+        this.down('numberfield[hidden=false]').markInvalid('');
+        this.down('combobox').markInvalid('');
+        var fieldset = this.up('fieldset[collapsible=true]');
+        if (fieldset) {
+            var i18n = Lada.getApplication().bundle;
+            var warningText = i18n.getMsg(this.name) + ': ' + warnings;
+            fieldset.showWarningOrError(true, warningText);
+        }
+    },
+
+    showErrors: function(errors) {
+        var img = this.down('image[name=errorImg]');
+        var warnImg = this.down('image[name=warnImg]');
+        warnImg.hide();
+        Ext.create('Ext.tip.ToolTip', {
+            target: img.getEl(),
+            html: errors
+        });
+        this.down('numberfield[hidden=false]').invalidCls = 'x-lada-error';
+        this.down('numberfield[hidden=false]').markInvalid('');
+        this.down('combobox').markInvalid('');
+        img.show();
+        var fieldset = this.up('fieldset[collapsible=true]');
+        if (fieldset) {
+            var i18n = Lada.getApplication().bundle;
+            var errorText = i18n.getMsg(this.name) + ': ' + errors;
+            fieldset.showWarningOrError(false, '', true, errorText);
+        }
+    },
+
+    clearWarningOrError: function() {
+        this.down('image[name=errorImg]').hide();
+        this.down('image[name=warnImg]').hide();
+    },
+
+    getValue: function() {
+        this.down('numberfield[hidden]').getValue();
+    },
+
+    setValue: function(value) {
+        this.down('numberfield[hidden]').setValue(value);
+    }
+});

http://lada.wald.intevation.org