neumear
neumear

Reputation: 121

Generating unique modals for each element in php

I have this project where the user selects an item from a list (fetched from a MySQL database), then outputs buttons named from the item as such:

p

My (stripped down) code so far:

<!DOCTYPE html>
<html>
</head>
    <body>
    <h2>Select User:</h2>
    <div>
    <form method="POST">
    <table border="5">
       <thead>
           <th></th>
           <th>Subject</th>

        </thead>
        <tbody>
<?php
            include('get.php');
               $query=mysqli_query($conn,"select * from `subjects`");
            while($row=mysqli_fetch_array($query)){
         ?>
            <tr>
                <td><input type="checkbox" value="<?php echo $row['subject']; ?>" name="id[]"></td>
                <td><?php echo $row['subject']; ?></td>
            </tr>
            <?php
          }
       ?>
   </tbody>
    </table>
<br>
<input type="submit" name="submit" value="Submit">
   </form>
    </div>
    <div>
        <h2>Subjects selected:</h2>
    <?php
        if (isset($_POST['submit'])){
            foreach ($_POST['id'] as $id):
                $sq=mysqli_query($conn,"select * from `subjects` where subject='$id'");
                $srow=mysqli_fetch_array($sq);
    ?>
            <button class="button animate" id="myBtn">
                <span> 
                    <?php echo $srow['subject']; ?> 
                 </span> 
             </button>
            <?php
              endforeach;
              }
            ?>
        </div>
        <div id="myModal" class="modal">
      <div class="modal-content">
       <span class="close">&times;</span>
      <p>Some text in the Modal..</p>
   </div>
  <script>

var modal = document.getElementById("myModal");
var btn = document.getElementById("myBtn");
var span = document.getElementsByClassName("close")[0];

 btn.onclick = function() {
 modal.style.display = "block";
   }
span.onclick = function() {
  modal.style.display = "none";
  }
window.onclick = function(event) {
  if (event.target == modal) {
  modal.style.display = "none";
 }
   }
   </script>

I was able to make a modal for one button but I want to make a unique modal for each button. How can I do this? Thanks.

Upvotes: 1

Views: 209

Answers (1)

Emiel Zuurbier
Emiel Zuurbier

Reputation: 20954

Write a function which will build a modal for you. Have this function accept some input, like the content of the modal which you want to show. Then add the modal to the page. This way you can generate an infinite amount of different modals based on the button that you click on.

I've made an example below which demonstrates how this could work. The example works with building a modal, with the same structure of your example, and use the value attribute of the button the set the content of that modal. For simple text this works fine, but for larges chunks of HTML you might consider getting your content from a hidden element and copy the innerHTML value of that element.

// Flag for checking if a modal is already opened.
// This way we can keep track of the opened modal and
// not open a second one before closing the first.
let modalOpen = false;

function createModal(html = '') {

  // Create the elements.
  const modal = document.createElement('div');
  const content = document.createElement('div');
  const close = document.createElement('span');
  
  // Add classes to the elements.
  modal.classList.add('modal');
  content.classList.add('modal-content');
  close.classList.add('close', 'js-close-modal');
  
  // Add content to the elements.
  content.insertAdjacentHTML('beforeend', html);
  close.innerHTML = '&times;';
  
  // Append children to parents and to the document.
  content.appendChild(close);
  modal.appendChild(content);
  document.body.appendChild(modal);
  
  return modal;
  
}

// Listen for clicks in the document.
document.addEventListener('click', event => {

  // If the create modal button has been clicked, create a modal.
  const button = event.target.closest('.js-create-modal');
  if (button !== null && modalOpen === false) {
    const html = button.value;
    createModal(html);
    modalOpen = true;
  }
  
  // If the close modal has been clicked, remove the modal.
  const close = event.target.closest('.js-close-modal');
  if (close !== null) {
    const modal = close.closest('.modal');
    modal.remove();
    modalOpen = false;
  }
  
});
*, *::before, *::after {
  box-sizing: border-box;
}

.modal {
  display: block;
  position: fixed;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 90%;
  max-width: 32em;
  max-height: 48em;
  box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.25);
  padding: 15px;
  transform: translate(-50%, -50%);
  background: #ffffff;
  border: 1px solid #d0d0d0;
  border-radius: 5px;
  z-index: 99;
}

.modal-content {
  padding: 15px;
}

.close {
  position: absolute;
  top: 15px;
  right: 15px;
  cursor: pointer;
}
<button class="js-create-modal" value="This is my first modal.">Modal 1</button>
<button class="js-create-modal" value="All the modals have their own content.">Modal 2</button>
<button class="js-create-modal" value="And are unique in every way.">Modal 3</button>

Another way would be to have a single modal on the page, which you show and hide. Whenever you click a button, you should modify the content of the modal based on the button that you clicked. That way you only have to modify a single piece. But hey, if a modal is hidden, why not just remove it and build a new one when you need it? Your choice.

Upvotes: 2

Related Questions