javascriptdialogmodal-dialog

How do I make my dialog-modal open a different modal for every link with the “data-open-modal” code?


I taught myself HTML, CSS, PHP, and MySQL many years ago, but I never got around to learning JavaScript. I’ve just picked up where I left off, but there are so many new things to learn since I last did any web coding. Can anyone help me with my JavaScript code as it currently is? I’ve only learned the basics of JS so far, and I can’t proceed with my project until I’ve learned a lot more.

Basically, my problem is, I want every edit button to open a unique dialog-modal, so far only the first one works.

const openButton = document.querySelector("[data-open-modal]")
const closeButton = document.querySelector("[data-close-modal]")
const modal = document.querySelector("[data-modal]")

openButton.addEventListener("click", () => {
  modal.showModal()
})
closeButton.addEventListener("click", () => {
  modal.close()
})

modal.addEventListener("click", e => {
  const dialogDimensions = modal.getBoundingClientRect()
  if (
    e.clientX < dialogDimensions.left ||
    e.clientX > dialogDimensions.right ||
    e.clientY < dialogDimensions.top ||
    e.clientY > dialogDimensions.bottom
  ) {
    modal.close()
  }
})
.rota-container {
  display: flex;
  flex-wrap: wrap;
  margin: 10px 0px 50px 0px;
}

.rota-item {
  flex: 1 0 13%;
  background-color: #dcdcdc;
  border: 1px solid #c0c0c0;
  height: auto;
  padding: 5px 0px 7px 0px;
}

.rota-item-day {
  height: auto;
  padding: 5px 0px 5px 0px;
  text-align: center;
  font-size: clamp(7px, 1.5vw, 50px);
  font-weight: bold;
  color: #000000;
}

.rota-date {
  text-align: right;
  margin: 0px 5px 0px 0px;
  font-size: clamp(7px, 1.5vw, 15px);
  color: #000000;
  font-family: Verdana, sans-serif;
}

.rota-edit {
  float: left;
  padding-left: 5px;
}

.rota-user {
  width: 90%;
  margin: 2px auto 0px auto;
  padding: 3px 0px 3px 3px;
  border-radius: clamp(0px, 0.4vw, 15px);
  color: white;
  font-size: clamp(7px, 1.5vw, 15px);
  font-family: Verdana, sans-serif;
}

.rota-user-1 {
  background-color: #008000;
  /*green*/
  border: 1px solid #008000;
}

.rota-user-2 {
  background-color: #cc006d;
  /*pink*/
  border: 1px solid #cc006d;
}

.rota-user-3 {
  background-color: #4b0082;
  /*blue*/
  border: 1px solid #4b0082;
}

.rota-user-4 {
  background-color: #707070;
  /*dark grey*/
  border: 1px solid #707070;
}

.rota-user-none {
  background-color: transparent;
  border: 1px solid transparent;
  color: transparent;
}

.modal {
  background-color: #f2f2f2;
  border: 1px solid #000000;
  border-radius: 10px;
  z-index: 10;
  padding: 20px;
}

.modal-container {
  display: grid;
  grid-template-columns: 1fr repeat(2, 1.5fr) 1fr;
  grid-template-rows: repeat(7, 1fr);
  grid-column-gap: 0px;
  grid-row-gap: 10px;
}

.modal-area-1 {
  grid-area: 2 / 2 / 3 / 3;
}

.modal-area-2 {
  grid-area: 3 / 2 / 4 / 3;
}

.modal-area-3 {
  grid-area: 4 / 2 / 5 / 3;
}

.modal-area-4 {
  grid-area: 5 / 2 / 6 / 3;
}

.modal-area-5 {
  grid-area: 6 / 2 / 7 / 3;
}

.modal-area-6 {
  grid-area: 2 / 3 / 3 / 4;
}

.modal-area-7 {
  grid-area: 3 / 3 / 4 / 4;
}

.modal-area-8 {
  grid-area: 4 / 3 / 5 / 4;
}

.modal-area-9 {
  grid-area: 5 / 3 / 6 / 4;
}

.modal-area-10 {
  grid-area: 6 / 3 / 7 / 4;
}

.modal-area-11 {
  grid-area: 2 / 4 / 3 / 5;
}

.modal-area-12 {
  grid-area: 3 / 4 / 4 / 5;
}

.modal-area-13 {
  grid-area: 4 / 4 / 5 / 5;
}

.modal-area-14 {
  grid-area: 5 / 4 / 6 / 5;
}

