0

I am new to Vuelidate and was wondering how I go about validating the form on load as I can't seem to find the answer anywhere?

I have my validation fully working using Vuelidate when empty required input or checking an email is valid.

The reason I want to validate on load is that data pre-populates my form and if all inputs are populated and passes validation, then the 'Submit' is enabled otherwise if there's an error I want it disabled so I need to validate onload.

My form has inputs, selects and textarea. The below snippet is some of the basic code.

Vue.use(window.vuelidate.default)
const { required, email } = window.validators
const touchMap = new WeakMap();

new Vue({
    el: "#app",
    data() {
        return {
          emailAdd: '',
          enquiryType: '',
          enqMsg: ''
        }
      },

      validations: {
         email: {
             required,
             email
         },
         enquiryType: {
             required
         },
         enqMsg: {
             required
         }
     },

     methods: {
      delayTouch($v) {
        $v.$reset()

        if (touchMap.has($v)) {
            clearTimeout(touchMap.get($v))
        }

        if ($v.$model === '') {
            touchMap.set($v, setTimeout($v.$touch, 0))
        } else {
            touchMap.set($v, setTimeout($v.$touch, 1000))
        }            
      },

      status(validation) {
        return {
            error: validation.$error,
            dirty: validation.$dirty
        }
      }
    }
})
#app {
  min-height: 600px
}

label {
  font-weight: bold
}

.error {
    border-color: red !important;
    background: #fdd !important;
}

.error::placeholder {
  color: #c94c4c !important;
  opacity: 1 !important; /* Firefox */
}
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/vuelidate@0.7.6/dist/validators.min.js"></script>
<script src="https://unpkg.com/vuelidate@0.7.6/dist/vuelidate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="p-3">
  <div class="form-group">
      <label for="emailAdd">Email address</label>
      <input id="emailAdd" ref="emailAdd" type="search" class="form-control" :class="status($v.email)" v-model.trim="emailAdd"@input="delayTouch($v.email)" placeholder="Enter your email address" />
      <small v-if="emailAdd.length == 0 && !$v.email.required && $v.email.$dirty" class="text-danger">This field is required</small>
      <small v-if="emailAdd.length > 0 && !$v.email.emailAdd && $v.email.$dirty" class="text-danger">The email address entered is invalid</small>
  </div>
  <div class="form-group">
      <label for="enquiryType">Enquiry type</label>
      <select id="enquiryType" ref="enquiryType" class="form-control" :class="status($v.enquiryType)" v-model="$v.enquiryType.$model">
          <option selected value>Select an enquiry type</option>
          <option value="cs">Customer services</option>
          <option value="eo">Existing order</option>
          <option value="ge">General enquiry</option>
          <option value="sb">Site bug</option>
          <option value="se">Site improvement</option>
      </select>
      <small v-if="!$v.enquiryType.required && $v.enquiryType.$dirty" class="text-danger">Please select an option</small>
  </div>
  <div class="form-group">
      <label for="enqMsg">Message</label>
      <textarea id="enqMsg" ref="enqMsg" class="form-control" :class="status($v.enqMsg)" v-model.trim="enqMsg" @input="delayTouch($v.enqMsg)" placeholder="Enter message" rows="7"></textarea>
      <small v-if="!$v.enqMsg.required && $v.enqMsg.$dirty" class="text-danger">This field is required</small>
  </div>
</div>
halfer
  • 19,824
  • 17
  • 99
  • 186
murday1983
  • 3,806
  • 14
  • 54
  • 105

2 Answers2

0

You can manually kick off the validation by running $v.$touch() in the mounted hook:

mounted(){ 
  $v.$touch() 
}
Thomas Kuhlmann
  • 943
  • 7
  • 18
0

Step 1: HTML template

<template>
  <div id="app">
    <form @submit.prevent="submitRegistration" novalidate>
      <div class="form-group">
        <label for="emailAdd">Email address</label>
        <input
          id="emailAdd"
          ref="emailAdd"
          type="search"
          class="form-control"
          v-model="emailAdd"
          placeholder="Enter your email address"
        />
        <small v-if="$v.emailAdd.$error" class="error">
          <span v-if="!$v.emailAdd.required">Email is required</span>
          <span v-if="emailAdd && !$v.emailAdd.email"
            >The email address entered is invalid</span
          >
        </small>
      </div>
      <div class="form-group">
        <label for="enquiryType">Enquiry type</label>
        <select
          id="enquiryType"
          ref="enquiryType"
          class="form-control"
          v-model="enquiryType"
        >
          <option selected value>Select an enquiry type</option>
          <option value="cs">Customer services</option>
          <option value="eo">Existing order</option>
          <option value="ge">General enquiry</option>
          <option value="sb">Site bug</option>
          <option value="se">Site improvement</option>
        </select>
        <small v-if="!$v.enquiryType.required" class="error"
          >Please select an option</small
        >
      </div>
      <div class="form-group">
        <label for="enqMsg">Message</label>
        <textarea
          id="enqMsg"
          ref="enqMsg"
          class="form-control"
          v-model="enqMsg"
          placeholder="Enter message"
          rows="7"
        ></textarea>
        <small v-if="!$v.enqMsg.required" class="error"
          >Message is required</small
        >
      </div>
      <div class="form-group">
        <input
          type="submit"
          class="btnRegister"
          value="Register"
          :disabled="this.isDisabled"
        />
      </div>
    </form>
  </div>
</template>

Step 2: Scripts will be

<script>
import { required, email } from "vuelidate/lib/validators";

export default {
  name: "App",
  data() {
    return {
      emailAdd: "",
      enquiryType: "",
      enqMsg: "",
    };
  },
  validations: {
    emailAdd: { required, email },
    enquiryType: { required },
    enqMsg: { required },
  },
  created() {
    this.submitted = true;
    return this.$v.$touch();
  },
  computed: {
    isDisabled() {
      return this.$v.$invalid;
    },
  },
  methods: {
    submitRegistration() {
      this.$v.$touch();
      if (this.$v.$invalid) {
        return false; // stop here if form is invalid
      } else {
        alert("Form Valid");
      }
    },
  },
};
</script>

Step 3: Styles will be

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.error {
  color: red;
}
</style>

DEMO

Jebasuthan
  • 5,538
  • 6
  • 35
  • 55