简体   繁体   English

我正在尝试实现VeeValidate以检查是否至少选中了一个复选框

[英]I'm trying to implement VeeValidate to check if at least one checkbox is checked

I found a jsfiddle example that I forked and then edited. 我找到一个我分叉然后编辑的jsfiddle示例。 I don't understand what's going on or how to fix it. 我不知道发生了什么或如何解决。 In my example I'm using checkboxes with values but when I click a checkbox the value is changed to true or false depending on if the checkbox is clicked. 在我的示例中,我使用的是带有值的复选框,但是当我单击一个复选框时,该值将更改为true或false,具体取决于是否单击了该复选框。

 const Checkboxes = { template: '#checkboxTmpl', data() { return { text: '', options: [ { name: 'Web', slug: 'web' }, { name: 'iOS', slug: 'ios' }, { name: 'Android', slug: 'android' } ] }; }, 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('platforms', option.slug, ['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"> <label v-for="(option, index) in options"> <input type="checkbox" v-model="option.slug" name="platform" v-validate.initial="option.slug" data-vv-rules="oneChecked:checked" data-vv-as="platform"/> {{option.name}} </label> <p v-show="errors.has('platform')">{{ errors.first('platform') }}</p> <pre>{{options}}</pre> <button type="submit">Submit</button> </form> </script> 

I don't understand why all of the checkboxes are checked and unchecking one of them returns a validation error even though two are still checked. 我不明白为什么所有的复选框都被选中,并且即使其中两个仍处于选中状态,取消选中其中一个也会返回验证错误。 I like that errors are shown before the form is submitted but unchecking all and then submitting doesn't trigger the validation error. 我喜欢在提交表单之前显示错误,但是取消选中所有复选框然后提交不会触发验证错误。

I'm using VeeValidate because that is what the example uses but any other solution would be fine. 我正在使用VeeValidate,因为该示例使用的是VeeValidate,但任何其他解决方案都可以。 I don't want to use jQuery in my vue.js application. 我不想在我的vue.js应用程序中使用jQuery。

I would really like to understand what is going on. 我真的很想了解发生了什么。

There was two main problems going on : 发生两个主要问题:

  1. Using v-model on the wrong key. 在错误的键上使用v-model In fact, each time the checkbox was checked or unchecked, it will emit an input event that will modify the original slug of the option (in your data ). 实际上,每次选中或取消选中此复选框时,它都会发出一个输入事件,该事件将修改该选项的原始段(在您的data )。 Instead, you need to add a checked field in your option. 相反,您需要在选项中添加一个checked字段。 Then in your template add the :checked attribute and modify your v-model to be :option.checked . 然后在模板中添加:checked属性,并将v-model修改为:option.checked
  2. As the docs of VeeValidate say, you can just use the required rule to make sure a checkbox has to be checked to submit your form. 正如VeeValidate的文档所说,您可以只使用required规则来确保必须选中一个复选框才能提交表单。 Here is the link towards the docs. 这是指向文档的链接 Therefore, you don't need your created block. 因此,您不需要created块。

Additionally, the validateAll function returns a promise containing the result of the validation. 此外, validateAll函数还返回一个包含验证结果的promise。 So no need to use this.errors.any() too. 因此也无需使用this.errors.any()

Also, I upgraded the VeeValidate library to the latest as you used a beta. 另外,当您使用Beta时,我将VeeValidate库升级到了最新版本。

Here is the working code : 这是工作代码:

 const Checkboxes = { template: '#checkboxTmpl', data() { return { text: '', options: [{ name: 'Web', slug: 'web', checked: false }, { name: 'iOS', slug: 'ios', checked: true }, { name: 'Android', slug: 'android', checked: true } ] }; }, methods: { validateBeforeSubmit(e) { this.$validator.validateAll().then(value => { if (value) { alert('successfully submitted') } }) } } }; Vue.use(VeeValidate); const app = new Vue({ el: '#app', render: (h) => h(Checkboxes) }) 
 <div id="app"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.js"></script> <script src="https://unpkg.com/vee-validate@latest"></script> <script id="checkboxTmpl" type="text/template"> <form @submit.prevent="validateBeforeSubmit"> <label v-for="(option, index) in options"> <input type="checkbox" :checked="option.checked" v-model="option.checked" name="platform" v-validate="'required'"/> {{option.name}} </label> <p v-show="errors.has('platform')">{{ errors.first('platform') }}</p> <pre>{{options}}</pre> <button type="submit">Submit</button> </form> </script> 

Hope that helps! 希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM