Targeting a toggle button within an accordion

1.1k Views Asked by At

I'm trying to target my on/off toggle control which is embedded in a link that also toggles an accordion when you tap on it. Both toggles work, but I want them to work independently of each other. The on/off switch is not supposed to toggle the accordion. I'm using Ratchet as the framework, if that means anything. Here's my JS Fiddle

<li class="table-view-cell toggle-handle accordion">
   Kitchen Light
  <div class="toggle">
    <div class="toggle-handle"></div>
  </div>
<!-- toggle -->
</li>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui, officiis asperiores totam. Amet, beatae explicabo placeat consequatur repellendus quia rerum saepe cumque autem facilis! Perferendis, exercitationem eius vitae alias ad.</p>
</div>
 li.accordion {
   curser: pointer;
   padding: 18px;
   width: 100%;
   border: none;
   text-align: left;
   outline: none;
   font-size: 15px;
   transition: 0.4s;
   }

 li.accordion.active,
 button.accordion:hover {
 background-color: #ddd;
 }

li.accordian:after {
  content: '\002B';
  color: #777;
  font-weight: bold;
  float: right;
  margin-left: 5px;
  }

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

 div.toggle {
  z-index: 1;
  }




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

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

There are 3 best solutions below

1
dmoo On BEST ANSWER

The key piece you are missing is event.stopPropagation(); as this prevents the toggle from also triggering the accordion.

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

for (i = 0; i < acc.length; i++) {
  acc[i].getElementsByClassName("toggle")[0].onclick = function() {
    event.stopPropagation();
    this.classList.toggle("active");
  }
  acc[i].onclick = function() {
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + 'px';
    }
  }
} //end function
li.accordion {
  /* change the button tag to li tag */
  curser: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

li.accordion.active,
button.accordion:hover {
  background-color: #ddd;
}

li.accordian:after {
  content: '\002B';
  color: #777;
  font-weight: bold;
  float: right;
  margin-left: 5px;
}

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

div.toggle {
  z-index: 1;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/ratchet/2.0.2/css/ratchet.css" rel="stylesheet"/>
<li class="table-view-cell toggle-handle accordion">
  Kitchen Light
  <div class="toggle">
    <div class="toggle-handle"></div>
  </div>
  <!-- toggle -->
</li>


<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui, officiis asperiores totam. Amet, beatae explicabo placeat consequatur repellendus quia rerum saepe cumque autem facilis! Perferendis, exercitationem eius vitae alias ad.</p>
</div>
<!-- end panel -->

0
Man Programmer On

I have functional your button

https://jsfiddle.net/Lpppha37/5/

I have updated some html code

<li class="table-view-cell toggle-handle accordion ">
  Kitchen Light
  <div class="toggle toggle-handle accordion">
    <div class="toggle-handle "></div>
  </div>
  <!-- toggle -->
</li>
0
Ronnie Royston On

Use JavaScript to handle the click event of the target element. That's it really. Just use the .classList toggle method.