Jump to content

modal gallery inside accordion closes accordion


Recommended Posts

 
when image is opened inside the accordion the gallery is in closes immediately, and it has to be reopened to look at next image.
 
 
<div class="accordion">
      <button class="section">People</button>
      <div class="panel">
        <!-- content goes below -->
        <!-- Group 1  -->
        <div class="w3-row">

          <div class="w3-third">
            <!-- Column  1-->
            <!-- Tile 1 -->
            <img src="https://source.unsplash.com/user/c_v_r/1900x800" style="width:100%" onclick="onClick(this)" alt="editorial">
            <!-- Tile 2 -->
            <img src="https://source.unsplash.com/user/c_v_r/1900x800" style="width:100%" onclick="onClick(this)" alt="editorial">
            <!-- Tile 3 -->
            <img src="https://source.unsplash.com/user/c_v_r/1900x800" style="width:100%" onclick="onClick(this)" alt="editorial">




          </div>

 

starting with some of w3schools CSS templates I made a simple image gallery grid, with modal.

now I have added that image gallery to an accordion; I have it set to one tab open at a time to keep clutter down, I achieved this with JS

now the image grid is inside the accordion

modal still makes them pop up and provides the close button as expected;

the problem is

when image is opened the accordion it came from closes immediately, and it has to be reopened to look at next image.

I created a fiddle here

My original Stack question here

thank you for any advice or direction on how to fix

 

 

console.log("working accordion test env 7");

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });
}

// Set up the click event on the accordion itself
// When a panel is clicked, that event will bubble up
// to the accordion and can be handled there.
document
  .querySelector(".accordion")
  .addEventListener("click", function(event) {
    // Check to see if the clicked panel was the currently open one.
    let alreadyActive = event.target.classList.contains("active");

    // Loop over all the panels an close each one
    document.querySelectorAll(".panel").forEach(function(panel) {
      panel.style.maxHeight = "0";
      panel.previousElementSibling.classList.remove("active");
    });

    // If the clicked panel wasn't the already active one go ahead
    // and open the clicked panel. Otherwise, do nothing and leave
    // all the panels closed.
    if (!alreadyActive) {
      // Then show the clicked panel which is accessible as event.target
      event.target.classList.add("active");
      var panel = event.target.nextElementSibling;
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });



// Modal Image Gallery
function onClick(element) {
  document.getElementById("img01").src = element.src;
  document.getElementById("modal01").style.display = "block";
  var captionText = document.getElementById("caption");
  captionText.innerHTML = element.alt;
}

 

 

form other readings, questions and replies I have received: 
I have gathered that the event listener is bubbling and interpreting all clicks inside the accordion; and it causes the accordion to collapse back.  
 
how would I modify the existing script to only target the accordion? 
 
 

update:

changing ".accordion" to ".section" stops the underlying accordion from closing; however stops the "one at a time" feature

 
console.log("working accordion test env 7");

var acc = document.getElementsByClassName("section");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function () {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });
}

// Set up the click event on the accordion itself
// When a panel is clicked, that event will bubble up
// to the accordion and can be handled there.
document.querySelector(".section").addEventListener("click", function (event) {
  // Check to see if the clicked panel was the currently open one.
  let alreadyActive = event.target.classList.contains("active");

  // Loop over all the panels an close each one
  document.querySelectorAll(".section").forEach(function (panel) {
    panel.style.maxHeight = "0";
    panel.previousElementSibling.classList.remove("active");
  });

  // If the clicked panel wasn't the already active one go ahead
  // and open the clicked panel. Otherwise, do nothing and leave
  // all the panels closed.
  if (!alreadyActive) {
    // Then show the clicked panel which is accessible as event.target
    event.target.classList.add("active");
    var panel = event.target.nextElementSibling;
    panel.style.maxHeight = panel.scrollHeight + "px";
  }
});
Edited by preppietrash
Link to comment
Share on other sites

Use console.log() at each event to show what is happening. For instance console.log('a') then next console.log('b') and so on. then check console web developers tools F12 -> console panel If multiple are triggered. Be sure the class 'active' is not used on more than one event to a specific element.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...