'Varying Modal Content using forEach in Node/EJS
Situation:
I'm passing an array of objects (days
) into an EJS template and running a forEach loop. Each iteration creates a card, a modal trigger button, and a modal.
The Problem:
Each card and trigger modal button are created no problem. However, the modal window only displays the data from the first loop iteration (day[0]
).
My Code:
Head Partial:
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta charset="UTF-8" />
<title>Slope Notes</title>
<!-- CSS (load bootswatch from a CDN) -->
<link
rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/minty/bootstrap.min.css" integrity="sha384 H4X+4tKc7b8s4GoMrylmy2ssQYpDHoqzPa9aKXbDwPoPUA3Ra8PA5dGzijN+ePnH" crossorigin="anonymous"/>
<!-- public/styles.css -->
<link rel="stylesheet" type="text/css" href="/styles.css" />
<!-- font-awesome kit -->
<script src="https://kit.fontawesome.com/46ee1546cc.js"
crossorigin="anonymous"></script>
<head>
<%- include('../partials/head'); %>
</head>
<body class="container">
<header><%- include('../partials/header'); %></header>
<% let formattedDate = ('0' + (days[0].date.getMonth()+1)).slice(-2) + '-' +
('0' + days[0].date.getDate()).slice(-2) + '-' + days[0].date.getFullYear() %>
<div class="list-group page-title-container list-group-item active">
<h2 class="page-title"><%= days[0].resortName %></h2>
<h2 class="page-title"><%= formattedDate %></h2>
<a class="btn-anchor btn-secondary" href="/date/new">
<i class="fa-solid fa-plus"></i>
Add Run
</a>
</div>
<div class="card-columns">
<% days.forEach((day, i) => { %>
<div class="card bg-secondary container">
<div class="row ard-header day-card-header-container">
<div class="col"><%= day.runName %></div>
<div class="col"><%= day.runDifficulty %></div>
<div class="col">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#runModal" data-whatever="<%= day.id%>">
View
</button>
<!-- Modal -->
<div class="modal fade" id="runModal" tabindex="-1" role="dialog" aria-labelledby="runModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="runModalLabel"><%= day.runName %></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body container">
<div class="row">
<div class="col">Rating: <%= day.runDifficulty %></div>
<div class="col">Time (in min): <%= day.runTime %></div>
</div>
<div class="row">
<div class="col">Weather: <%= day.weatherConditions %></div>
<div class="col">Wind: <%= day.windConditions %></div>
</div>
<div class="row">
<div class="col">Snow: <%= day.snowConditions %></div>
</div>
<div class="row">
<div class="form-group">
<label for="runNotes" class="form-label mt-4">Extra Notes:</label>
<textarea class="form-control" id="runNotes" rows="5" cols="55"><%= day.runNotes %></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<% }) %>
</div>
<footer><%- include('../partials/footer'); %></footer>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
Solution 1:[1]
Found the problem in case anyone else stumbles across this -
The issue stemmed from not passing a unique document identifier. The changes in the code are in the modal button's data-target
and the modal id
:
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#runModal<%= _day.id %>"
View
</button>
<!-- Modal -->
<div class="modal fade" id="runModal<%= day._id %>" tabindex="-1" role="dialog" aria-labelledby="runModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | jacver |