javascript - 我正在尝试实施 VeeValidate 以检查是否至少选中了一个复选框
问题描述
我找到了一个我分叉然后编辑的 jsfiddle 示例。我不明白发生了什么或如何解决它。在我的示例中,我使用带有值的复选框,但是当我单击复选框时,值将根据是否单击复选框更改为 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>
我不明白为什么所有复选框都被选中并且取消选中其中一个会返回验证错误,即使仍然选中了两个。我喜欢在提交表单之前显示错误,但取消选中所有然后提交不会触发验证错误。
我正在使用 VeeValidate,因为这是示例使用的,但任何其他解决方案都可以。我不想在我的 vue.js 应用程序中使用 jQuery。
我真的很想了解发生了什么。
解决方案
有两个主要问题:
v-model
在错误的键上使用。实际上,每次选中或取消选中复选框时,它都会发出一个输入事件,该事件将修改选项的原始 slug(在您的data
. 相反,您需要checked
在选项中添加一个字段。然后在您的模板中添加:checked
属性并将您的修改v-model
为:option.checked
.- 正如 VeeValidate 的文档所说,您可以使用该
required
规则来确保必须选中一个复选框才能提交您的表单。这是指向文档的链接。因此,你不需要你的created
块。
此外,该validateAll
函数返回一个包含验证结果的承诺。所以也不需要使用this.errors.any()
。
此外,当您使用测试版时,我将 VeeValidate 库升级到了最新版本。
这是工作代码:
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>
希望有帮助!
推荐阅读
- html - select tag under select tag
- java - how to use one of the options (flag) as an argument for another option (Apache.commons.cli)?
- r - R - Trouble installing tabular package
- sql - 在不指定所有列的情况下向 SQL 查询添加额外的行
- android - 第一次“共享”后图像 URI 未更新
- c++ - 为什么 std::{container}::emplace 不推断其参数类型?
- loops - Loop preventing event from firing
- swift - 插入或更新对象时,NSFetchedResultsController 未检测到更改类型
- c# - Xamarin.Android 中的 X509Store 为空
- javascript - 反应返回带有变量值的 HTML