Reputation: 69
I want to allow either the checkbox to be checked, the text field to be filled in, or both in Quasar.
In the validation of this form, the error does not disappear even if the check box is checked after the validation error occurs.
index.html
<div id="q-app">
<q-card class="my-card q-py-md">
<q-card-section>
<h3 class="text-h5 q-my-none">Fruits<span class="text-red">*</span></h3>
<p>Which fruit did you eat?</p>
</q-card-section>
<q-card-section>
<q-field
hide-bottom-space
borderless
item-aligned
class="row q-pa-none"
:rules="[fruitsRule]">
<q-option-group
:options="fruits"
label="Notifications"
type="checkbox"
v-model="fruits_select"></q-option-group>
</q-field>
<q-input
class="q-mt-md"
v-model="fruits_other"
label="Other"
:rules="[fruitsRule]"></q-input>
</q-card-section>
</q-card>
</div>
main.js
new Vue({
el: '#q-app',
data () {
return {
fruits_select: [],
fruits: [
{ label: 'Apple', value: 1},
{ label: 'Banana', value: 2},
{ label: 'Orange', value: 3}
],
fruits_other: ""
}
},
methods: {
fruitsRule () {
if (!this.fruits_select.length && this.fruits_other === ""){
return 'Select one or more checkboxes or fill in the others.'
}
}
}
})
My question is
Upvotes: 0
Views: 5870
Reputation: 37793
There are few problems with your code and Quasar validation in general
v-model
on q-field
. Without it, the rules are not executed for checkboxes<q-field hide-bottom-space borderless item-aligned class="row q-pa-none" v-model="fruits_select" :rules="[fruitsRule]">
<q-option-group :options="fruits" label="Notifications" type="checkbox" v-model="fruits_select" />
</q-field>
Your custom validator will be a function which returns
true
if validator succeeds orString
with error message if it doesn’t succeed
But your fruitsRule
never retuns true
. Fix:
fruitsRule () {
return this.fruits_select.length > 0 || this.fruits_other !== "" || 'Select one or more checkboxes or fill in the others.'
}
Easiest thing to fix this is to use <QForm>
, which has a method validate()
that triggers the validation of every field in the form and execute it whenever one of the models changes:
<q-form ref="form">
<q-field hide-bottom-space borderless item-aligned class="row q-pa-none" v-model="fruits_select" :rules="[fruitsRule]">
<q-option-group :options="fruits" label="Notifications" type="checkbox" v-model="fruits_select" />
</q-field>
<q-input class="q-mt-md" v-model="fruits_other" label="Other" :rules="[fruitsRule]" />
</q-form>
watch: {
fruits_select() {
this.$refs.form.validate()
},
fruits_other() {
this.$refs.form.validate()
}
},
Using QForm
makes sense when you have more controls. You have only two so of course, you can leave out the QForm
, place refs
directly on both controls and use watchers to trigger the validation of the other control.
It is not very good solution but unfortunately the Quasar's internal validation is pretty limited. If you forms gets little bit more complicated I would recommend using external validation library - for examle Vuelidate
UPDATE: Updated my demo so all models are grouped together to one object. This allows only use single deep
watcher to trigger all validations...
Upvotes: 4