I am working on e-commerce app using ejs template and nodejs as backend . In that I have admin role for administrative work . I create Bootstrap modal for update the order status . But I am able to only update the first order , if I try to any other order only first order gets update . Can anyone please help me to sort out this problem .
allOrders.ejs (list of orders & modal)
<%- include("../partials/header") %> <%- include("../partials/navbar") %>
<div class="container-fluid">
<h3 class="text-center mt-2">All Orders</h3>
<table class="table table-bordered border-primary mt-4 mb-3">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Order Date</th>
<th scope="col">Order Updated Date</th>
<th scope="col">Status</th>
<th scope="col">Amount</th>
<th scope="col">Actions</th>
</tr>
</thead>
<% 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 className="bg-secondary">
<!-- Button trigger modal -->
<button
type="button"
class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#exampleModal"
>
Update
</button>
<!-- Modal For Edit Status-->
<div
class="modal fade"
id="exampleModal"
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">
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"
novalidate
>
<div class="mb-3">
<label for="orderId" class="form-label">Order ID</label>
<input
type="text"
class="form-control"
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" class="form-label"
>Update Staus
</label>
<select
class="form-select form-control"
name="status"
value="status"
>
<option name="Processing" value="Processing">
Processing
</option>
<option name="Prepared" value="Prepared">
Prepared
</option>
<option name="Dispatched" value="Dispatched">
Dispatched
</option>
<option name="Delivered" value="Delivered">
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"
>
Cancle
</button>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
<% } %>
</table>
</div>
<%- include("../partials/footer") %>
routes for order
const express = require("express");
const router = express.Router();
const { isLoggedIn } = require("../middlewere");
const Order = require("../models/order");
router.get("/admin/:id/allorders", isLoggedIn, async (req, res) => {
try {
const allOrders = await Order.find({}).sort({ date: -1 });
res.render("admin/allOrders", { allOrders });
} catch (error) {
req.flash("error", "Cannot Find Orders");
res.render("error");
}
});
router.patch("/admin/:id/order/:orderId", isLoggedIn, async (req, res) => {
try {
await Order.findByIdAndUpdate(req.params.orderId, req.body);
req.flash("success", "Order Updated Successfully");
res.redirect(`/admin/${req.params.id}/allorders`);
} catch (error) {
req.flash("error", "Cannot Update Order");
res.render("error");
}
});
module.exports = router;
I am able to fetch all orders but in modal it always shows first order details . I check code from Devtool (https://codeshare.io/8pyknv) also it showing correct info . But modal not showing it .
The problem exists inside the for loop. In your loop you have a button with an attribute data-bs-target="#exampleModal"
. That means all rows in your table will have the same button which triggers the modal with id exampleModal
. All these button will call the same modal.
Apart from this, each order generates a modal with a specific id exampleModal. So all modals have the same id. That's why you always open the first modal. Each modal must have a unique id
To fix this problem, you should give unique ids to modals, for example
<div
class="modal fade"
id="Modal<%= order._id %>"
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
and each button should call its own modal,
<button
type="button"
class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#Modal<%= order._id %>"
>