I have the code below which is working as expected. It is doing a form validation with Vue.js and Vee-Validate. It is checking that at least one checkbox is checked.
I only don't like that I have to manually call validate for oneChecked-Validator on form submission. With-out the call it's not validating on submit.
It would be great if someone could review my code and give me an advice to the following points:
How can I configure Vee Validator so that it evaluates the oneChecked validator with the call of
this.$validator.validateAll();
?Is it possible to pass the
this.options
array into validate method of oneChecked validator? (Would be more re-usable. I've tried passing as array withJSON.stringify
but couldn't get it to work.)
If there is more to improve please let me know. I'm using Vee-Validate for the first time.
You can also find the same code at jsfiddle.
const Checkboxes = {
template: '#checkboxTmpl',
data() {
return {
text: '',
options: [{
id: 0,
checked: false
}, {
id: 1,
checked: false
}, {
id: 2,
checked: false
}]
};
},
created() {
this.$validator.extend('oneChecked', {
getMessage: field => 'At least one ' + field + ' needs to be checked.',
validate: (value, [testProp]) => {
const options = this.options;
// console.log('questions', value, testProp, options.some((option) => option[testProp]));
return value || options.some((option) => option[testProp]);
}
});
},
methods: {
validateBeforeSubmit(e) {
this.$validator.validateAll(); // why is oneChecked not validated here? --> manually trigger validate below
this.options.forEach((option) => {
this.$validator.validate('check0', option.checked, ['checked'])
});
console.log('validator', this.errors);
if (!this.errors.any()) {
alert('succesfully submitted!');
}
}
}
};
Vue.use(VeeValidate);
const app = new Vue({
el: '#app',
render: (h) => h(Checkboxes)
})
<script src="https://cdn.jsdelivr.net/vee-validate/2.0.0-beta.18/vee-validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.js"></script>
<div id="app">
</div>
<script id="checkboxTmpl" type="text/template">
<form @submit.prevent="validateBeforeSubmit">
<input v-model="text" name="text" v-validate.initial="text" data-vv-rules="required|min:3" placeholder="required input" />
<p v-show="errors.has('text')">{{ errors.first('text') }}</p>
<br/>
<label v-for="(option, index) in options">
<input type="checkbox" v-model="option.checked" name="check0" v-validate.initial="option.checked" data-vv-rules="oneChecked:checked" data-vv-as="checkbox" />Checkbox {{index}}
</label>
<p v-show="errors.has('check0')">{{ errors.first('check0') }}</p>
<pre>{{options}}</pre>
<button type="submit">Submit</button>
</form>
</script>
1 Answer 1
How can I configure Vee Validator so that it evaluates the oneChecked validator with the call of this.$validator.validateAll();?
Yes, you can use validateAll()
, you're just not passing the fields for it to validate. Here's an example on how to do this:
methods: {
validateBeforeSubmit(e) {
this.$validator.validateAll({
name0: true
});
console.log('validator', this.errors);
if (!this.errors.any()) {
alert('succesfully submitted!');
}
}
}
Taken from here.
Is it possible to pass the this.options array into validate method of oneChecked validator? (Would be more re-usable. I've tried passing as array with JSON.stringify but couldn't get it to work.)
Why pass it as a parameter when it's already a constant?
Consider this:
created() {
this.$validator.extend('oneChecked', {
getMessage: field => 'At least one ' + field + ' needs to be checked.',
validate: (value, [testProp]) => {
return value || Checkboxes.data().options.some((option) => option[testProp]);
}
});
},
This also provides you some protection for when data().options inevitably has more than 3 elements in it.
-
\$\begingroup\$ Thanks for your answer. The way with
validateAll
to pass a reference name was new for me and it simplifies code because I can create a map for all checkbox groups and pass it to validateAll. That's easier than callingvalidate
with all parameters. But it breaks the validation of text input - not sure why (see this fiddle). Also what does thetrue
mean inside the passed object? I had to passfalse
to make the validation work. In my demo it's working by accessing the constant but I'd like to have it more flexible. (that's OK now -see fiddle) \$\endgroup\$AWolf– AWolf2017年01月15日 17:18:59 +00:00Commented Jan 15, 2017 at 17:18 -
\$\begingroup\$ @AWolf I have the same problem like u, and I think I am missing some information. I asked my question on github: github.com/baianat/vee-validate/issues/1674 Maybe you can share some insights on the questions I asked there: Most important: why is my rule not validated anyway? Why do we need something like your
validateBeforeSubmit
. Thank you in advance. \$\endgroup\$Merc– Merc2018年10月24日 23:40:32 +00:00Commented Oct 24, 2018 at 23:40