Home > Software design >  How to add multiple modals without repeating javascript code
How to add multiple modals without repeating javascript code

Time:03-22

I have added modals to my site and included the for loop which is working, but the problem is both modals show same content yet they are supposed to show different content. How do I fix this without repeating my self in Javascript.

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


for (var i = 0; i < btn.length; i  ) {
  btn[i].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";
  }
}
.chimps {
  margin-left: 20px;
  height: 150px;
  width: 250px;
  display: grid;
  grid-template-columns: auto auto auto auto;
  gap: 10px;
}

.chimpDet {
  background-color: rgba(0, 128, 0, 0.5);
  cursor: pointer;
}

.chimpImg {
  height: 150px;
  width: 250px;
}

.modal {
  display: none;
  /* Hidden by default */
  position: fixed;
  /* Stay in place */
  z-index: 1;
  /* Sit on top */
  padding-top: 100px;
  /* Location of the box */
  left: 0;
  top: 0;
  width: 100%;
  /* Full width */
  height: 100%;
  /* Full height */
  overflow: auto;
  /* Enable scroll if needed */
  background-color: rgb(0, 0, 0);
  /* Fallback color */
  background-color: rgba(0, 0, 0, 0.4);
  /* Black w/ opacity */
}


/* Modal Content */

.modal-content {
  position: relative;
  background-color: #fefefe;
  margin: auto;
  padding: 0;
  border: 1px solid #888;
  width: 80%;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  -webkit-animation-name: animatetop;
  -webkit-animation-duration: 0.4s;
  animation-name: animatetop;
  animation-duration: 0.4s
}


/* Add Animation */

@-webkit-keyframes animatetop {
  from {
    top: -300px;
    opacity: 0
  }
  to {
    top: 0;
    opacity: 1
  }
}

@keyframes animatetop {
  from {
    top: -300px;
    opacity: 0
  }
  to {
    top: 0;
    opacity: 1
  }
}


/* The Close Button */

.close {
  color: white;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
}

.modal-header {
  padding: 2px 16px;
  background-color: #5cb85c;
  color: white;
}

.modal-body {
  padding: 2px 16px;
}

.modal-footer {
  padding: 2px 16px;
  background-color: #5cb85c;
  color: white;
}

.saveBtn {
  background-color: green;
  border: none;
  height: 50px;
  width: 250px;
  cursor: pointer;
  color: white;
  font-size: 20px;
}

.gig {
  display: flex;
}

.cIB {
  display: flex;
  flex-direction: column;
}
<div >
  <div >
    <div >
      <img  src="https://via.placeholder.com/250x150" alt="">
      <h3>AFRIKA</h3>
    </div>
    <div id="myModal" >
      <!-- Modal content -->
      <div >
        <div >
          <span >&times;</span>
          <h2>Welcome to Afrika's Diary</h2>
        </div>
        <div >
          <form action="">
            <div >
              <div>
                <textarea name="" id="" cols="90" rows="20"></textarea>
              </div>
              <div >
                <img  src="https://via.placeholder.com/250x150" alt="">
                <button >Save</button>
              </div>
            </div>
          </form>
        </div>
        <div >
          <h3>Afrika</h3>
        </div>
      </div>
    </div>
  </div>
  <div >
    <div >
      <img  src="https://via.placeholder.com/250x150" alt="">
      <h3>Asega</h3>
    </div>
    <div id="myModal" >
      <!-- Modal content -->
      <div >
        <div >
          <span >&times;</span>
          <h2>Welcome to Asega's Diary</h2>
        </div>
      </div>
    </div>
  </div>

</div>

CodePudding user response:

You can only use an ID once on a page (must be unique), so having two divs with id="myModal" will not work. Fortunately you don't need those IDs, it's easy to get the "next" element of the button that was clicked, which happens to be the modal you want to open.

for (var i = 0; i < btn.length; i  ) {
     btn[i].onclick = function() {
         let modal = this.nextElementSibling;
         modal.style.display = "block";
    }
}

CodePudding user response:

