Search code examples
javascriptvue.jsvuelidate

How to validate confirm password with password and show error message at every character?


This my code pen link https://codepen.io/santoshch/pen/bGgKNWV

 <label class="form__group is-required">
    <span class="form__label">Password</span>
    <input
      class="form__input" type="password" name="form-password"
      v-model="password" @input="$v.password.$touch"
    >
    <p v-if="$v.password.$dirty">
      <span class="form__alert" v-if="!$v.password.required">Required.</span>
      <span class="form__alert" v-if="!$v.password.minLength">
        {{$v.password.$params.minLength.min}} letters at least.
      </span>
    </p>
  </label>
  <!-- Repeat Password -->
  <label class="form__group is-required">
    <span class="form__label">Repeat<br>password</span>
    <input
      class="form__input" type="password" name="form-repeat-password"
      v-model="repeatPassword" @input="$v.repeatPassword.$touch"
    >
    <p v-if="$v.repeatPassword.$dirty">
      <span class="form__alert" v-if="!$v.repeatPassword.required">Required.</span>
      <span class="form__alert" v-if="!$v.repeatPassword.sameAsPassword">
        Must be identical.
      </span>
    </p>
  </label>
Got reference for Vuetify, How to validate password field with every character in Vuejs?
export default {
    data() {
        return {
        confirmPasswordRules: [
           (value) => !!value || 'type confirm password',
           (value) =>
           value === this.password ||
           'The password confirmation does not match.',
        ],
}
:rules="confirmPasswordRules"

Ya code is working fine which provided in codepen. but one more functionality need to add for confirmPassword filed. i.e, in confirmpassword field, I need to check each and every character with password field, and then i need to display at which character we have entered wrong.


Solution

  • First remove the :rules from your HTML, and just use vuelidate. Remove the property confirmPasswordRules from your data object. As they are not doing anything, and are just wasting space.

    <span class="form__label">
      Repeat<br />
      password
    </span>
    

    Now when comparing your two passwords, if you want to check character by character, you will want to get a substring of your existing password string. For example let's say the password is test1234, if the user has begun typing tes in your repeat password field you take the substring of the password to match the same length so you are not comparing "test1234" == "tes", instead by taking the substring you would be comparing "tes"=="tes". We do this by calling .substring(start, end). Our start will always be 0, and our end will be the current length of repeatPassword so we will get our string from the beginning to the point that the user has typed their repeated password.

    To do this with Vuelidate we will need to create a custom function that returns a boolean value. So we create the inline function:

    (value) => value === this.password.substring(0, value.length+1)
    

    However, because of how vuelidate works this will be inaccessible. So we need to pass one more parameter to our function containing the Vue instance. We can do this by changing our function to expect two variables, one containing the object's current value, and the other containing the Vue instance. Then we will replace this with our variable with the Vue instance.

    (value,vm) => value === vm.password.substring(0, value.length+1)
    

    We will place this function inside of your validations code, under repeatPassword. This would then make our repeatPassword object look like so:

    repeatPassword: {
      required: required,
      sameAsPassword: (value, vm) =>
          value === vm.password.substring(0, value.length+1),
    },
    

    Here is a full codesandbox