You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:50:37