如何在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"); } });
功能验证流程
- 进入订单列表页,点击任意订单的更新按钮,弹出对应订单的模态框,自动选中当前订单状态
- 选择新的状态,点击保存按钮,表单提交到后端PATCH路由
- 路由更新数据库中对应订单的status字段,跳转回订单列表,即可看到更新后的状态,同时显示成功提示
内容的提问来源于stack exchange,提问作者prathamesh mungekar
相关产品推荐
相关产品推荐

