Categories
Vue

Vuelidate — Errors and Lists Validation

Spread the love

Vue.js doesn’t come with any form validation capabilities by default.

Therefore, we need to add our own form validation library or with our own code.

In this article, we’ll look at how to validate forms with Vuelidate.

$error vs $anyError

We can get form validation errors with the $error and $anyError validation property.

$dirty and $anyDirty checks if the forms have been modified.

For example, we can write:

<template>
  <div id="app">
    <div>
      <div :class="{ 'form-group--error': $v.name.$error }">
        <label>name</label>
        <input v-model.trim="$v.name.$model">
        <div class="error" v-if="!$v.name.required">name is required.</div>
      </div>

<div :class="{ 'form-group--error': $v.age.$error }">
        <label>age</label>
        <input v-model.trim="$v.age.$model">
      </div>
      <div class="error" v-if="!$v.age.required">age is required.</div>
    </div>
  </div>
</template>
<script>
import { required } from "vuelidate/lib/validators";
export default {
  name: "App",
  data() {
    return {
      name: "",
      age: ""
    };
  },
  validations: {
    name: {
      required
    },
    age: {
      required
    }
  }
};
</script>

Then we gave the $v.age.$error and $v.name.$error properties to get the errors.

If they’re true , then the form-group--error class will be applied.

Validation Groups

We can create validation groups to validate all the form fields together.

For example, we can write:

<template>
  <div id="app">
    <div>
      <div :class="{ 'form-group--error': $v.name.$error }">
        <label>name</label>
        <input v-model.trim="$v.name.$model">
        <div class="error" v-if="!$v.name.required">name is required.</div>
      </div>

      <div :class="{ 'form-group--error': $v.age.$error }">
        <label>age</label>
        <input v-model.trim="$v.age.$model">
        <div class="error" v-if="!$v.age.required">age is required.</div>
      </div>

      <div :class="{ 'form-group--error': $v.phone.mobile.$error }">
        <label>mobile phone</label>
        <input v-model.trim="$v.phone.mobile.$model">
        <div class="error" v-if="!$v.phone.mobile.required">mobile phone is required.</div>
      </div>

<div v-if="$v.validationGroup.$error">group is invalid.</div>
    </div>
  </div>
</template>
<script>
import { required } from "vuelidate/lib/validators";
export default {
  name: "App",
  data() {
    return {
      name: "",
      age: "",
      phone: {
        mobile: ""
      }
    };
  },
  validations: {
    name: {
      required
    },
    age: {
      required
    },
    phone: {
      mobile: {
        required
      }
    },
    validationGroup: ["name", "age", "phone.mobile"]
  }
};
</script>

We added the validationGroup property in the validations property to add a validation group.

It has an array of strings with the property names.

If the property is nested, then the property is separated by a dot.

Then in the template, we get the $v.validationGroup.$error property to see if there’re any errors in the fields in the group.

Collections Validation

We can validate collections with the $each keyword.

For instance, we can write:

<template>
  <div id="app">
    <div v-for="(v, index) in $v.people.$each.$iter">
      <div class="form-group" :class="{ 'form-group--error': v.$error }">
        <label>Name</label>
        <input v-model.trim="v.name.$model">
      </div>
      <div v-if="!v.name.required">Name is required.</div>
      <div
        v-if="!v.name.minLength"
      >Name must have at least {{ v.name.$params.minLength.min }} letters.</div>
    </div>
    <div>
      <button class="button" [@click](http://twitter.com/click "Twitter profile for @click")="people.push({name: ''})">Add</button>
      <button class="button" [@click](http://twitter.com/click "Twitter profile for @click")="people.pop()">Remove</button>
    </div>
    <div class="form-group" :class="{ 'form-group--error': $v.people.$error }"></div>
    <div
      v-if="!$v.people.minLength"
    >List must have at least {{ $v.people.$params.minLength.min }} elements.</div>
    <div v-else-if="!$v.people.required">List must not be empty.</div>
    <div v-else-if="$v.people.$error">List is invalid.</div>
    <button class="button" [@click](http://twitter.com/click "Twitter profile for @click")="$v.people.$touch">$touch</button>
    <button class="button" [@click](http://twitter.com/click "Twitter profile for @click")="$v.people.$reset">$reset</button>
  </div>
</template>
<script>
import { required, minLength } from "vuelidate/lib/validators";
export default {
  name: "App",
  data() {
    return {
      people: [
        {
          name: "mary"
        },
        {
          name: ""
        }
      ]
    };
  },
  validations: {
    people: {
      required,
      minLength: minLength(3),
      $each: {
        name: {
          required,
          minLength: minLength(2)
        }
      }
    }
  }
};
</script>

In the validations property, we have the $each property with the minLength property to set the min length of the people array.

Also, we have the minLength property in the name field to check if the name entered has the required length.

In the template, we have the $touch and $reset methods that we can use to trigger validation and reset the validation state respectively.

Conclusion

We can validate lists and check for errors with Vuelidate.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *