skip to Main Content

I have working code that toggles a modal, but I want to be able to toggle different modal content by different triggers on the page. I know I need to use ids in this, but I am not 100% sure how to accomplish that with my current code. I’m still learning!

Can someone help me change my Javascript to trigger by ids? Do I have to use Bootstrap or something else to achieve this or can my code be altered easily?

var modal = document.querySelector(".modal");
var trigger = document.querySelector(".trigger");
var closeButton = document.querySelector(".close-button");
    

function toggleModal() {
    modal.classList.toggle("show-modal");
}

function windowOnClick(event) {
    if (event.target === modal) {
        toggleModal();
    }
}
function closeAction(){
toggleModal();
}

trigger.addEventListener("click", toggleModal);
closeButton.addEventListener("click", closeAction);
window.addEventListener("click", windowOnClick);
.trigger{
    font-size: 16px;
    color: #fff;
    background-color: #3b94a3;
    border-radius: 0px 4px 4px 0px;
    max-width: 350px;
    line-height: 1.4!important;
    position: absolute;
    left: 0px;
    top: 80px;
}
.trigger:hover{
    color: #fff;
    background-color: #4E4E4E;
}
.modal {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    opacity: 0;
    visibility: hidden;
    transform: scale(1.1);
    transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s;
    z-index: 1;
    cursor: pointer;
}
.modal-content {
    background-color: white;
    padding: 1rem 1.5rem;
    margin: 100px auto;
    width: 70%;
    cursor: default;
    position: relative;
}
.close-button {
    position: absolute;
    cursor: pointer;
    right: -40px;
    top: -10px;
    font-size: 40px;
}
.close-button:hover {
    color: darkgray;
}
.show-modal {
    z-index: 100;
    opacity: 1;
    visibility: visible;
    transform: scale(1.0);
    transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
}
<!--Modal 1 -->
<div id="tour" class="trigger">Take a Tour</div>
<div id="tour" class="modal">
  <div class="modal-content">
    <div class="close-button">&times;</div>
    <h3>This is tour content</h3>
  </div>
</div>
<!--Modal 2 -->
<div id="game" class="trigger">View the game</div>
<div id="game" class="modal">
  <div class="modal-content">
    <div class="close-button">&times;</div>
    <h3>This is game content</h3>
  </div>
</div>

3

Answers


  1. Here is the updated javascript code based on different ID you can manage both modal invidiously

     <script>
    // Select modal elements by their IDs
    var tourModal = document.getElementById("tourModal");
    var gameModal = document.getElementById("gameModal");
    
    // Select trigger elements by their IDs
    var tourTrigger = document.getElementById("tourTrigger");
    var gameTrigger = document.getElementById("gameTrigger");
    
    // Select close buttons within modals
    var tourCloseButton = tourModal.querySelector(".close-button");
    var gameCloseButton = gameModal.querySelector(".close-button");
    
    function toggleModal(modal) {
        modal.classList.toggle("show-modal");
    }
    
    function closeAction(modal) {
        toggleModal(modal);
    }
    
    // Event listeners for each trigger
    tourTrigger.addEventListener("click", function() {
        toggleModal(tourModal);
    });
    
    gameTrigger.addEventListener("click", function() {
        toggleModal(gameModal);
    });
    
    // Event listeners for close buttons
    tourCloseButton.addEventListener("click", function() {
        closeAction(tourModal);
    });
    
    gameCloseButton.addEventListener("click", function() {
        closeAction(gameModal);
    });
    
    // Close modal if clicked outside of modal content
    window.addEventListener("click", function(event) {
        if (event.target === tourModal) {
            closeAction(tourModal);
        }
        if (event.target === gameModal) {
            closeAction(gameModal);
        }
    });
    </script>
    
    
    
    
    <!-- Modal 1 -->
    
    <div id="tourTrigger" class="trigger separate-modal">Take a Tour</div>
    <div id="tourModal" class="modal">
        <div class="modal-content">
            <div class="close-button">&times;</div>
            <h3>This is tour content</h3>
        </div>
    </div>
    
    
    <!-- Modal 2 -->
    <div id="gameTrigger" class="trigger">View the game</div>
    <div id="gameModal" class="modal">
        <div class="modal-content">
            <div class="close-button">&times;</div>
            <h3>This is game content</h3>
        </div>
    </div>
    
    
    
    // Add in CSS 
    
    .separate-modal{
      margin: 30px;
      margin-left:0
    }
    
    Login or Signup to reply.
  2. All you need is a better understanding (i think) of css selectors.

    document.querySelector(".modal");
    

    This is selecting the first element in the DOM with the class "modal".

    if you change the "." to a "#" this will select first element in DOM with ID "modal"

    You can chain the twos by doing document.querySelector(".modal#your-id");

    Here is the documentation for selectors

    Depends on what your need is, but you could do something like

    document.querySelector(".modal#your-first-id").addEventListener("click", OpenFirstModal);
    document.querySelector(".modal#your-second-id").addEventListener("click", OpenSecondModal);
    
    Login or Signup to reply.
  3. One approach for this is to actually have only a single modal but inject the content dynamically. You can do this by saving the contents in an array of objects, where the key (let’s call it "id" for this example) can be the corresponding trigger’s id and the rest of the fields store additional data like the title, content, etc.

    now you can grab all the triggers by using document.querySelectorAll('.trigger') and iterate through them with a loop, each time setting their onClick function to toggleModal(triger.id)
    as you can see, im now passing the id to the toggleModal function, and can triger the modal for the specific content in the array.

    You would also have to change the function to grab the right content using contents.find(content => content.id == idFromTrigger) and appending it to the modal element bu using modal.appendChild(<whichever element you want to create and inject here>), then actually toggling it by adding the "show-modal" class.

    Hope this helps! feel free to ask for any clarifications.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search