ValidationProvider need to validate after submit Vue 2 - vue.js

I am using ValidationObserver and ValidationProvider for validating the email field.
<ValidationProvider
name="email"
rules="required|max:50|email"
v-slot="{ errors }"
>
<md-field
class="border-round-10 border_box"
:class="{ 'md-invalid': errors.length > 0 }"
>
<label>Email </label>
<md-input
v-model="email"
#blur="greatToSeeYou()"
></md-input>
<span class="md-error">{{ errors[0] }}</span>
</md-field>
</ValidationProvider>
I want to validate the email only after the submit button. I tried so many options but didn't work.

There is 4 modes to configure ValidationProvider: aggressive, lazy, eager and passive.
From your requirement, you would like to validate the form on submission only so you can choose passive mode
<ValidationProvider
name="email"
rules="required|max:50|email"
v-slot="{ errors }"
mode="passive"
>
...
</ValidationProvider>
Here is the codesandbox example I made for your reference:
https://codesandbox.io/s/kind-breeze-rbf27?file=/src/components/HelloWorld.vue:146-293

Related

Vee-validate - [Vue warn]: Failed to resolve directive: validate

I want to validate text fields, trying below code :
<input v-validate="result.val=='Required' ? 'required' : ''" v-model="required" :name="f_name" type="text"/>
but getting this error:
app.js:48089 [Vue warn]: Failed to resolve directive: validate
Trying this:
<ValidationProvider name="phone" :rules="required" v-slot="{ errors }">
<input class="form-control" :name="phone" type="text" v-model="form.phone"/>
</ValidationProvider>
According to the migration guide this directive is removed in v3.x :
Fields that had the v-validate directive needs to be wrapped by ValidationProvider component now, and they need to use v-model to properly tag themselves for vee-validate.
So this:
<input type="text" name="field" v-validate="'required'">
<span>{{ errors.first('field') }}</span>
Will be re-written as this:
<ValidationProvider name="field" rules="required" v-slot="{ errors }">
<input type="text" v-model="value">
<span>{{ errors[0] }}</span>
</ValidationProvider>
Your code should be like :
<ValidationProvider name="f_name" :rules="result.val=='Required' ? 'required' : ''" v-slot="{ errors }">
<input v-model="required" :name="f_name" type="text"/>
</ValidationProvider>
You should add this to main.js :
import { ValidationProvider } from 'vee-validate';
Vue.component('ValidationProvider', ValidationProvider);
If you are not using a bundler and using vee-validate in the browser or from a CDN:
<script>
// ...
Vue.component('validation-provider', VeeValidate.ValidationProvider);
// ...
</script>

Vee Validate 3.0 custom classes not applied

From the docs, I think I need to use configure to add custom classes to my validated fields, but I can't get it to work.
This is what I have so far...
import { extend, configure, localize } from 'vee-validate'
import { required, min, max } from 'vee-validate/dist/rules'
import en from 'vee-validate/dist/locale/en.json'
// Install rules
extend('required', required)
extend('min', min)
extend('max', max)
// Install classes
configure({
classes: {
valid: 'is-valid',
invalid: 'is-invalid'
}
})
// Install messages
localize({
en
})
And in my view....
<ValidationObserver ref="observer" v-slot="{ invalid }" tag="form" #submit.prevent="checkRef()">
<div class="form-group">
<label for="reference">Reference</label>
<ValidationProvider rules="required|max:20" name="reference" v-slot="{ errors }">
<input maxlength="20" name="reference" v-model="ref" id="reference" class="form-control"/>
<span class="warning">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<button #click="checkRef" class="btn btn-primary app-button">Check Reference</button>
</ValidationObserver>
When I click the button, I see the error message but I don't get the 'in-invalid' class applied to my field.
What am I doing wrong?
VeeValidate does not apply the classes automatically anymore, since v3 you now must bind it yourself. Like errors you can extract classes from the slot props and apply it to your input:
<ValidationProvider rules="required|max:20" name="reference" v-slot="{ errors, classes }">
<input maxlength="20" name="reference" v-model="ref" id="reference" class="form-control" :class="classes" />
<span class="warning">{{ errors[0] }}</span>
</ValidationProvider>

v-select validate not working in Internet Explorer 11

Good day, how can i make v-select validate work on IE 11?
i added require('es6-promise').polyfill(); on my vue script but till i encounter error Failed to generate render function.
<v-select :options="books" label="title" v-model="selected">
<template #search="{attributes, events}">
<input
class="vs__search"
:required="!selected"
v-bind="attributes"
v-on="events"
/>
</template>
</v-select>
Solve by accessing the slot directly and binding the required attributes
<v-select :options="books" label="title" v-model="selected">
<template #search="{attributes, events}">
<input :required="!selected" aria-label="Search for option" role="combobox" type="search" autocomplete="off" class="vs__search">
</template>
</v-select>

