Search code examples
javascriptomeka

JavaScript accordion in Omeka


I'm trying to create accordion buttons in my Omeka site so I found some code from W3Schools to adapt. I was able to get this to work when testing it out in an HTML doc with the JavaScript inside < script > tags but now that I've put that code in its own .js file to load into the page's head my buttons aren't working and I'm getting the following error: TypeError: panel is null.

Below is the code in my .js file:

/*
 * Script for accordion buttons
 */

document.addEventListener("DOMContentLoaded", function () { 

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

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 = "none";
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    } 
  });
}
});

And this is the CSS I've used:

 /* --- Accordion Menu Buttons --- */

.accordion {
    background-color: #A4C4E9 !important;
    color: #000;
    cursor: pointer;
    width: 75%;
    border: none;
    text-align: left;
    outline: none;
    font-size: 15px;
    transition: 0.4s;
}

.accordion:hover {
    background-color: #999 !important;
}

.panel {
    padding: 0 18px;
    background-color: white;
    max-height: 0;
    width: 75%;
    overflow: hidden;
    transition: max-height 0.2s ease-out;
} 

This is the HTML:

<p><button class="accordion">Section 1</button></p>
<div class="panel">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

Solution

  • You are setting the max-height property for the .panel class and you are trying to set the display:block or none via javascript you should set the maxHeight via using the scrollHeight of the div.panel or either use display:none inside the .panel class instead of max-height property.

    The Element.scrollHeight read-only property is a measurement of the height of an element's content, including content not visible on the screen due to overflow.

    See a demo below

    document.addEventListener("DOMContentLoaded", function() {
      var acc = document.getElementsByClassName("accordion");
      var i;
    
      for (i = 0; i < acc.length; i++) {
        acc[i].addEventListener("click", function() {
    
          /* Toggle between adding and removing the "active" class,
          to highlight the button that controls the panel */
          this.classList.toggle("active");
    
          /* Toggle between hiding and showing the active panel */
          var panel = this.nextElementSibling; //.classList.toggle('active');
    
          if (panel.style.maxHeight == "") {
            panel.style.maxHeight = panel.scrollHeight + "px";
          } else {
            panel.style.maxHeight = "";
          }
        });
      }
    
    
    });
    /* --- Accordion Menu Buttons --- */
    
    .accordion {
      background-color: #A4C4E9 !important;
      color: #000;
      cursor: pointer;
      width: 75%;
      border: none;
      text-align: left;
      outline: none;
      font-size: 15px;
      transition: 0.4s;
    }
    
    .accordion:hover {
      background-color: #999 !important;
    }
    
    .panel {
      padding: 0 18px;
      background-color: white;
      max-height: 0;
      width: 75%;
      overflow: hidden;
      transition: max-height 0.2s ease-out;
    }
    
    .panel.active {
      max-height: 100%;
    }
    
    .active,
    .accordion:hover {
      background-color: #ccc;
    }
    <button class="accordion">Section 1</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </div>
    <button class="accordion">Section 1</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </div>
    <button class="accordion">Section 1</button>
    <div class="panel">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
    </div>