.modal-area-15 {
  grid-area: 6 / 4 / 7 / 5;
}

.modal-area-16 {
  grid-area: 1 / 2 / 2 / 3;
}

.modal-area-17 {
  grid-area: 1 / 3 / 2 / 4;
}

.modal-area-18 {
  grid-area: 2 / 1 / 3 / 2;
}

.modal-area-19 {
  grid-area: 3 / 1 / 4 / 2;
}

.modal-area-20 {
  grid-area: 4 / 1 / 5 / 2;
}

.modal-area-21 {
  grid-area: 5 / 1 / 6 / 2;
}

.modal-area-22 {
  grid-area: 6 / 1 / 7 / 2;
}

.modal-area-23 {
  grid-area: 7 / 4 / 8 / 5;
}
<div class="rota-container">
  <div class="rota-item rota-item-day">Monday</div>
  <div class="rota-item rota-item-day">Tuesday</div>
  <div class="rota-item rota-item-day">Wednesday</div>
  <div class="rota-item rota-item-day">Thursday</div>
  <div class="rota-item rota-item-day">Friday</div>
  <div class="rota-item rota-item-day">Saturday</div>
  <div class="rota-item rota-item-day">Sunday</div>
  <div class="rota-item">
    <div class="rota-date"><a class="rota-edit" data-open-modal>Edit</a>21</div>
    <div class="rota-user rota-user-1">8am-1pm</div>
    <div class="rota-user rota-user-none">1pm-4pm</div>
    <div class="rota-user rota-user-4">4pm-5pm</div>
    <div class="rota-user rota-user-none">5pm-9pm</div>
    <div class="rota-user rota-user-1">9pm-8am</div>
  </div>
  <div class="rota-item">
    <div class="rota-date"><a class="rota-edit" data-open-modal>Edit</a>22</div>
    <div class="rota-user rota-user-1">8am-1pm</div>
    <div class="rota-user rota-user-none">1pm-4pm</div>
    <div class="rota-user rota-user-2">4pm-5pm</div>
    <div class="rota-user rota-user-2">5pm-9pm</div>
    <div class="rota-user rota-user-2">9pm-8am</div>
  </div>
  <div class="rota-item">
    <div class="rota-date"><a class="rota-edit" data-open-modal>Edit</a>23</div>
    <div class="rota-user rota-user-2">8am-1pm</div>
    <div class="rota-user rota-user-none">1pm-4pm</div>
    <div class="rota-user rota-user-4">4pm-5pm</div>
    <div class="rota-user rota-user-none">5pm-9pm</div>
    <div class="rota-user rota-user-2">9pm-8am</div>
  </div>
  <div class="rota-item">
    <div class="rota-date"><a class="rota-edit" data-open-modal>Edit</a>24</div>
    <div class="rota-user rota-user-2">8am-1pm</div>
    <div class="rota-user rota-user-none">1pm-4pm</div>
    <div class="rota-user rota-user-3">4pm-5pm</div>
    <div class="rota-user rota-user-3">5pm-9pm</div>
    <div class="rota-user rota-user-3">9pm-8am</div>
  </div>
  <div class="rota-item">
    <div class="rota-date"><a class="rota-edit" data-open-modal>Edit</a>25</div>
    <div class="rota-user rota-user-3">8am-1pm</div>
    <div class="rota-user rota-user-none">1pm-4pm</div>
    <div class="rota-user rota-user-4">4pm-5pm</div>
    <div class="rota-user rota-user-none">5pm-9pm</div>
    <div class="rota-user rota-user-3">9pm-8am</div>
  </div>
  <div class="rota-item">
    <div class="rota-date"><a class="rota-edit" data-open-modal>Edit</a>26</div>
    <div class="rota-user rota-user-3">8am-1pm</div>
    <div class="rota-user rota-user-none">1pm-4pm</div>
    <div class="rota-user rota-user-4">4pm-5pm</div>
    <div class="rota-user rota-user-none">5pm-9pm</div>
    <div class="rota-user rota-user-3">9pm-8am</div>
  </div>
  <div class="rota-item">
    <div class="rota-date"><a class="rota-edit" data-open-modal>Edit</a>27</div>
    <div class="rota-user rota-user-3">8am-1pm</div>
    <div class="rota-user rota-user-none">1pm-4pm</div>
    <div class="rota-user rota-user-4">4pm-5pm</div>
    <div class="rota-user rota-user-none">5pm-9pm</div>
    <div class="rota-user rota-user-1">9pm-8am</div>
  </div>
