Search code examples
javascriptvue.jsvuetify.jsvuelidate

vuetify input appended button loader working incorrectly


I have an email v-text-field field (I have a lot more actually, but email requires more complex rules), and I use Vuelidate for form validation. And after the user input his email and Vuelidate detect it as a valid I need to show a Check button, to make a request and check if user exists or not. Till request on his way to the server and back, I want to show the loader on the button. Here is the code:

<template>
  <v-text-field 
     v-model="user.email" 
     type="email" 
     label="Email" 
     solo="true" 
     :error-messages="emailErrors" 
     @input="$v.user.email.$touch()" 
     @blur="$v.user.email.$touch()"
  >
     <template v-slot:append>
        <v-btn
            v-if="!$v.user.email.$invalid()"
            class="ma-2"
            :loading="user.emailVerificationInProgress"
            color="#ad5697"
            @click="checkUserRegistration()"
        >Check </v-btn>
     </template>
   </v-text-field>
<tempale>

<script>
import {validationMixin} from 'vuelidate'
import {required, email} from 'vuelidate/lib/validators'

export default {
  mixins: [validationMixin],
  validations: {
     user: {
       email: {required, email},
     }
  },
   data: () => ({
       user: {
         email: null,
         emailVerificationInProgress: false
       }
   }),
   methods: {
    checkUserRegistration() {
      this.$v.user.email.$touch();
      if (this.$v.user.email.$invalid) return;
      this.user.emailVerificationInProgress = true;
      setTimeout(
          () => {
            // simulate request
            this.user.emailVerificationInProgress = false;
          },
          3000
      )
    },
   },
   computed: {
     emailErrors() {
      const errors = []
      if (!this.$v.user.email.$dirty) return errors
      !this.$v.user.email.email && errors.push('Invalid email provided')
      !this.$v.user.email.required && errors.push('Email is required.')

      return errors;
    }
   } 

All is working as expected except the button loader, for some reason after I click on the Check button, another button with preloader appearing before the Check button, but the loader should appear on the same button.


Solution

  • Your code looks alright, besides a couple issues. You really should also receive error for these! in your text field solo="true", should be :solo="true" to capture the boolean value.

    As for the button, v-if="!$v.user.email.$invalid()" should throw error too, should be without parenthesis, in other words, it should be: v-if="!$v.user.email.$invalid.

    By the way, also using $touch in template is enough. No need to do $touch().

    Here's a working sandbox for your reference: CODESANDBOX