This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git

commit 874ebb4f2c04370ba6b053291482fe00fa67db9b
Author: Marcus Christie <[email protected]>
AuthorDate: Mon Apr 23 13:02:47 2018 -0400

    AIRAVATA-2611 Exp input editors validate value and dispatch events
---
 .../django_airavata_api/js/models/Experiment.js    | 13 -------
 .../js/models/InputDataObjectType.js               |  5 ++-
 .../js/components/experiment/ExperimentEditor.vue  | 40 ++++++++++----------
 .../experiment/input-editors/FileInputEditor.vue   | 44 ++++++++++++++++++++--
 .../experiment/input-editors/StringInputEditor.vue | 44 ++++++++++++++++++++--
 5 files changed, 104 insertions(+), 42 deletions(-)

diff --git 
a/django_airavata/apps/api/static/django_airavata_api/js/models/Experiment.js 
b/django_airavata/apps/api/static/django_airavata_api/js/models/Experiment.js
index 90e6637..d45637e 100644
--- 
a/django_airavata/apps/api/static/django_airavata_api/js/models/Experiment.js
+++ 
b/django_airavata/apps/api/static/django_airavata_api/js/models/Experiment.js
@@ -74,19 +74,6 @@ export default class Experiment extends BaseModel {
 
     validate() {
         let validationResults = {};
-        const experimentInputsValidation = this.experimentInputs
-            .map(experimentInput => {
-                const validation = experimentInput.validate();
-                if (validation && 'value' in validation) {
-                    return {[experimentInput.name]: validation};
-                } else {
-                    return null;
-                }
-            })
-            .reduce((accumulator, currentValue) => Object.assign(accumulator, 
currentValue), {});
-        if (Object.keys(experimentInputsValidation).length > 0) {
-            validationResults['experimentInputs'] = experimentInputsValidation;
-        }
         const userConfigurationDataValidation = 
this.userConfigurationData.validate();
         if (Object.keys(userConfigurationDataValidation).length > 0) {
             validationResults['userConfigurationData'] = 
userConfigurationDataValidation;
diff --git 
a/django_airavata/apps/api/static/django_airavata_api/js/models/InputDataObjectType.js
 
b/django_airavata/apps/api/static/django_airavata_api/js/models/InputDataObjectType.js
index dfe2846..eb5407b 100644
--- 
a/django_airavata/apps/api/static/django_airavata_api/js/models/InputDataObjectType.js
+++ 
b/django_airavata/apps/api/static/django_airavata_api/js/models/InputDataObjectType.js
@@ -26,9 +26,10 @@ export default class InputDataObjectType extends BaseModel {
         super(FIELDS, data);
     }
 
-    validate() {
+    validate(experiment, value = undefined) {
+        let inputValue = typeof value != 'undefined' ? value : this.value;
         let results = {};
-        if (this.isRequired && this.isEmpty(this.value)) {
+        if (this.isRequired && this.isEmpty(inputValue)) {
             results['value'] = 'This field is required.';
         }
         return results;
diff --git 
a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentEditor.vue
 
b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentEditor.vue
index 29be831..94a8d44 100644
--- 
a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentEditor.vue
+++ 
b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentEditor.vue
@@ -55,7 +55,9 @@
                                 :experiment="localExperiment"
                                 :experiment-input="experimentInput"
                                 v-model="experimentInput.value"
-                                :key="experimentInput.name"/>
+                                :key="experimentInput.name"
+                                
@invalid="recordInvalidInputEditorValue(experimentInput.name)"
+                                
@valid="recordValidInputEditorValue(experimentInput.name)"/>
                         </div>
                     </div>
                 </div>
@@ -122,6 +124,7 @@ export default {
         return {
             projects: [],
             localExperiment: this.experiment.clone(),
+            invalidInputs: [],
         }
     },
     components: {
@@ -141,9 +144,12 @@ export default {
                 text: project.name,
             }));
         },
-        isSaveDisabled: function() {
+        valid: function() {
             const validation = this.localExperiment.validate();
-            return Object.keys(validation).length > 0;
+            return Object.keys(validation).length === 0 && 
this.invalidInputs.length === 0;
+        },
+        isSaveDisabled: function() {
+            return !this.valid;
         },
     },
     methods: {
@@ -192,21 +198,6 @@ export default {
             });
             return Promise.all(uploads);
         },
-        getApplicationInputState: function(applicationInput) {
-            const validation = 
this.getApplicationInputValidation(applicationInput);
-            return validation !== null ? 'invalid' : null;
-        },
-        getApplicationInputFeedback: function(applicationInput) {
-            const validation = 
this.getApplicationInputValidation(applicationInput);
-            return validation !== null ? validation['value'] : null;
-        },
-        getApplicationInputValidation: function(applicationInput) {
-            const validationResults = applicationInput.validate();
-            if (validationResults !== null && 'value' in validationResults) {
-                return validationResults;
-            }
-            return null;
-        },
         getValidationFeedback: function(properties) {
             return utils.getProperty(this.localExperiment.validate(), 
properties);
         },
@@ -221,7 +212,18 @@ export default {
             }
             // Default
             return 'string-input-editor';
-        }
+        },
+        recordInvalidInputEditorValue: function(experimentInputName) {
+            if (!this.invalidInputs.includes(experimentInputName)) {
+                this.invalidInputs.push(experimentInputName);
+            }
+        },
+        recordValidInputEditorValue: function(experimentInputName) {
+            if (this.invalidInputs.includes(experimentInputName)) {
+                const index = this.invalidInputs.indexOf(experimentInputName);
+                this.invalidInputs.splice(index, 1);
+            }
+        },
     },
     watch: {
         experiment: function(newValue) {
diff --git 
a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/FileInputEditor.vue
 
b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/FileInputEditor.vue
index 2d5dbeb..4efa9b1 100644
--- 
a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/FileInputEditor.vue
+++ 
b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/FileInputEditor.vue
@@ -1,8 +1,10 @@
 <template>
-    <b-form-group :label="experimentInput.name" 
:label-for="experimentInput.name">
-        <b-form-file :id="experimentInput.name" v-model="data" required
+    <b-form-group :label="experimentInput.name" 
:label-for="experimentInput.name"
+        :feedback="validationFeedback" :state="validationState">
+        <b-form-file :id="experimentInput.name" v-model="data"
             :placeholder="experimentInput.userFriendlyDescription"
-            @input="emitValueChanged"/>
+            :state="validationState"
+            @input="valueChanged"/>
     </b-form-group>
 </template>
 
@@ -26,12 +28,46 @@ export default {
     data () {
         return {
             data: this.value,
+            inputHasBegun: false,
         }
     },
+    computed: {
+        validationResults: function() {
+            return this.experimentInput.validate(this.experiment, this.data);
+        },
+        valid: function() {
+            return Object.keys(this.validationResults).length === 0;
+        },
+        validationFeedback: function() {
+            // Only display validation feedback after the user has provided
+            // input so that missing required value errors are only displayed
+            // after interacting with the input editor
+            return this.inputHasBegun && 'value' in this.validationResults
+                ? this.validationResults['value']
+                : null;
+        },
+        validationState: function() {
+            return this.inputHasBegun && 'value' in this.validationResults
+                ? 'invalid'
+                : null;
+        },
+    },
     methods: {
-        emitValueChanged: function() {
+        valueChanged: function() {
+            this.inputHasBegun = true;
             this.$emit('input', this.data);
+            this.checkValidation();
         },
+        checkValidation: function() {
+            if (this.valid) {
+                this.$emit('valid');
+            } else {
+                this.$emit('invalid');
+            }
+        }
     },
+    mounted: function() {
+        this.checkValidation();
+    }
 }
 </script>
diff --git 
a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/StringInputEditor.vue
 
b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/StringInputEditor.vue
index 27628b0..4a3a96a 100644
--- 
a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/StringInputEditor.vue
+++ 
b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/StringInputEditor.vue
@@ -1,8 +1,10 @@
 <template>
-    <b-form-group :label="experimentInput.name" 
:label-for="experimentInput.name">
-        <b-form-input :id="experimentInput.name" type="text" v-model="data" 
required
+    <b-form-group :label="experimentInput.name" 
:label-for="experimentInput.name"
+        :feedback="validationFeedback" :state="validationState">
+        <b-form-input :id="experimentInput.name" type="text" v-model="data"
             :placeholder="experimentInput.userFriendlyDescription"
-            @input="emitValueChanged"/>
+            :state="validationState"
+            @input="valueChanged"/>
     </b-form-group>
 </template>
 
@@ -27,12 +29,46 @@ export default {
     data () {
         return {
             data: this.value,
+            inputHasBegun: false,
         }
     },
+    computed: {
+        validationResults: function() {
+            return this.experimentInput.validate(this.experiment, this.data);
+        },
+        valid: function() {
+            return Object.keys(this.validationResults).length === 0;
+        },
+        validationFeedback: function() {
+            // Only display validation feedback after the user has provided
+            // input so that missing required value errors are only displayed
+            // after interacting with the input editor
+            return this.inputHasBegun && 'value' in this.validationResults
+                ? this.validationResults['value']
+                : null;
+        },
+        validationState: function() {
+            return this.inputHasBegun && 'value' in this.validationResults
+                ? 'invalid'
+                : null;
+        },
+    },
     methods: {
-        emitValueChanged: function() {
+        valueChanged: function() {
+            this.inputHasBegun = true;
             this.$emit('input', this.data);
+            this.checkValidation();
         },
+        checkValidation: function() {
+            if (this.valid) {
+                this.$emit('valid');
+            } else {
+                this.$emit('invalid');
+            }
+        }
     },
+    mounted: function() {
+        this.checkValidation();
+    }
 }
 </script>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to