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

如何在EJS中使用Bootstrap模态框编辑数据并提交到MongoDB

实现方案

你的现有代码存在几个核心问题,修复后即可正常实现模态框提交数据更新到数据库的功能:

1. 前置依赖检查:确保安装method-override

express默认不支持表单直接发送PUT/PATCH请求,你用了?_method=PATCH参数需要先配置这个中间件:

  • 安装依赖:npm install method-override
  • 在项目入口文件(通常是app.js/server.js)中引入配置:
const methodOverride = require('method-override');
app.use(methodOverride('_method'));

2. 修复allorders.ejs代码问题

核心问题:

  • 循环生成的模态框ID重复,所有触发按钮都指向同一个ID的模态框,导致只能操作第一个订单
  • 下拉选择框没有匹配当前订单状态的默认选中值
  • 代码存在拼写错误、属性写法错误

修改后的ejs核心代码片段:

<% for(let order of allOrders ){ %>
<tbody>
  <tr>
    <td><%= order._id %></td>
    <td><%= order.date %></td>
    <td><%= order.updatedAt %></td>
    <td><%= order.status %></td>
    <td><%= order.amount %></td>
    <td class="bg-secondary">
      <!-- 按钮target绑定对应订单ID的模态框 -->
      <button
        class="btn btn-primary"
        data-bs-toggle="modal"
        data-bs-target="#staticBackdrop<%= order._id %>"
      >
        Update
      </button>

      <!-- 模态框ID绑定订单ID,保证全局唯一 -->
      <div
        class="modal fade"
        id="staticBackdrop<%= order._id %>"
        data-bs-backdrop="static"
        data-bs-keyboard="false"
        tabindex="-1"
        aria-labelledby="staticBackdropLabel<%= order._id %>"
        aria-hidden="true"
      >
        <div class="modal-dialog modal-dialog modal-lg">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="staticBackdropLabel<%= order._id %>">
                Update Order Status
              </h5>
              <button
                type="button"
                class="btn-close"
                data-bs-dismiss="modal"
                aria-label="Close"
              ></button>
            </div>
            <form
              class="m-5"
              action="/admin/<%= currentUser._id %>/order/<%=order._id%>?_method=PATCH"
              method="POST"
            >
              <div class="mb-3">
                <label for="orderId<%= order._id %>" class="form-label">Order ID</label>
                <input
                  type="text"
                  class="form-control"
                  id="orderId<%= order._id %>"
                  disabled
                  value="<%= order._id %>"
                />
                <label class="form-label">Current Status</label>
                <input
                  type="text"
                  class="form-control"
                  disabled
                  value="<%= order.status %>"
                />
                <div class="mb-4">
                  <label for="updateStatus<%= order._id %>" class="form-label">
                    Update Status
                  </label>
                  <select
                    class="form-select form-control"
                    name="status"
                    id="updateStatus<%= order._id %>"
                  >
                    <option value="Processing" <%= order.status === 'Processing' ? 'selected' : '' %>>
                      Processing
                    </option>
                    <option value="Prepared" <%= order.status === 'Prepared' ? 'selected' : '' %>>
                      Prepared
                    </option>
                    <option value="Dispatched" <%= order.status === 'Dispatched' ? 'selected' : '' %>>
                      Dispatched
                    </option>
                    <option value="Delivered" <%= order.status === 'Delivered' ? 'selected' : '' %>>
                      Delivered
                    </option>
                  </select>
                </div>
              </div>
              <button type="submit" class="btn btn-primary save">
                Save Status
              </button>
            </form>
            <div class="modal-footer">
              <button
                type="button"
                class="btn btn-secondary"
                data-bs-dismiss="modal"
              >
                Cancel
              </button>
            </div>
          </div>
        </div>
      </div>
    </td>
  </tr>
</tbody>
<% } %>

3. 修复路由代码问题

现有GET路由渲染页面时没有传递currentUser变量,导致ejs中读取currentUser._id会报错,修改后代码:

router.get("/admin/:id/allorders", isLoggedIn, async (req, res) => {
  try {
    const allOrders = await Order.find({}).sort({ date: -1 });
    // 传入currentUser变量,isLoggedIn中间件一般会把登录用户挂载到req.user,根据你的实际逻辑调整即可
    res.render("admin/allOrders", { allOrders, currentUser: req.user });
  } catch (error) {
    req.flash("error", "Cannot Find Orders");
    res.render("error");
  }
});

router.patch("/admin/:id/order/:orderId", isLoggedIn, async (req, res) => {
  try {
    // 明确指定更新status字段,避免非法参数注入
    await Order.findByIdAndUpdate(req.params.orderId, { status: req.body.status });
    req.flash("success", "Order Updated Successfully");
    res.redirect(`/admin/${req.params.id}/allorders`);
  } catch (error) {
    req.flash("error", "Cannot Update Order");
    res.render("error");
  }
});

功能验证流程

  1. 进入订单列表页,点击任意订单的更新按钮,弹出对应订单的模态框,自动选中当前订单状态
  2. 选择新的状态,点击保存按钮,表单提交到后端PATCH路由
  3. 路由更新数据库中对应订单的status字段,跳转回订单列表,即可看到更新后的状态,同时显示成功提示

内容的提问来源于stack exchange,提问作者prathamesh mungekar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 03:54:00