3

I'm developing a Vue application. I would like to know if a form field is in an invalid state. For example, if the field is required, and the user hits submit, but they haven't filled out the field, then the browser's validation should trigger and the field shows in red with a validation message under it. That's what I mean by an invalid state.

I can reference the field with $refs as follows:

<v-text-field 
    ref="myField"
    required
    v-model="value" />
this.$refs['myField'].what?

Is there anything I can do with $refs['myField'] that will tell me if it's in an invalid state or not?

0

2 Answers 2

7

v-text-field has two mixin properties that could be used to determine its validation status: hasError or valid. To check if the field is invalid, you could do:

this.$refs['myField'].hasError

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      password: 'Password',
      rules: {
        required: value => !!value || 'Required.',
        min: v => v.length >= 8 || 'Min 8 characters',
      },
    }
  },
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuetify.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/vuetify.min.css">
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">

<v-app id="app">
  <v-container>
    <v-text-field
      ref="password"
      v-model="password"
      :rules="[rules.required, rules.min]"
      type="password"
      label="Password"
      hint="At least 8 characters"
      counter
    ></v-text-field>
    <pre v-if="$refs.password">
      hasError: {{$refs.password.hasError}}
      valid: {{$refs.password.valid}}
    </pre>
  </v-container>
</v-app>

Sign up to request clarification or add additional context in comments.

Comments

1

You can use v-model binding on v-form element to get form valid state.

If you can't do that you can bind ref to v-form and probably access valid state internally

Take a look at below snippet!

Vue.config.productionTip = false;
Vue.config.devtools = false;

new Vue({
  el: '#app',
  data: () => ({
    valid: false,
    name: '',
    nameRules: [
      (v) => !!v || 'Name is required',
      (v) => v.length <= 10 || 'Name must be less than 10 characters'
    ],
  }),
  computed: {
    formState() {

      let nameValid = false;
      let errorBucket = []
      let nameInput = this.$refs.nameInput;

      if (nameInput) {
        nameValid = nameInput.valid
        errorBucket = nameInput.errorBucket
      }

      return JSON.stringify({
        valid: this.valid,
        nameValid,
        errorBucket,
        name: this.name
      });
    }
  },
  methods: {
    submit() {
      console.log(this.valid, this.name)
    }
  },
  vuetify: new Vuetify(),
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>


<div id="app">
  <v-app>
    <v-content>
      <v-form v-model="valid">
        <v-container>
          <v-text-field ref="nameInput" v-model="name" :rules="nameRules" label="Name"></v-text-field>
          <v-btn :disabled="!valid" class="mr-4" @click="submit">submit</v-btn>
          <div>{{formState}}</div>
        </v-container>
      </v-form>
    </v-content>
  </v-app>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.