Seems like the problem could be because both modals have the same id property. Try changing one of them.

CodePudding user response:

The best scripts don't depend on IDs at all. I'd probably collect your buttons and modals in DOM node lists and use DOM traversal to open the correct modal.

const modalBtns = document.querySelectorAll('.chimpDet');
const modals = document.querySelectorAll('.modal');
const closeBtns = document.querySelectorAll('.close');

// open next sibling modal on button click
modalBtns.forEach(function(btn) {
  btn.onclick = function() {
    btn.nextElementSibling.style.display = "block";
  }
});

// close all modals on any close button click
closeBtns.forEach(function(btn) {
  btn.onclick = function() {
    modals.forEach(function(modal) {
      modal.style.display = "none";
    });
  }
});

// close all modals on modal wrapper click
window.onclick = function(event) {
  if (Array.from(modals).includes(event.target)) {
    modals.forEach(function(modal) {
      modal.style.display = "none";
    });
  }
}
.chimps {
  margin-left: 20px;
  height: 150px;
  width: 250px;
  display: grid;
  grid-template-columns: auto auto auto auto;
  gap: 10px;
}

.chimpDet {
  background-color: rgba(0, 128, 0, 0.5);
  cursor: pointer;
}

.chimpImg {
  height: 150px;
  width: 250px;
}

.modal {
  display: none;
  /* Hidden by default */
  position: fixed;
  /* Stay in place */
  z-index: 1;
  /* Sit on top */
  padding-top: 100px;
  /* Location of the box */
  left: 0;
  top: 0;
  width: 100%;
  /* Full width */
  height: 100%;
  /* Full height */
  overflow: auto;
  /* Enable scroll if needed */
  background-color: rgb(0, 0, 0);
  /* Fallback color */
  background-color: rgba(0, 0, 0, 0.4);
  /* Black w/ opacity */
}


/* Modal Content */

.modal-content {
  position: relative;
  background-color: #fefefe;
  margin: auto;
  padding: 0;
  border: 1px solid #888;
  width: 80%;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  animation-name: animatetop;
  animation-duration: 0.4s
}


/* Add Animation */

@-webkit-keyframes animatetop {
  from {
    top: -300px;
    opacity: 0
  }
  to {
    top: 0;
    opacity: 1
  }
}

@keyframes animatetop {
  from {
    top: -300px;
    opacity: 0
  }
  to {
    top: 0;
    opacity: 1
  }
}


/* The Close Button */

.close {
  color: white;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
}

.modal-header {
  padding: 2px 16px;
  background-color: #5cb85c;
  color: white;
}

.modal-body {
  padding: 2px 16px;
}

.modal-footer {
  padding: 2px 16px;
  background-color: #5cb85c;
  color: white;
}

.saveBtn {
  background-color: green;
  border: none;
  height: 50px;
  width: 250px;
  cursor: pointer;
  color: white;
  font-size: 20px;
}

.gig {
  display: flex;
}

.cIB {
  display: flex;
  flex-direction: column;
}

textarea {
  max-width: 100%;
}
<div >
  <div >
    <div >
      <img  src="https://via.placeholder.com/250x150" alt="">
      <h3>AFRIKA</h3>
    </div>

    <div id="myModal" >
      <div >
        <div >
          <span >&times;</span>
          <h2>Welcome to Afrika's Diary</h2>
        </div>

        <div >
          <form action="">
            <div >
              <div>
                <textarea name="" id="" cols="90" rows="20"></textarea>
              </div>
              <div >
                <img  src="https://via.placeholder.com/250x150" alt="">
                <button >Save</button>
              </div>
            </div>
          </form>
        </div>

        <div >
          <h3>Afrika</h3>
        </div>
      </div>
    </div>
  </div>

  <div >
    <div >
      <img  src="https://via.placeholder.com/250x150" alt="">
      <h3>Asega</h3>
    </div>

    <div id="myModal" >
      <div >
        <div >
          <span >&times;</span>
          <h2>Welcome to Asega's Diary</h2>
        </div>
      </div>
    </div>
  </div>
</div>

  • Related