Skip to content

How to Fix Your EJS Modals When They Don't Show the Correct Info

2 min read

Does your EJS page behave incorrectly? You click on a button to open a modal only to find out it shows the wrong text? You're getting crazy if you don't find a solution any time soon and Stackoverflow couldn't help you. We've all been there. The code looks ok but the behaviour is super strange and you really can't explain why.

When you're displaying a list of items in EJS, or any other template engine for that matter, there's one thing to be aware of:

All id attributes inside HTML elements need to have unique values

This is a general requirement on all HTML pages. The purpose of the id attribute is to uniquely identify the element it belongs to when linking, scripting or styling.

Let's say we have a table with a couple of users. Inside each row, there's an action button that opens up a modal which shows info of that particular user and allows editing some fields. You would think to write something like this:

<% users.forEach((user) => { %>
<tr>
  <td><%= user._id %></td>
  <td><%= user.name %></td>
  <td><%= user.dateOfBirth %></td>
  <td><%= user.knownFor %></td>
  <td>
    <button type="submit" data-target="#modal-edit-user"> <!-- 🚫 all buttons link to first modal -->
      Edit
    </button>
  </td>
</tr>

<div id="modal-edit-user"> <!-- 🚫 multiple modals with same id -->
  <!-- Modal content -->
</div>
<% }) %>

The problem here is that for each user in the array you create a modal that has the same id as all the other ones. The browser looks at the first modal and disregards the others with duplicate id resulting in all buttons linking to the first modal. Which explains the strange behaviour we see.

To fix this we need to make the id of each modal unique. Usually, you choose a property that is unique to each item inside the array and append it to the id attribute. In our case, our user has a unique identifier from the database. You can also choose the index of the item in the array or put together two properties to create a unique combination.

Also to make sure we link each button to the correct modal we also change the data-target attribute in the same way.

<% users.forEach((user) => { %>
<tr>
  <td><%= user._id %></td>
  <td><%= user.name %></td>
  <td><%= user.dateOfBirth %></td>
  <td><%= user.knownFor %></td>
  <td>
    <button type="submit" data-target="#modal-edit-user-<%= user._id %>"> <!-- ✅ each buttons links to its corresponding modal -->
      Edit
    </button>
  </td>
</tr>

<div id="modal-edit-user-<%= user._id %>"> <!-- ✅ unique id for each modal -->
  <!-- Modal content -->
</div>
<% }) %>

Now our buttons link to their specific modal which shows the correct info for each user. No weird behaviour anymore. Everything works as it should!

Write clean code. Stay ahead of the curve.

Every other Tuesday, I share tips on how to build robust Node.js applications. Join a community of 1,450 developers committed to advancing their careers and gain the knowledge & skills you need to succeed.

No spam! 🙅🏻‍♀️ Unsubscribe at any time.

You might also like

ES Modules in Node.js

My notes on the ES Modules in Node.js presentation by Gil Tayar at Nodeconf Remote.
Read article

ESLint Setup in Node.js: A Detailed Guide

Unlock the power of ESLint in Node.js! Dive into this beginner-friendly guide for seamless integration and smarter coding.
Read article

Node.js 15 Is Out! What Does It Mean for You?

How does this new major release affect you? Find out what the breaking changes are and how to use the new features.
Read article