Vuelidate reset specific field so that $error flag is false
Asked Answered
H

2

8

Using Vuelidate you can reset the validation errors by using this.$v.$reset(). In this Codepen example resetting the lastName field that uses a Vuetify component works - $invalid is true while $error is set to false.

When resetting the regular text input for firstName it doesn't work as the $error flag is still true. How can I modify the text input so that $error is false when calling reset?

I've also tried this.$nextTick(() => {...}) but that doesn't work either.

Vue.use(window.vuelidate.default)
var validationMixin = window.vuelidate.validationMixin
const {
  maxLength,
  required
} = window.validators

new Vue({
  el: '#app',
  mixins: [validationMixin],
  data: () => ({
    form: {
      firstName: '',
      lastName: ''
    }
  }),
  validations: {
    form: {
      firstName: {
        required, maxLength: maxLength(2)
      },
      lastName: {
        required, maxLength: maxLength(2)
      },
    }
  }
})
input.raw {
  border: solid;
}

.is-invalid {
  border-color: #FF5252 !important;
}
<html>
  <head>
    <script src="https://unpkg.com/[email protected]/dist/validators.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vuelidate.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
  </head>
  <body>
    <div id="app">
            <label for="firstName">First Name</label>
            <input
              v-model="form.firstName"
              id="firstName"
              class="raw"
              :class="{ 'is-invalid': $v.form.firstName.$error }"
              type="text"
              width="100%"
              :oninput="$v.form.firstName.$touch()"
              :onblur="$v.form.firstName.$touch()"
            />
            <button @click="$v.form.firstName.$touch()">
              $touch
            </button>
            <button @click="$v.form.firstName.$reset()">
              $reset
            </button>
            <pre>{{ $v.form.firstName }}</pre>
    </div>
  </body>
</html>
Horrify answered 30/1, 2020 at 12:32 Comment(1)
Not sure why, but it seems to make a difference when you use @input and @blur instead of :oninput and :onblur.Epitaph
G
1

In your example, you are using oninput and onblur HTML attributes, but in Vue, you should use @input(v-on:input) and @blur(v-on:blur) bindings instead. See docs for details.

Replacing HTML attributes with Vue bindings made your example work correctly:

Vue.use(window.vuelidate.default)
var validationMixin = window.vuelidate.validationMixin
const {
  maxLength,
  required
} = window.validators

new Vue({
  el: '#app',
  mixins: [validationMixin],
  data: () => ({
    form: {
      firstName: '',
      lastName: ''
    }
  }),
  validations: {
    form: {
      firstName: {
        required, maxLength: maxLength(2)
      },
      lastName: {
        required, maxLength: maxLength(2)
      },
    }
  }
})
input.raw {
  border: solid;
}

.is-invalid {
  border-color: #FF5252 !important;
}
<html>
  <head>
    <script src="https://unpkg.com/[email protected]/dist/validators.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vuelidate.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
  </head>
  <body>
    <div id="app">
            <label for="firstName">First Name</label>
            <input
              v-model="form.firstName"
              id="firstName"
              class="raw"
              :class="{ 'is-invalid': $v.form.firstName.$error }"
              type="text"
              width="100%"
              @input="$v.form.firstName.$touch()"
              @blur="$v.form.firstName.$touch()"
            />
            <button @click="$v.form.firstName.$touch()">
              $touch
            </button>
            <button @click="$v.form.firstName.$reset()">
              $reset
            </button>
            <pre>{{ $v.form.firstName }}</pre>
    </div>
  </body>
</html>
Grimbal answered 7/10, 2020 at 5:52 Comment(0)
S
-3

This is Issue From Vuelidate and they must be fixed, in this position you can not reset form and give same (badly) behavior you can re-render by the router

// re render component for reset all fileds
this.$router.go(0)
Skirr answered 20/6, 2020 at 7:52 Comment(1)
If this is a Vuelidate bug, consider adding a link to a related Github issue.Grimbal

© 2022 - 2024 — McMap. All rights reserved.