Added 'eager' validation to textbox-question component
This commit is contained in:
parent
3a3bbf738a
commit
b5aa014e85
1 changed files with 32 additions and 5 deletions
|
|
@ -1,8 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="textbox-question" :class="(errors && errors.length) || hasError ? 'has-error' : ''">
|
<div class="textbox-question" :class="(errors && errors.length) || hasError ? 'has-error' : ''">
|
||||||
<label :for="inputId" :aria-label="questionText" class="form-label" v-html="labelText"></label>
|
<label :for="inputId" :aria-label="questionText" class="form-label" v-html="labelText"></label>
|
||||||
<input v-model="value"
|
<input
|
||||||
|
v-on="validationListeners"
|
||||||
|
v-model="value"
|
||||||
v-maska="mask"
|
v-maska="mask"
|
||||||
|
|
||||||
:type="type"
|
:type="type"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
:ref="inputId"
|
:ref="inputId"
|
||||||
|
|
@ -14,9 +17,7 @@
|
||||||
:aria-required="isRequired"
|
:aria-required="isRequired"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
:class="[hasIcon ? 'has-icon' : '', iconRight ? 'icon-right' : '']"
|
:class="[hasIcon ? 'has-icon' : '', iconRight ? 'icon-right' : '']"
|
||||||
:validationRules="validationRules"
|
:validationRules="validationRules" />
|
||||||
@change="handleChange"
|
|
||||||
@blur="handleBlur" />
|
|
||||||
<div v-show="errorMessage" class="row mt-2 form-test-error">
|
<div v-show="errorMessage" class="row mt-2 form-test-error">
|
||||||
<span role="alert">{{ errorMessage }}</span>
|
<span role="alert">{{ errorMessage }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -24,7 +25,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue';
|
||||||
import { useField } from "vee-validate";
|
import { useField } from "vee-validate";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -57,6 +58,7 @@ export default {
|
||||||
const fieldOptions = {
|
const fieldOptions = {
|
||||||
type: "text",
|
type: "text",
|
||||||
value: props.modelValue,
|
value: props.modelValue,
|
||||||
|
validateOnValueUpdate: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
@ -68,6 +70,25 @@ export default {
|
||||||
errors,
|
errors,
|
||||||
} = useField(props.inputId, props.validationRules, fieldOptions);
|
} = useField(props.inputId, props.validationRules, fieldOptions);
|
||||||
|
|
||||||
|
const validationListeners = computed(() => {
|
||||||
|
// If the field is valid or have not been validated yet
|
||||||
|
// lazy
|
||||||
|
if (!errorMessage.value) {
|
||||||
|
return {
|
||||||
|
blur: handleChange,
|
||||||
|
change: handleChange,
|
||||||
|
// disable `shouldValidate` to avoid validating on input
|
||||||
|
input: e => handleChange(e, false),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// Aggressive
|
||||||
|
return {
|
||||||
|
blur: handleChange,
|
||||||
|
change: handleChange,
|
||||||
|
input: handleChange, // only switched this
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
errorMessage,
|
errorMessage,
|
||||||
handleBlur,
|
handleBlur,
|
||||||
|
|
@ -75,6 +96,7 @@ export default {
|
||||||
validate,
|
validate,
|
||||||
meta,
|
meta,
|
||||||
errors,
|
errors,
|
||||||
|
validationListeners
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -110,6 +132,11 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
value(newValue) {
|
||||||
|
this.handleChange(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue