Reputation: 4031
I am using Vuetify to create a simple form where the data is being validated by some rules associated with each field. What I am trying to do is disable the Submit button if any of those validation rules fails. How can I do so? What I am trying to understand is how to check the state of each rule so that I can bind the disabled
property on the button.
<template>
<v-card>
<v-card-text>
<v-combobox
v-model="addTool.name"
:rules="rules.name"
:items="toolNames"
counter
label="Name of the tool"
></v-combobox>
<v-combobox
multiple
:small-chips="true"
:deletable-chips="true"
:hide-selected="true"
:clearable="true"
v-model="addTool.categories"
:rules="rules.categories"
label="Select/Add categories"
:items="this.toolCategories"
:search-input.sync="searchCat"
@change="searchCat = ''"
></v-combobox>
<v-text-field
v-model="addTool.site"
label="URL for the tool. It is best to use a Github repo link."
:rules="rules.site"
></v-text-field>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="submit" color="grey darken-4" class="green--text text--accent-2" dark>Add</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
data() {
return {
dialog: false,
searchCat: "",
addToolMessage: undefined,
addTool: {
name: "",
categories: [],
created_on: "",
site: ""
},
rules: {
name: [
v => !!v || "Required.",
v => v.length < 80 || "Name is too long",
v =>
!this.toolsData
.map(n => n.name.toLowerCase())
.includes(v.toLowerCase()) || "This tool already exists"
],
categories: [v => v.length != 0 || "At least one category is needed"],
site: [
v => !!v || "Required.",
v =>
new RegExp(
"^(?:(?:https?|ftp)://)(?:S+(?::S*)?@)?(?:(?!(?:10|127)(?:.d{1,3}){3})(?!(?:169.254|192.168)(?:.d{1,3}){2})(?!172.(?:1[6-9]|2d|3[0-1])(?:.d{1,3}){2})(?:[1-9]d?|1dd|2[01]d|22[0-3])(?:.(?:1?d{1,2}|2[0-4]d|25[0-5])){2}(?:.(?:[1-9]d?|1dd|2[0-4]d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:.(?:[a-z\u00a1-\uffff]{2,})).?)(?::d{2,5})?(?:[/?#]S*)?$",
"ig"
).test(v) || "Not a valid URL",
v =>
!this.toolsData.map(u => u.site).includes(v) ||
"This tool already exists"
]
}
};
}
};
</script>
Upvotes: 31
Views: 50394
Reputation: 5213
Vuetify will track the validity of form if you wrap input elements in v-form
and then attach v-model to form
like this:
<v-form v-model="isFormValid">
<!-- all input elements go here -->
</v-form>
<!-- disable if form is not valid -->
<v-btn :disabled="!isFormValid">Add</v-btn>
You also need to add isFormValid
to the component's data
field:
data: () => ({
isFormValid: false,
})
You can read more here: https://vuetifyjs.com/en/components/forms
Upvotes: 61
Reputation: 919
You can create a computed property do to it. Lets say name
and site
are requireds, so:
<temlate>
<v-btn :disabled="isAddButtonDisabled" @click="submit" color="grey darken-4" class="green--text text--accent-2" dark>Add</v-btn>
</template>
<script>
export default {
data() {
return {
addTool: {
name: "",
categories: [],
created_on: "",
site: ""
},
};
},
computed: {
isAddButtonDisabled() {
return !(this.addTool.name || this.addTool.site);
// means u have neither name nor site
},
},
};
</script>
If you need to check if form is valid, you can do:
export default {
computed: {
formValid () {
// loop over all contents of the fields object and check if they exist and valid.
return Object.keys(this.addTool).every(field => {
return this.addTool[field] && this.addTool[field].valid;
});
}
}
}
From here: https://github.com/logaretm/vee-validate/issues/853
Upvotes: 1