gib65
gib65

Reputation: 2007

How to tell if a form field is invalid in vue.js

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?

Upvotes: 3

Views: 16686

Answers (2)

tony19
tony19

Reputation: 138216

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>

Upvotes: 7

J&#243;zef Podlecki
J&#243;zef Podlecki

Reputation: 11283

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>

Upvotes: 1

Related Questions