Vee-validate: Possibility to defer validation until blur?

Created on 4 May 2017  ·  9Comments  ·  Source: logaretm/vee-validate

Thx. for the great lib.

Would you consider (or is it already possible) to configure vee-validate in such a way that the validation will be performed on-blur instead of immediately (or after delay) ??. IMHO the user should not get any validation-errors until he actually leaves a field.

Best, Carsten

✨ enhancement ❔ question

Most helpful comment

I see that this is sitll not implemented, or at least I did not find how to achieve it.
I tried with data-vv-validate-on="blur" but this disables the ability to validate when the input becomes valid (for example, when typing email).
So the best result would be, as with angular, if the field has not been touched, show error only when the user blurs it. If it has been touched validate always at every event.

All 9 comments

If you are binding your inputs with your models via v-model you can use the v-model.lazy modifier which should trigger the validation less frequently.

In general the only way to do it is to specify data-vv-validate-on on each input, which is very verbose, I will try to add a global config to set the behavior without much hassle.

custom input components will be excluded from this behavior tho.

I see that this is sitll not implemented, or at least I did not find how to achieve it.
I tried with data-vv-validate-on="blur" but this disables the ability to validate when the input becomes valid (for example, when typing email).
So the best result would be, as with angular, if the field has not been touched, show error only when the user blurs it. If it has been touched validate always at every event.

@knaos See https://github.com/baianat/vee-validate/issues/1146

Example:

errors.has('email') && fields.email.touched

I even prever to use the dirty flag, since I find it pretty annoying that when the user only just tabs through the fields it gets the validation messages already.
So I now mostly use the following:

v-show="fields.email && fields.email.dirty && errors.has('email')"

(where _email_ is depending on your field ^^ )

or (if you have a generic InputField component):

v-show="fields[name] && fields[name].dirty && errors.has(name)"

Link to all the flags documentation


But I can see what @knaos is asking for. It would be great to have some kind of validationCallback possibility or something. So we can adjust the validation-rules based on if the field is touched and/or was previously valid. I can imagine a situation where you don't want to validate the email address immediately ... but after the blur it validates. But when the user then adjusts the email address, from that moment on, it should validate on keydown

When input and it's error message are made in one component (as it should be imho) it's easy to watch focus/blur events.
Take a look on fast made example on codesandbox, open Basic.vue.

this.errors.has('email') && ((this.fields.email.untouched && !this.fields.email.dirty) || (this.fields.email.touched && this.fields.email.dirty))

Validate field after first change of field and if validateAll();

this.errors.has('email') && ((this.fields.email.untouched && !this.fields.email.dirty && this.fields.email.validated) || (this.fields.email.touched && (this.fields.email.dirty || this.fields.email.validated)));

This condition work for me well

Why not like this? It will throw the error only if v-model value is entered and there is no focus on the field.
Not a native vee-validate approach but I believe it works pretty well...

<template>
<ValidationProvider
:rules="required"
v-slot="{ errors, valid, invalid, pristine }">

    <input
    @focus='focus = true' 
    @focusout='focus = false' 
    v-model="value"
    type="text" />
    <small
    v-if='errors[0] && value != "" && !focus'
    :class="errorClasses">{{ errors[0] }}</small>

</ValidationProvider>
</template>
<script>
export default {
  name: "form-input",
  data: () => ({
    focus: false,
    value: ""
  })
}
</script>
Was this page helpful?
0 / 5 - 0 ratings