如何在Node/Express中实现复选框数量验证与错误处理
解决EJS表单复选框数量限制验证问题
一、前端即时验证(提升用户体验)
在EJS页面的<head>标签内添加JavaScript代码,针对不同name属性的复选框组设置勾选数量限制,超出限制时自动取消新勾选操作并提示用户:
<script> // 定义各复选框组的勾选数量规则 const checkboxRules = { 'legsMain': 1, 'chestMain': 1, 'backMain': 1, 'shoulderMain': 1, 'legsSecond': 1, 'chestSecond': 1, 'backSecond': 1, 'accessory': 2 }; // 给所有复选框绑定点击事件 document.querySelectorAll('input[type="checkbox"]').forEach(checkbox => { checkbox.addEventListener('click', function() { const groupName = this.name; const maxAllowed = checkboxRules[groupName]; if (!maxAllowed) return; // 统计当前组已勾选的复选框数量 const checkedCount = document.querySelectorAll(`input[name="${groupName}"]:checked`).length; // 超出限制时取消当前勾选并提示 if (checkedCount > maxAllowed) { this.checked = false; alert(`该组最多只能选择${maxAllowed}个选项`); } }); }); </script>
二、后端路由验证(保障数据安全)
修改app.js中/print的POST路由,添加复选框数量验证逻辑,不符合规则时返回表单页面并携带错误提示:
app.post('/print/', async (req, res) => { const errors = []; const formData = req.body; // 定义验证规则,和前端逻辑保持一致 const validationRules = [ { name: 'legsMain', max: 1, label: '主项腿部训练' }, { name: 'chestMain', max: 1, label: '主项胸部训练' }, { name: 'backMain', max: 1, label: '主项背部训练' }, { name: 'shoulderMain', max: 1, label: '主项肩部训练' }, { name: 'legsSecond', max: 1, label: '次项腿部训练' }, { name: 'chestSecond', max: 1, label: '次项胸部训练' }, { name: 'backSecond', max: 1, label: '次项背部训练' }, { name: 'accessory', max: 2, label: '辅助训练' } ]; // 遍历规则验证每组复选框 validationRules.forEach(rule => { let checkedCount = 0; // 兼容单个勾选(字符串)和多个勾选(数组)的情况 if (Array.isArray(formData[rule.name])) { checkedCount = formData[rule.name].length; } else if (formData[rule.name]) { checkedCount = 1; } if (checkedCount > rule.max) { errors.push(`${rule.label}最多只能选择${rule.max}个选项`); } // 可选:添加必填验证,强制用户选择至少一个选项 // else if (checkedCount === 0) { // errors.push(`${rule.label}必须选择至少1个选项`); // } }); // 存在错误则返回对应表单页面,携带错误信息和用户之前的输入 if (errors.length > 0) { const week = await Week.findById(formData.weekId); let targetPage = ''; switch(week.name) { case 'threeX': targetPage = 'threeX'; break; case 'fourX': targetPage = 'fourX'; break; case 'sixX': targetPage = 'sixX'; break; } return res.render(targetPage, { week: formData.weekId, errors, formData }); } // 验证通过则保存数据并跳转 const newWorkout = new Workout(formData); await newWorkout.save(); res.redirect(`/print/${newWorkout._id}/${formData.weekId}`); })
三、前端展示错误信息与保留用户输入
在EJS表单页面的顶部添加错误信息展示区域,渲染后端传来的错误提示:
<% if (errors && errors.length > 0) { %> <div style="color: #dc3545; margin-bottom: 1rem; padding: 0.5rem; border: 1px solid #dc3545; border-radius: 4px;"> <% errors.forEach(error => { %> <p><%= error %></p> <% }) %> </div> <% } %>
同时,为复选框设置默认选中状态,保留用户之前的选择:
以chestMain组的复选框为例:
<label for="flatBench">Flat bench press</label> <input type="checkbox" name="chestMain" id="flatBench" value="Flat bench press" <% if (formData && formData.chestMain && (formData.chestMain === 'Flat bench press' || (Array.isArray(formData.chestMain) && formData.chestMain.includes('Flat bench press')))) { %> checked <% } %>>
内容的提问来源于stack exchange,提问作者Red Kakarot
相关产品推荐
相关产品推荐