</div>

<dialog class="modal" data-modal>
  <form method="post" action="" class="modal-container">

    <div class="modal-area-1"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-2"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-3"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-4"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-5"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-6"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-7"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-8"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-9"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-10"><input type="text" name="time-start-1" value="" /></div>
    <div class="modal-area-11">
      <select id="time-employee-1" name="time-employee-1">
        <option value="Helping Hands">None</option>
        <option value="Helping Hands">Helping Hands</option>
        <option value="Emma Cooper">Emma Cooper</option>
        <option value="Savannah Gregoire">Savannah Gregoire</option>
        <option value="Tracy Walker">Tracy Walker</option>
      </select>
    </div>
    <div class="modal-area-12">
      <select id="time-employee-1" name="time-employee-1">
        <option value="Helping Hands">None</option>
        <option value="Helping Hands">Helping Hands</option>
        <option value="Emma Cooper">Emma Cooper</option>
        <option value="Savannah Gregoire">Savannah Gregoire</option>
        <option value="Tracy Walker">Tracy Walker</option>
      </select>
    </div>
    <div class="modal-area-13">
      <select id="time-employee-1" name="time-employee-1">
        <option value="Helping Hands">None</option>
        <option value="Helping Hands">Helping Hands</option>
        <option value="Emma Cooper">Emma Cooper</option>
        <option value="Savannah Gregoire">Savannah Gregoire</option>
        <option value="Tracy Walker">Tracy Walker</option>
      </select>
    </div>
    <div class="modal-area-14">
      <select id="time-employee-1" name="time-employee-1">
        <option value="Helping Hands">None</option>
        <option value="Helping Hands">Helping Hands</option>
        <option value="Emma Cooper">Emma Cooper</option>
        <option value="Savannah Gregoire">Savannah Gregoire</option>
        <option value="Tracy Walker">Tracy Walker</option>
      </select>
    </div>
    <div class="modal-area-15">
      <select id="time-employee-1" name="time-employee-1">
        <option value="Helping Hands">None</option>
        <option value="Helping Hands">Helping Hands</option>
        <option value="Emma Cooper">Emma Cooper</option>
        <option value="Savannah Gregoire">Savannah Gregoire</option>
        <option value="Tracy Walker">Tracy Walker</option>
      </select>
    </div>
    <div class="modal-area-16">Start</div>
    <div class="modal-area-17">Finish</div>
    <div class="modal-area-18">Morning</div>
    <div class="modal-area-19">Afternoon</div>
    <div class="modal-area-20">Teatime</div>
    <div class="modal-area-21">Evening</div>
    <div class="modal-area-22">Night time</div>
    <div class="modal-area-23"><button data-close-modal>Close</button></div>

  </form>
</dialog>


Solution

  • The Problem :D

    You are using document.querySelector, which is designed to find only the first element that matches the selector [data-open-modal]. That's why only your first "Edit" button works.

    The Solution c;

    To fix this, you need to use document.querySelectorAll to get a list of all matching buttons. Then, you loop over that list and add an event listener to each one individually.

    Updated JavaScript

    Replace your current JavaScript with this. The logic for closing the modal is correct and does not need to change.

    // Select ALL buttons that open the modal
    const openButtons = document.querySelectorAll("[data-open-modal]");
    const closeButton = document.querySelector("[data-close-modal]");
    const modal = document.querySelector("[data-modal]");
    
    // Loop over each open button and add a click event
    openButtons.forEach(button => {
      button.addEventListener("click", () => {
        // When any of them are clicked, show the modal
        modal.showModal();
        
        // Bonus: If you want to know WHICH day was clicked, you can get its data.
        // To make this work, change your HTML from <a data-open-modal> to <a data-date="21">
        // Then you could uncomment this line:
        // console.log("Editing date:", button.dataset.date); 
      });
    });
    
    // This part of your code is perfect and remains the same
    closeButton.addEventListener("click", () => {
      modal.close();
    });
    
    modal.addEventListener("click", e => {
      const dialogDimensions = modal.getBoundingClientRect();
      if (
        e.clientX < dialogDimensions.left ||
        e.clientX > dialogDimensions.right ||
        e.clientY < dialogDimensions.top ||
        e.clientY > dialogDimensions.bottom
      ) {
        modal.close();
      }
    });
    

    This code finds every "Edit" link and attaches the logic to open the modal. Now, every button will work how you expect.