Skip to content

Commit

Permalink
Input Range from input is not valid when is not required and not valu…
Browse files Browse the repository at this point in the history
…e is set (#658)

* 🐛 Fix validation of input not required

* avoid nested `if-else`

* 🐛 Fix validation of input not required and empty

* Add conversion value of state  value to compare with values from server

* Comment

* force add options values array in case validate.unique

* Simplify checkbox

* Fix validation of exlude_value fro this.state.validate.unique general

* Change behavior of input unique widget

* Set always empty values array in case if not provided by server configuration

* Remove from current list of unique values, the old value

* Editing add new value. No need to remove initial value. It could be usefull maintain it to remember during changes

---------

Co-authored-by: Raruto <[email protected]>
(cherry picked from commit 67fc2fe)
  • Loading branch information
volterra79 authored and github-actions[bot] committed Sep 17, 2024
1 parent ff64e5d commit 468c73e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 48 deletions.
20 changes: 11 additions & 9 deletions src/app/core/layers/tablelayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -615,12 +615,6 @@ proto.getFieldsWithValues = function(obj, options = {}) {
field._value = attributes[field.name]; // store original value
field.update = false; // at beginning set update false. Used to form

if (field.input) {
const options = this.getEditingFields().find(f => f.name === field.name).input.options;
field.input.options.loading = options.loading || { state: null };
field.input.options.values = options.values;
}

field.visible = exclude.indexOf(field.name) === -1; // exclude contain field to set visible false

// for editing purpose
Expand All @@ -631,14 +625,22 @@ proto.getFieldsWithValues = function(obj, options = {}) {
field.forceNull = false;
field.validate.valid = true;
field.validate._valid = true; // useful to get previous value in certain case
field.value_from_default_value = false; // need to be check if default value is set by server configuration field
field.get_default_value = get_default_value; // specify if need to get value from form field.input.options.default value in case of missing value of field.value
field.value_from_default_value = false; // need to be checked if the default value is set by server configuration field
field.get_default_value = get_default_value; // specify if you need to get value from form field.input.options.default value in case of missing value of field.value
field.validate.exclude_values = new Set(); // for validate.unique purpose to check is new value iserted or change need to be di
field.validate.unique = field.validate.unique || false;
field.validate.required = field.validate.required || false;
field.validate.mutually_valid = true;
field.validate.empty = !field.validate.required;
field.validate.empty = false; // Mean no value (field.value) set start value to false. It will be set once the input field is show
field.validate.message = null;

if (field.input) {
const options = this.getEditingFields().find(f => f.name === field.name).input.options;
field.input.options.loading = options.loading || { state: null };
//check if value is defined otherwise set empty array (e.g required for field.validate unique)
field.input.options.values = options.values || [];
}

});

return fields;
Expand Down
29 changes: 18 additions & 11 deletions src/app/gui/inputs/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,35 +85,42 @@ proto.setValidator = function(validator) {
this._validator = validator;
};

proto.setEmpty = function(){
this.state.validate.empty = !((Array.isArray(this.state.value) && this.state.value.length) || !_.isEmpty(_.trim(this.state.value)));
/**
* set input empty '', null, undefined or []
*/
proto.setEmpty = function() {
this.state.validate.empty = !((Array.isArray(this.state.value) && this.state.value.length > 0) || !(_.isEmpty(_.trim(this.state.value))));
};

// the general method to check the value of the state is valid or not
proto.validate = function() {
if (this.state.validate.empty) {
this.state.validate.empty = true;
this.state.value = null;
this.state.validate.unique = true;
this.state.value = null; //force to null
// check if you require or check validation
this.state.validate.valid = this.state.validate.required ? false : this._validator.validate(this.state.value);
this.state.validate.valid = !this.state.validate.required;
} else {
if (['integer', 'float'].includes(this.state.input.type)) {
if (['integer', 'float', 'bigint'].includes(this.state.input.type)) {
if (+this.state.value < 0) {
this.state.value = null;
this.state.validate.empty = true;
this.state.validate.valid = !this.state.validate.required;
} else this.state.validate.valid = this._validator.validate(this.state.value);
} else {
this.state.validate.valid = this._validator.validate(this.state.value);
}
}
if (this.state.validate.exclude_values && this.state.validate.exclude_values.size) {
this.state.validate.valid = !this.state.validate.exclude_values.has(this.state.value);
//check exclude_values state.validate.unique (QGIS field property [x] Enforce unique constraint)
if (this.state.validate.unique && this.state.validate.exclude_values && this.state.validate.exclude_values.size) {
//need to convert this.state.value to string because editing store exclude_values items as string
this.state.validate.valid = !this.state.validate.exclude_values.has(`${this.state.value}`);
} else {
this.state.validate.valid = this._validator.validate(this.state.value);
}
}

return this.state.validate.valid;
};


proto.setErrorMessage = function() {
//in vase of
if (this.state.validate.error) {
Expand All @@ -127,7 +134,7 @@ proto.setErrorMessage = function() {
this.state.validate.message = `${t("sdk.form.inputs.input_validation_max_field")} (${this.state.validate.max_field})`;
} else if (this.state.validate.min_field) {
this.state.validate.message = `${t("sdk.form.inputs.input_validation_min_field")} (${this.state.validate.min_field})`;
} else if (this.state.validate.unique && this.state.validate.exclude_values && this.state.validate.exclude_values.size) {
} else if (('unique' === this.state.input.type || this.state.validate.unique) && this.state.validate.exclude_values && this.state.validate.exclude_values.size) {
this.state.validate.message = `${t("sdk.form.inputs.input_validation_exclude_values")}`;
} else if (this.state.validate.required) {
message = `${t("sdk.form.inputs.input_validation_error")} ( ${t("sdk.form.inputs." + this.state.type)} )`;
Expand Down
7 changes: 3 additions & 4 deletions src/components/InputCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,10 @@ export default {
this.setLabel();
}
},
created() {
this.value = this.state.forceNull ? this.value : this.service.convertValueToChecked();
},
mounted() {
if (!this.state.forceNull) this.setLabel();
if (this.state.forceNull) {
this.setLabel();
}
}
};
</script>
45 changes: 21 additions & 24 deletions src/components/InputUnique.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
-->

<template>
<baseinput :state="state">
<baseinput :state="state" v-disabled = "!editable">
<select
slot = "body"
:id = "id"
style = "width:100%"
:tabIndex = "tabIndex"
v-disabled = "!editable"
class = "form-control"
>
<option value = "null"></option>
Expand All @@ -33,33 +32,31 @@ export default {
/** @since 3.8.6 */
name: "input-unique",

mixins: [Input, selectMixin],
mixins: [ Input, selectMixin ],
data() {
const id = `unique_${getUniqueDomId()}`;
return {id}
},
watch: {
async 'state.input.options.values'(values) {
this.state.value = this.state.value ? this.state.value: null;
this.state.value !== null && values.indexOf(this.state.value) === -1 && this.service.addValueToValues(this.state.value);
await this.$nextTick();
this.state.value && this.select2.val(this.state.value).trigger('change');
}
return { id : `unique_${getUniqueDomId()}`}
},
async mounted() {
await this.$nextTick();
if (this.state.input.options.editable) {
this.select2 = $(`#${this.id}`).select2({
dropdownParent: $('#g3w-view-content'),
tags: true,
language: this.getLanguage()
});
this.select2 = $(`#${this.id}`).select2({
dropdownParent: $('#g3w-view-content'),
tags: this.state.input.options.editable,
language: this.getLanguage()
});
if (null !== this.state.value) {
this.select2.val(this.state.value).trigger('change');
this.select2.on('select2:select', event => {
const value = event.params.data.$value ? event.params.data.$value : event.params.data.id;
this.changeSelect(value);
})
}
}
this.select2.on('select2:select', async e => {
const value = e.params.data.$value ? e.params.data.$value : e.params.data.id;
this.state.value = 'null' === value ? null :
//need to check if values are Number or string and convert it to compare
//@TODO need to find a better way to comprare input value (from input html element) value is set as string
['integer', 'float', 'bigint'].includes(this.state.type) ? Number(value) : value;
//check if start value is changed
this.changeSelect(this.state.value);
await this.$nextTick();
})
},

};
</script>

0 comments on commit 468c73e

Please sign in to comment.