Only show submit button when 3 validations are checked

Viewed 47

I have a validated form:

       <label class="form-label" for="full name">¿Cómo te llamas?</label>
       <input class="form-control" placeholder="ej: María" type="text" v-model="name" required>
       <div class="alert alert-danger w-100" v-if="msg.name">{{msg.name}}</div>
       <label class="form-label" for="email">Email de empresa:</label>
       <input class="form-control" placeholder="maria@lamejorempresadelmundo.com"  type="text" v-model="email" required> <br>
       <div class="alert alert-danger w-100" v-if="msg.email">{{msg.email}}</div>
       <label class="form-label" type="password" for="password">Contraseña:</label>
       <input class="form-control" type="text" v-model="password" required><br>
       <div class="alert alert-danger w-100" v-if="msg.password">{{msg.password}}</div>

I want the submit button to show only if the 3 validation methods are met. I've tried to return true in each validation and make the submit have an v-if to check the 3 with no luck. Any ideas?

  <button type="submit"  @click.prevent="submit" v-if="this.validateEmail == true && this.validateName == true && this.validatePassword == true" >Finalizar</button>

For validations, I use 3 different methods that already work correctly:

Data

msg: [],

Watcher

watch: {
  email(value){
    this.email = value;
    this.validateEmail(value);
  },
  password(value){
    this.password = value;
    this.validatePassword(value);
  },
  name(value){
    this.name = value;
    this.validateName(value);
  }
}

Validation Methods

  validateEmail(value){
       if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(value)) {
         this.msg['email'] = ''
         return false
       } else {
         this.msg['email'] = 'Email no válido';
         return true
        }
       },
       validatePassword(value){
       let difference = 6 - value.length;
         if (value.length<6) {
           this.msg['password'] = 'Mínimo 6 caracteres - '+ difference + ' caracteres restantes' ;
           return false
         } else {
            this.msg['password'] = '';
            return true
         }
       },
       validateName(value){
        let difference = 4 - value.length;
         if (value.length < 4) {
           return false
           this.msg['name'] = 'Mínimo 4 caracteres - '+ difference + ' caracteres restantes' ;
         } else {
           this.msg['name'] = '';
           return true
         }
2 Answers

I believe that checking functions like that won't do for the button conditioning since there is no value parameter being passed but in general, I would assume you could initialise a new data property for checks like:

validator: {
 isEmail: false,
 isPw: false,
 isName: false
}

Then instead of returning false or true in your validation functions, you would do something like:

this.validator.isEmail = false
else
this.validator.isEmail = true

and so on...

then v-if for your button:

<button type="submit" @click.prevent="submit" v-if="validator.isEmail && validator.isPw && validator.isName">Finalizar</button>

There are a few issues with your code:

  1. The watchers should not set the property's value to the same value.

    watch: {
      email(value) {
        // this.email = value; ❌
        this.validateEmail(value);
      },
      //...
    }
    
  2. validateName() returns false before it sets this.msg. That should be reversed to ensure the change to this.msg.

    methods: {
      validateName(value) {
        if (value.length < 4) {
           // return false; ❌
           this.msg['name'] = '...';
           return false; ✅
        }
        //...
      }
    }
    
  3. Vue 2 cannot automatically detect property additions to this.msg, so use vm.$set():

    // this.msg['name'] = '...'; ❌
    this.$set(this.msg, 'name', '...')
    

To hide the Submit button, you could use a computed property (named formValid) that returns whether all three properties are non-empty and whether this.msg has a corresponding error:

computed: {
  formValid() {
    return this.name && !this.msg.name
      && this.email && !this.msg.email
      && this.password && !this.msg.password;
  }
}

And in the template, conditionally render the Submit button based on formValid:

<button v-if="formValid">Submit</button>

demo

Related