Randy Morgan
Randy Morgan

Reputation: 3

Close all open drop downs and consolidate code if possible

What I need to be able to do is to have the text drop downs close when another is selected so that I do not end up with a bunch of drop downs open on the page at the same time.

I have two text dropdowns that will be used one after the other alternating on a page. In other words accordion1, accordion2, accordion1, accordion2 and so on the reason I have accordion1 and accordion2 is that with my limited experience it is the only way I could figure out change the button color so the list could alternate colors. It would be nice to consolidate the code, but I can live with the extra code if need be.

Here is the code for accordion1

var acc = document.getElementsByClassName("accordion1");
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("active1");

    /* Toggle between hiding and showing the active panel */
    var panel = this.nextElementSibling;
    if (panel.style.display === "block") {
      panel.style.display = "none";
    } else {
      panel.style.display = "block";
    }
  });
}

var acc = document.getElementsByClassName("accordion2");
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("active1");

    /* Toggle between hiding and showing the active panel */
    var panel = this.nextElementSibling;
    if (panel.style.display === "block") {
      panel.style.display = "none";
    } else {
      panel.style.display = "block";
    }
  });
}
.accordion1 {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  text-align: left;
  border: none;
  outline: none;
  transition: 0.4s;
}

.accordion2 {
  background-color: #8461E8;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  text-align: left;
  border: none;
  outline: none;
  transition: 0.4s;
}


/* Add a background color to the button if it is clicked on (add the 
      .active class with JS), and when you move the mouse over it (hover) */

.active1,
.accordion1:hover {
  background-color: #ccc;
}


/* Style the accordion panel. Note: hidden by default */

.panel1 {
  padding: 0 18px;
  background-color: white;
  display: none;
  overflow: hidden;
}

.accordion1:after {
  content: '\02795';
  /* Unicode character for "plus" sign (+) */
  font-size: 13px;
  color: #777;
  float: right;
  margin-left: 5px;
}

.accordion2:after {
  content: '\02795';
  /* Unicode character for "plus" sign (+) */
  font-size: 13px;
  color: #777;
  float: right;
  margin-left: 5px;
}

.active1:after {
  content: "\2796";
  /* Unicode character for "minus" sign (-) */
}
<Section><button class="accordion1"><h3>Alternators and regulators</h3> 
    </button>
  <div id="accordion1-div" class="panel1">
    <p>First group of words go here></div>
</Section>

<Section><button class="accordion2"><h3>Batteries and Inverters</h3> 
    </button>
  <div id="accordion-div" class="panel1">
    <p>Second set of words go here.</p>
  </div>
</Section>

<Section><button class="accordion1"><h3>AC and DC Panels </h3> 
    </button>
  <div id="accordian1-div" class="panel1">
    <p>Third set of words reusing "accordion1 go here"</p>
  </div>
</Section>

Any help or resources to figure out the needed code would be greatly appreciated.

Upvotes: 0

Views: 171

Answers (1)

Barthy
Barthy

Reputation: 3231

Question 1 — "How do I not end up with a bunch of drop downs open on the page at the same time":

You close all dropdowns before opening another one. You can also create css rules to display or hide the dropdown. This way, it will be easier to find the currently active dropdown. See code below.

Question 2 — "How can I make the list alternate colors"

You can add more than one class to an element. Simply create color classes and add them to the right elements. See code below.

Notes:

Edit (scrollIntoView)

I added code to automatically scroll the window so that the active tab is visible. It works only on Chrome, Firefox and Opera. Use this polyfill iamdustan/smoothscroll to use it in other browsers. See compatibility here and all functions here.

// Query all accordions
var accordions = document.querySelectorAll('.accordion');

for (var i = 0; i < accordions.length; i++) {
  accordions[i].addEventListener('click', function() {
    // Get the currently active accordion
    var active = document.querySelector('.accordion.active');

    // If there is one, deactivate it
    if (active) {
      active.classList.remove('active');
    }

    // Activate the new accordion, if it's not the one you just deactivated
    if (active !== this) {
      this.classList.add('active');
      
      // Use scrollIntoView to adjust the window scroll position to show the content.
      this.scrollIntoView({
        behavior: 'smooth'
      });
    }
  });
}
.accordion .header button {
  text-align: left;
  padding: 18px;
  background: transparent;
  border: none;
  outline: none;
  cursor: pointer;
  width: 100%;
  color: #444;
  width: 100%;
  transition: 0.4s;
}


/* Set the color according to the modifier class */

.accordion.gray button {
  background-color: #eee;
}

.accordion.purple button {
  background-color: #8461E8;
}

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

.accordion .panel {
  padding: 0 18px;
  background-color: white;
  display: none;
  overflow: hidden;
}


/* Show the panel if the accordion is active */

.accordion.active .panel {
  display: block;
}

.accordion button:after {
  content: '\02795';
  font-size: 13px;
  color: #777;
  float: right;
  margin-left: 5px;
}

.accordion.active button:after {
  content: "\2796";
}
<section>
  <!-- Each accordion is wrapped by a div with the class 'accordion' -->
  <!-- 'accordion' is the component, 'gray' is the color modifier -->
  <div class="accordion gray">
    <!-- h3 can contain a button -->
    <h3 class="header">
      <button>Alternators and regulators</button>
    </h3>
    <div class="panel">
      <p>
        First group of words go here.<br/> I'm afraid I just blue myself. No… but I'd like to be asked! Michael! It's called 'taking advantage.' It's what gets you ahead in life. Now, when you do this without getting punched in the chest, you'll have
        more fun.
      </p>
    </div>
  </div>
</section>

<section>
  <!-- Use the 'purple' modifier class here -->
  <div class="accordion purple">
    <h3 class="header">
      <button>Batteries and Inverters</button>
    </h3>
    <div class="panel">
      <p>
        Second set of words go here.<br/> Steve Holt! I don't criticize you! And if you're worried about criticism, sometimes a diet is the best defense. That's why you always leave a note! Well, what do you expect, mother? I don't criticize you! And
        if you're worried about criticism, sometimes a diet is the best defense.<br/>
        <br/> Across from where? As you may or may not know, Lindsay and I have hit a bit of a rough patch. Now, when you do this without getting punched in the chest, you'll have more fun. No… but I'd like to be asked!
      </p>
    </div>
  </div>
</section>

<section>
  <div class="accordion gray">
    <h3 class="header">
      <button>AC and DC Panels 
    </button>
    </h3>
    <div class="panel">
      <p>
        Third set of words go here.<br/> That's why you always leave a note! Not tricks, Michael, illusions. As you may or may not know, Lindsay and I have hit a bit of a rough patch. It's called 'taking advantage.' It's what gets you ahead in life.<br/>
        <br/> Say goodbye to these, because it's the last time! First place chick is hot, but has an attitude, doesn't date magicians. I'm afraid I just blue myself. I'm afraid I just blue myself. I'm afraid I just blue myself.
      </p>
    </div>
  </div>
</section>

Upvotes: 2

Related Questions