Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuelidate: validate on click, not when field touched

I'm kinda new to vuelidate, and everything works fine, except I have no clue how to run validation only when the button Submit has been clicked. Right now it marks touched field red when you start providing any input and I'd like it to wait with that, till user wants to submit filled form.

Here's what I've got up to now:

Vue.use(window.vuelidate.default)
const { required, minLength, sameAs } = window.validators

new Vue({
	el: "#app",
  data: {
  	user: {
    	login: '',
      password: '',
      repeatedPassword: ''
    }
  },
  validations: {
  	user: {
    	login: {
      	required,
        minLength: minLength(5)
      },
      password: {
    	  required,
        minLength: minLength(8)
      },
      repeatedPassword: {
      	required,
        sameAs: sameAs('password')
      }
    }
  }
})
input {
  border: 1px solid silver;
  border-radius: 4px;
  background: white;
  padding: 5px 10px;
}

.error {
  border-color: red;
  background: #FDD;
}

.error:focus {
  outline-color: #F99;
}

.valid {
  border-color: #5A5;
  background: #EFE;
}

.valid:focus {
  outline-color: #8E8;
}
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuelidate/dist/validators.min.js"></script>
<script src="https://unpkg.com/vuelidate/dist/vuelidate.min.js"></script>
`<div id="app">

  <input type="text" placeholder="login"
    v-model="user.login"
    v-on:input="$v.user.login.$touch"
    v-bind:class="{error: $v.user.login.$error, valid: $v.user.login.$dirty && !$v.user.login.$invalid}">
  <br/>    
  <input type="password" placeholder="password"
    v-model="user.password"
    v-on:input="$v.user.password.$touch"
    v-bind:class="{error: $v.user.password.$error, valid: $v.user.password.$dirty && !$v.user.password.$invalid}">
  <br/>  
  <input type="password" placeholder="repeat password"
    v-model="user.repeatedPassword"
    v-on:input="$v.user.repeatedPassword.$touch"
    v-bind:class="{error: $v.user.repeatedPassword.$error, valid: $v.user.repeatedPassword.$dirty && !$v.user.repeatedPassword.$invalid}"
  >
  <button :disabled="$v.user.$error" @click="$v.user.$touch()">
    Submit!
  </button>
</div>`
like image 225
nemezis Avatar asked Aug 31 '17 14:08

nemezis


People also ask

What does touch do in Vuelidate?

$touch() , which will call $touch on all the nested properties. $touch is attached to each field, to its parent, all the way up to the root of the validation. This is useful in cases where you have a Submit button and want to trigger the whole form $dirty . See Validating Forms Before Submitting for an example.

How do you validate a form field?

Basic Validation − First of all, the form must be checked to make sure all the mandatory fields are filled in. It would require just a loop through each field in the form and check for data. Data Format Validation − Secondly, the data that is entered must be checked for correct form and value.


2 Answers

I could never really get used to the Vuelidate way of doing things, but, generally speaking, it works like this: https://monterail.github.io/vuelidate/#sub-basic-form

Setting it up like this allows you to have validation for each form input/element and then an overall check to see if the form is "dirty" and/or "invalid"

form: {
"name": {
"required": false,
"$invalid": true,
"$dirty": false,
"$error": false,
"$pending": false,
"$params": {
  "required": {
    "type": "required"
  }
}
},
"Age": {
  "required": false,
  "$invalid": true,
  "$dirty": false,
  "$error": false,
  "$pending": false,
  "$params": {
    "required": {
      "type": "required"
    }
  }
},
"$invalid": true,  <------- This is what you are after for valid/invalid
"$dirty": false,   <------- This is what you are after to see if the form has been used.
"$error": false,  <-------  This checks both invalid and dirty
"$pending": false,
"$params": {
   "nestedA": null,
   "nestedB": null
}
}

As far as using this in practice, one option would be to call validateform event on submit.

@click.prevent="validateform"

Then create a validateform method in your vue instance that checks

$v.form.$invalid  or $v.form.$error

then either display errors or call the actual submit method

like image 75
retrograde Avatar answered Sep 18 '22 20:09

retrograde


Then the only thing you have to do after setting up the validations is to call a method that will validate the errors. So follow below:

<button @click="validate">Submit</button>

The method:

validate () {
  this.$v.$touch() //it will validate all fields
  if (!this.$v.$invalid) { //invalid, becomes true when a validations return false
   //you dont have validation error.So do what u want to do here
  }
}
like image 35
Roland Avatar answered Sep 20 '22 20:09

Roland