16

I have a (Vuetify) form with an email input that uses ES6 & regex to check if it's a valid email. How would I set up another emailConfirmationRules ruleset to check if the emailConfirmation input matches the email input?

<template>
  <v-form v-model="valid">
       <v-text-field label="Email Address"
            v-model="email" 
            :rules="emailRules"
            required></v-text-field>

       <v-text-field label="Confirm Email Address"
            v-model="emailConfirmation" 
            :rules="emailConfirmationRules"
            required></v-text-field>
   </v-form>
 <template>

export default {
    data () {
      return {
         valid: false,
         email: '',
         emailConfirmation: '',
         emailRules: [
             (v) => !!v || 'E-mail is required',
             (v) => /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(v) || 'E-mail must be valid'
        ],
        emailConfirmationRules: [
            (v) => !!v || 'Confirmation E-mail is required',
        ]   (v) => ??? || 'Confirmation E-mail does not match'
    }
}
sternmd
  • 635
  • 2
  • 8
  • 15

5 Answers5

18

Rules are not the proper way of handling field confirmation. emailConfirmationRules are triggered only when emailConfirmation changes, but if you change email again, your fields won't match anymore without any break of rules.

You have to handle this manually:

methods: {
  emailMatchError () { 
    return (this.email === this.emailConfirmation) ? '' : 'Email must match'
  }
}
<v-text-field v-model='emailConfirmation' :error-messages='emailMatchError()'></v-text-field>

There may be an alternative way of doing this with vee-validate too.

Eiji Shinjo
  • 181
  • 1
  • 4
  • 3
    It's the good way but the best is to put this method inside computed – John Apr 26 '19 at 12:51
  • This should be the accepted answer, thanks! Because like you said, even if rules are computed properties, they are not reactive to changes in other components (fields). – knary Nov 03 '20 at 23:58
12

You can accomplish the same with a computed rule.

computed: {
    emailConfirmationRules() {
      return [
        () => (this.email === this.emailToMatch) || 'E-mail must match',
        v => !!v || 'Confirmation E-mail is required'
      ];
    },
}

Luis Molina
  • 146
  • 1
  • 5
  • any way to make it pristine again.? my form is reusable, but when use this rules it always show error for the second form and other form – Sae May 28 '20 at 01:58
1
  emailConfirmationRules: [
    (v) => !!v || 'Confirmation E-mail is required',
    (v) => v == this.email || 'E-mail must match'
  ],
sternmd
  • 635
  • 2
  • 8
  • 15
  • I think i have updated something, the solution worked all the time but now i also get undefined. But not the "this". just the value is always undefined. The property itself has the correct value. I think I need to change my way to validate. Maybe vee-validate – prdatur Dec 22 '18 at 14:18
  • Wrong answer. Please see Eiji Shinjo's answer below. – sureshvv Feb 17 '19 at 08:38
  • This did not work for me. I'm getting the following error: `Error in beforeMount hook: "TypeError: _this is undefined"` – Julien Salinas Apr 30 '19 at 20:29
  • 1
    This is WRONG answer. Rule-functions are called without context (see https://github.com/vuetifyjs/vuetify/blob/e60cf638dfd671af6fc8fa4ff01fe7addc914f9c/packages/vuetify/src/mixins/validatable/index.ts#L239) – disfated Sep 14 '19 at 17:37
  • `this` is not available in an arrow function – Riza Khan Jan 23 '21 at 17:05
1
  <template>   
    <v-text-field
      v-model="employee.email"
      :rules="emailRules"
      required
      validate-on-blur
      />
</template>

<script>
data() {
    return {
    emailRules: [
        v => !!v || "E-mail is required",
        v =>
          /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(v) ||
          "E-mail must be valid"
      ],
}
</script>
1

Check this post https://stackoverflow.com/a/58883995/9169379

<template>
  <v-input  v-model="firstPassword" />
  <v-input :rules=[rules.equals(firstPassword)] v-model="secondPassword" />
</template>

<script>    
  data() {
  firstPassword: '',
  secondPassword: '',
    rules: {
      equals(otherFieldValue) {
        return v =>  v === otherFieldValue || 'Not equals';
      }
    }
  }
</script>
Miguel Galindo
  • 111
  • 1
  • 3