Using Vee-validate to disable button until form is filled out correctly Using Vee-validate to disable button until form is filled out correctly vue.js vue.js

Using Vee-validate to disable button until form is filled out correctly


Setting up the button to be :disabled:"errors.any()" disables the button after validation. However, when the component first loads it will still be enabled.

Running this.$validator.validate() in the mounted() method, as @im_tsm suggests, causes the form to validate on startup and immediately show the error messages. That solution will cause the form to look pretty ugly. Also, the Object.keys(this.fields).some(key => this.fields[key].invalid); syntax is super ugly.


Instead, run the validator when the button is clicked, get the validity in the promise, and then use it in a conditional. With this solution, the form looks clean on startup but if they click the button it will show the errors and disable the button.

<button :disabled="errors.any()" v-on:click="sendInvite();">    Send Invite</button>
sendInvite() {    this.$validator.validate().then(valid=> {        if (valid) {            ...        }    })}

Validator API


Probably simpliest way is to use ValidationObserver slot for a form. Like this:

<ValidationObserver v-slot="{ invalid }">  <form @submit.prevent="submit">    <InputWithValidation rules="required" v-model="first" :error-messages="errors" />    <InputWithValidation rules="required" v-model="second" :error-messages="errors" />    <v-btn :disabled="invalid">Submit</v-btn>  </form></ValidationObserver>

More info - Validation Observer


One way to disable a button until all the values you need are filled, is to use a computed property that will return bool if all values are assigned or not

Example:

Create a computed property like this:

computed: {  isComplete () {    return this.username && this.password && this.email;  }}

And bind it to the html disabled attribute as:

<button :disabled='!isComplete'>Send Invite</button

This means, disable the button if !isComplete is true

Also, in your case you don't need two if/else-bound buttons. You can use just one to hide/show it based on if the form is completed or has any errors:

<button :disabled="errors.any() || !isCompleted" class="btn btn-primary" v-on:click="sendInvite();" data-dismiss="modal" type="submit">Send Invite</button>

This button will be disabled until all fields are filled and no errors are found