I have the following form built with Bootstrap-Vue, which has a bit of Vuelidation code applied to it.
<b-form @submit.prevent="onSubmit">
<input type="hidden" name="_token" :value="csrf" />
<transition-group name="fade">
<b-form-select
:class="{ 'hasError': $v.form.dobDate.$error }"
class="mb-3"
name="dobDate"
id="dobDate"
v-model.lazy="$v.form.dobDate.$model"
:options="optionsDays"
v-if="isSixteen"
key="dobDateSelect"
>
<template slot="first">
<option value disabled>Please select a date</option>
</template>
</b-form-select>
</transition-group>
<transition-group name="fade">
<b-form-select
:class="{ 'hasError': $v.form.dobMonth.$error }"
class="mb-3"
name="dobMonth"
id="dobMonth"
v-model.lazy="$v.form.dobMonth.$model"
:options="optionsMonths"
v-if="isSixteen"
value="optionsMonths.key"
key="dobMonthSelect"
>
<template slot="first">
<option value disabled>Please select a Month</option>
</template>
</b-form-select>
</transition-group>
<b-alert
show
variant="danger"
class="error"
v-if="!$v.form.dobYear.required"
>This field is required</b-alert>
<b-alert
show
variant="danger"
class="error"
v-if="!$v.form.dobYear.minLength"
>Field must have at least {{ $v.form.dobYear.$params.minLength.min }} characters.</b-alert>
<b-alert class="error" v-if="!$v.form.dobYear.numeric">Please enter a valid year of birth</b-alert>
<b-alert show variant="danger" v-if="belowSixteen">You are underage</b-alert>
<b-form-input
:class="{ 'hasError': $v.form.dobYear.$error }"
placeholder="Year of Birth"
v-model="form.dobYear"
@blur="$v.form.dobYear.$touch()"
autofocus
class="form-control mb-3"
name="year"
id="year"
maxlength="4"
@keyup="checkAge"
></b-form-input>
<b-button
class="btn btn-lg btn-primary btn-block"
type="submit"
variant="primary"
:disabled="$v.$invalid||belowSixteen"
>Submit</b-button>
<b-alert
show
variant="danger"
v-if="belowSixteen"
class="error mt-3"
>Sorry you have to be over 16 to play</b-alert>
</b-form>
But currently I am getting immediate feedback when the page loads which can be jarring for the user. Instead I want the errors to show when the user has finished with the input/select.
I have tried using @blur="$v.form.dobYear.$touch()" however it doesn't seem to work at all. What am I doing wrong?
Here is a snipper of how my validations look like in my script currently:
validations: {
form: {
dobYear: {
required,
minLength: minLength(4),
maxLength: maxLength(4),
numeric
},
dobMonth: {
required: requiredIf(function() {
return this.isSixteen;
})
},
dobDate: {
required: requiredIf(function() {
return this.isSixteen;
})
}
}
}
I have the following form built with Bootstrap-Vue, which has a bit of Vuelidation code applied to it.
<b-form @submit.prevent="onSubmit">
<input type="hidden" name="_token" :value="csrf" />
<transition-group name="fade">
<b-form-select
:class="{ 'hasError': $v.form.dobDate.$error }"
class="mb-3"
name="dobDate"
id="dobDate"
v-model.lazy="$v.form.dobDate.$model"
:options="optionsDays"
v-if="isSixteen"
key="dobDateSelect"
>
<template slot="first">
<option value disabled>Please select a date</option>
</template>
</b-form-select>
</transition-group>
<transition-group name="fade">
<b-form-select
:class="{ 'hasError': $v.form.dobMonth.$error }"
class="mb-3"
name="dobMonth"
id="dobMonth"
v-model.lazy="$v.form.dobMonth.$model"
:options="optionsMonths"
v-if="isSixteen"
value="optionsMonths.key"
key="dobMonthSelect"
>
<template slot="first">
<option value disabled>Please select a Month</option>
</template>
</b-form-select>
</transition-group>
<b-alert
show
variant="danger"
class="error"
v-if="!$v.form.dobYear.required"
>This field is required</b-alert>
<b-alert
show
variant="danger"
class="error"
v-if="!$v.form.dobYear.minLength"
>Field must have at least {{ $v.form.dobYear.$params.minLength.min }} characters.</b-alert>
<b-alert class="error" v-if="!$v.form.dobYear.numeric">Please enter a valid year of birth</b-alert>
<b-alert show variant="danger" v-if="belowSixteen">You are underage</b-alert>
<b-form-input
:class="{ 'hasError': $v.form.dobYear.$error }"
placeholder="Year of Birth"
v-model="form.dobYear"
@blur="$v.form.dobYear.$touch()"
autofocus
class="form-control mb-3"
name="year"
id="year"
maxlength="4"
@keyup="checkAge"
></b-form-input>
<b-button
class="btn btn-lg btn-primary btn-block"
type="submit"
variant="primary"
:disabled="$v.$invalid||belowSixteen"
>Submit</b-button>
<b-alert
show
variant="danger"
v-if="belowSixteen"
class="error mt-3"
>Sorry you have to be over 16 to play</b-alert>
</b-form>
But currently I am getting immediate feedback when the page loads which can be jarring for the user. Instead I want the errors to show when the user has finished with the input/select.
I have tried using @blur="$v.form.dobYear.$touch()" however it doesn't seem to work at all. What am I doing wrong?
Here is a snipper of how my validations look like in my script currently:
validations: {
form: {
dobYear: {
required,
minLength: minLength(4),
maxLength: maxLength(4),
numeric
},
dobMonth: {
required: requiredIf(function() {
return this.isSixteen;
})
},
dobDate: {
required: requiredIf(function() {
return this.isSixteen;
})
}
}
}
Share
Improve this question
asked Sep 4, 2019 at 10:08
ImranRImranR
5163 gold badges13 silver badges31 bronze badges
6
-
Have you tried to use a
@click
-Function on yoursubmit
-Button? It only get's triggered when theuser
finished his input and you could simply set your code:this.$v.form.dobYear.$touch()
in there. – Matthias Commented Sep 4, 2019 at 20:58 -
Or listen for the
@submit
event on the form – Troy Morehouse Commented Sep 4, 2019 at 21:44 - 1 Have you solved this issue? Please add an answer with your solution. I'm struggling with this right now... – mattelacchiato Commented Jul 15, 2020 at 13:57
- @mattelacchiato sorry it's been a while since I used vuelidate. I briefly remember using $touch() like the first example in the ments...essentially what I did was put a few seconds delay before the validation message is shown. This gives the user some time to finish typing. Otherwise the only other option I could think of at the time was to trigger only when the submit button is clicked on but that doesn't feel so 'reactive'. – ImranR Commented Jul 16, 2020 at 14:32
- @mattelacchiato I just took a look at the old source code I used. So it looks like I used the delayTouch method for Vuelidate, and I waited 15000 mili seconds for user input to end. See the example on the vuelidate website, just search for 'delaytouch' vuelidate.js/#sub-delayed-validation-errors – ImranR Commented Jul 16, 2020 at 14:35
2 Answers
Reset to default 1Calling $touch()
in blur
event is right. But you could use little bit different logic with state
attribute given from bootstrap-vue. You could find more detail from here Form input [contextual states]
eg:
<b-form-input
v-model="form.name"
type="text"
@blur="$v.form.name.$touch()"
:state="$v.form.name.$dirty ? !$v.form.name.$anyError : null"
/>
<b-form-invalid-feedback :state="$v.form.name.$dirty ? !$v.form.name.$anyError : null" >
Some kind of invalid feedback Message here
</b-form-invalid-feedback>
And out of curiosity why you use v-model
with validation model like shown below.
v-model.lazy="$v.form.dobMonth.$model"
Isn't it just okay for use v-model
with data()
like shown below?
v-model.lazy="form.dobMonth"
You can wrap it as follows:
<div v-if="$v.email.$dirty">
<b-alert
show
variant="danger"
class="error"
v-if="!$v.form.dobYear.required"
>This field is required</b-alert>
<b-alert
show
variant="danger"
class="error"
v-if="!$v.form.dobYear.minLength"
>Field must have at least {{ $v.form.dobYear.$params.minLength.min }} characters.</b-alert>
<b-alert class="error" v-if="!$v.form.dobYear.numeric">Please enter a valid year of birth</b-alert>
<b-alert show variant="danger" v-if="belowSixteen">You are underage</b-alert></div>
Know more