user6728960
user6728960

Reputation: 285

How to close accordion element before opening another accordion text

Actually i have implemented Accordion using bootstrap classes It is working fine while we click on More Info.But If i click on Next accordion text the first one should close automatically.Can any one help me this.Thanks In advance.

HTML:

<div class="accordion" >More Info</div>
                    <div class="panel">
        <p>            
        Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum
        </p>
        </div>
        <div class="accordion" >More Info</div>
                    <div class="panel">
        <p>            
        Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum
        </p>
        </div>

CSS:

div.panel {
padding: 0 18px;
display: none;
background-color: white;
border: 1px solid #d4d4d4;
 }

     div.panel.show {
display: block;
color: #2b3034;
font-size: 12px;
font-family: Roboto,sans-serif;
margin-left: -18px;
border-radius: 0px;
width: 778px;
margin-top: 16px;
background: #ffffff;
margin-bottom: -17px;
              }

Javascript:

var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
    this.classList.toggle("active");
    this.nextElementSibling.classList.toggle("show");
 }
 }

JSFiddle

Upvotes: 3

Views: 1288

Answers (6)

user3282227
user3282227

Reputation: 149

Here is another version that worked for me. Hopefully others can use it.

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;  // Collapse clicked panel
    } 
    else { // expand clicked panel
        panel.style.maxHeight = panel.scrollHeight + "px";
        collapseOthers(this);
    } 
    }
}

// Collapse all other accordions except the clicked one
function collapseOthers(clickedAccor) {
    var accs = document.getElementsByClassName("accordion");
    for (var i = 0; i < accs.length; i++) {
        if (accs[i] != clickedAccor) {
           accs[i].nextElementSibling.style.maxHeight = null;
        }
    }
}

Upvotes: 0

simmu
simmu

Reputation: 83

I think there is better approach by tweaking your HTML so that we can move the expand logic to the CSS. This will trim down one call on the JS. Anyway, to help you understand more how it works, I updated your JS based on our style. Hope it helps.

   var acc = document.getElementsByClassName("accordion");
   var showMore = function(){
       hideOthers();
       this.classList.toggle('active');
       this.nextElementSibling.classList.toggle("show");
   };

   var hideOthers = function(){
       var elements = document.getElementsByClassName("accordion active");
       for (var i = 0; i < elements.length; i++) {
           elements[i].nextElementSibling.classList.toggle('show');
           elements[i].classList.toggle('active');
       } 
   }

working fiddle

Upvotes: 0

Amar Singh
Amar Singh

Reputation: 5622

Since You have tagged Jquery tag .Just add $(".panel").removeClass("show");

for (i = 0; i < acc.length; i++) {
        acc[i].onclick = function(){

            $(".panel").removeClass("show");
            this.classList.toggle("active");
            this.nextElementSibling.classList.toggle("show");
      }
    }

Working Demo

Upvotes: 1

Enmanuel Duran
Enmanuel Duran

Reputation: 5118

You can solve this with jQuery by doing something simple like this:

Here a Fiddle http://jsfiddle.net/mveau1v4/5/

var acc = jQuery(".accordion");

acc.on("click", function(){
    //remove status from past elements
    $(".show").removeClass("show");
    $(".active").removeClass("active");
    //add new status to the clicked element.
    $(this).addClass("active");
    $(this).next(".panel").addClass("show");
})

Upvotes: 0

Dhananjay
Dhananjay

Reputation: 554

One approach could be to track the previously expanded accordion e.g:

var currentActive; // track the current active accordion.

and close it when another one is expanded,

var toggleAccordionState = function(accordion) {
      accordion.classList.toggle("active");
      accordion.nextElementSibling.classList.toggle("show");
};

for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function(){
        if(currentActive) {
                toggleAccordionState(currentActive);  //Close the current accordion.
        }
        toggleAccordionState(this);
        currentActive = this;     // Save the current open accordion   
  }

see the updated fiddle

Upvotes: 0

Samudrala Ramu
Samudrala Ramu

Reputation: 2106

In Your Code You Selected Accordions Based On Class Name , And One More Thing At All The Time Its Not A Correct Process, You Should Select That Item Based On Separate Id Then It Will Works Perfectly .

Upvotes: 0

Related Questions