vee-validate not working with bootstrap-vue

I'm trying to use vee-validate for form validation with bootstrap-vue, and cannot get anything to work. Basically, I want to do:
<b-form-input v-model="emailText"
placeholder="Enter email"
v-validate="'required|email'"
name="email"
type="text">
<b-row>
<span>{{ errors.first('email') }}</span>
</b-row>
</b-form-input>
But I don't see anything when I type a non-email address in the field. However, if I change:
b-form-input to input
then everything works. Is there a workaround for this behavior? Any help would be greatly appreciated.
You have put the error messages inside the <b-form-input>, which has no internal slot, so the error messages aren't rendered. If you move them to after the input, it should fix your issue:
<b-form-input v-model="emailText"
placeholder="Enter email"
v-validate="'required|email'"
name="email"
type="text">
</b-form-input>
<b-row>
<span>{{ errors.first('email') }}</span>
</b-row>
You can also use Bootstrap-Vue's state and invalid-feedback properties on the <b-form-input> and a surrounding <b-form-group> to display validation errors with a better accessibility. All of this is demonstrated in this codepen

vee validate "required" validation is working only when on change of the field

Below is my code. Three fields are there in my form. Firstname, Middlename, Lastname. All these fields are set as required one. Only difference is that "Firstname & Lastname" contains input tag, but "Middlename" contains b-form-input tag. Actually my problem is, When I focus out(blur) these("Firstname & Lastname") fields it throws an required error but when I do the same for ("Middlename") field it doesn't Image1. I have to enter the value in that ("Middlename") field Image2 ,then I removed the value it's throwing error
Image3 i.e. required validation is only working "on change" of the "("Middlename") field. What is the reason for this?
<template>
<b-card>
<h4 slot="header" class="card-title">Employee</h4>
<b-row>
<b-col sm="3">
<b-form-group>
<label for="name">First Name </label>
<input type="text" id="" class="form-control" placeholder="Enter your name" v-validate="'required'" name="Firstname">
<span v-show="errors.has('Firstname')" class="is-danger">{{ errors.first('Firstname') }}</span>
</b-form-group>
</b-col>
<b-col sm="3">
<b-form-group>
<label for="name">Middle Name </label>
<b-form-input type="text" id="" class="form-control" placeholder="Enter your name" v-validate="'required'" name="Middlename"> </b-form-input>
<span v-show="errors.has('Middlename')" class="help is-danger">{{ errors.first('Middlename') }}</span>
</b-form-group>
</b-col>
<b-col sm="3">
<b-form-group>
<label for="name">Last Name </label>
<input type="text" id="" class="form-control" placeholder="Enter your middle name" v-validate="'required|Name'" name="Lastname">
<span v-show="errors.has('Lastname')" class="help is-danger">{{ errors.first('Lastname') }}</span>
</b-form-group>
</b-col>
</b-row>
<input type="submit" value="Submit" #click="validateForm">
</b-card>
</template>
<script>
import Vue from 'vue'
import VeeValidate from 'vee-validate';
Vue.use(VeeValidate);
export default {
name: 'addEmpl',
created: function() {
this.$validator.extend('Name', {
getMessage: field => '* Enter valid ' + field + '',
validate: value => /^[a-zA-Z]*$/.test(value)
});
}
}
</script>
<style lang="scss" scoped>
.is-danger{
color: RED;
}
</style>
First of all, I am also new to Vue.js and Vee-validate so I stand corrected.
The difference between the 2 fields and the middlename field is that it is a component instead of native input field.
In essence, you need to make the component behaves like an input, i.e. emits the necessary events so Vee-validate can pick up on them ('input', 'change', 'blur' etc).
For e.g if your component is a div wrapping on input it would be something like this:
<template>
<div class="myClassForDiv">
<input
type="text"
class="myClass"
#blur="$emit('blur')"
#input="$emit('input', $event.target.value)"
>
</div>
</template>
<script>
export default {
name: "b-form-input"
}
</script>
The part relevant to the question is #blur="$emit('blur')". Without this line, VeeValidate has no way of getting notified of a blur event occurring hence does not validate (I don't know what other events VeeValidate listens to by default, but 'blur' works for me and 'focusout' does not. You can always use the data-vv-validate-on directive for special events specific to your components).
You may refer to the this article by the maintainer of VeeValidate library. Notice how he creates a component that plays nicely with VeeValidate by making the component emits all the right events.
https://medium.com/#logaretm/authoring-validatable-custom-vue-input-components-1583fcc68314