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

Express+Node.js开发TodoList:勾选复选框任务无下划线问题求助

问题分析与修复方案:Express TodoList 复选框下划线功能失效

我正在用Express.js和Node.js开发TodoList应用,需求是用户勾选任务复选框时,任务文本显示下划线效果。尝试用POST请求实现,但功能无法生效,相关代码如下:

原代码片段

index.js

let taskList = [];
let viewTaskList = ["Task 1","Task 2","Task 3","Task 4"];

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("public"));



app.get("/", (req, res) => {
    
    res.render("index.ejs", {
        views: viewTaskList
    });  

});


app.post("/today", (req, res) => {
    
    let itemName = req.body.task;
    let button = req.body.add;
    button = true;
    if (button) {
        taskList.push(itemName);   
    }

    res.render("index.ejs", {
        task: taskList,
        views: viewTaskList
    }); 

    let checkbox = req.body.checked;
    checkbox = true;
    if (checkbox) {
        res.render("index.ejs", {
            underlined: checkbox
        });
    } else {
        checkbox = false;
    }


});

index.ejs

<% if (locals.task) { %>
    <% task.forEach(tasks => { %>
        <div class="checkbox-div">
            <input type="checkbox" name="checked">
            <label for="checked">
                <% if (locals.underlined) { %>
                <u> <%= tasks %></u>
                <% } else { %>
                 <%=tasks %>
                 <% } %>
            </label>
        </div>  

    <% }) %>
   <% } %>
 

<form action="/submit" method="post">
    <input type="text" name="task" placeholder="New Item">
    <button type="submit" value="Add">+</button>
</form>

问题分析

  • 路由与表单不匹配:表单的action是/submit,但后端只处理了/today的POST请求,导致勾选或添加任务的请求根本没被正确接收。
  • 无任务状态管理:当前用字符串数组存储任务,没有为单个任务记录“是否勾选”的状态,全局的underlined变量无法区分不同任务的状态。
  • 渲染逻辑错误:在/today路由里,先调用res.render发送响应,后续代码不会执行;同时手动将button和checkbox设为true,完全忽略了实际的请求参数。
  • 复选框绑定混乱:所有复选框的name和label的for属性都是checked,导致多个复选框与label绑定错误,无法识别具体是哪个任务被勾选。

修复方案

1. 后端代码(index.js)调整

改用对象数组存储任务,为每个任务添加completed状态字段,统一处理表单请求:

let taskList = [];
// 初始化默认任务为带状态的对象
let viewTaskList = ["Task 1","Task 2","Task 3","Task 4"].map(item => ({
  name: item,
  completed: false
}));

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("public"));

app.get("/", (req, res) => {
  // 合并默认任务和用户新增任务,传递给模板
  res.render("index.ejs", {
    tasks: [...viewTaskList, ...taskList]
  });  
});

// 统一处理添加任务和勾选状态更新
app.post("/submit", (req, res) => {
  // 处理新增任务
  if (req.body.task) {
    taskList.push({
      name: req.body.task,
      completed: false
    });
  }

  // 处理复选框状态更新
  if (req.body.completedTasks) {
    // 兼容单个/多个勾选的情况
    const completedNames = Array.isArray(req.body.completedTasks) 
      ? req.body.completedTasks 
      : [req.body.completedTasks];
    // 更新所有任务的完成状态
    [...viewTaskList, ...taskList].forEach(task => {
      task.completed = completedNames.includes(task.name);
    });
  }

  // 重定向到首页,避免重复提交
  res.redirect("/");
});

2. 前端代码(index.ejs)调整

为每个复选框设置唯一标识,根据任务状态动态渲染下划线,统一表单提交:

<form action="/submit" method="post">
  <% tasks.forEach(task => { %>
    <div class="checkbox-div">
      <input 
        type="checkbox" 
        id="task-<%= task.name %>" 
        name="completedTasks" 
        value="<%= task.name %>"
        <%= task.completed ? 'checked' : '' %>
      >
      <label for="task-<%= task.name %>">
        <%= task.completed ? `<u>${task.name}</u>` : task.name %>
      </label>
    </div>  
  <% }) %>

  <div class="add-task">
    <input type="text" name="task" placeholder="New Item">
    <button type="submit">+</button>
  </div>
</form>

关键修复点说明

  • 用对象数组存储任务,每个任务包含name和completed字段,实现单个任务的状态管理。
  • 表单统一提交到/submit路由,同时处理添加任务和状态更新,解决路由不匹配问题。
  • 使用res.redirect代替直接渲染,避免用户刷新页面重复提交表单。
  • 每个复选框设置唯一id,确保label与对应复选框正确绑定,name设为数组形式completedTasks,方便后端接收多个勾选任务。

内容的提问来源于stack exchange,提问作者Yuval Yanay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:45:28