Reputation: 2007
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
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
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