Building an accordion collapse feature in HTML using CSS and JavaScript

I've been working on creating an accordion interface, but I'm facing an issue where only the first collapsible button works properly. The rest of the buttons are not functioning and don't even appear on the page.

When I remove the CSS styling for the "content" variable, all the content displays correctly, but the "day" buttons become unresponsive.

I've experimented with different code snippets, and as someone unfamiliar with JavaScript, I've borrowed code from a W3Schools example (while creating my own components). However, I find it challenging to understand how these scripts function and how I can troubleshoot them.

Answer №1

One possible solution is to use the following code:

var acc = document.getElementsByClassName("daytitle");
var i;
var x = document.getElementById("content1");

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";
    }
    if (x.style.display === "none") {
      x.style.display = "block";
    }
  });
}

function collapse() {
  if (x.style.display === "none") {
    x.style.display = "block";
  } else {
    x.style.display = "none";
  }
}
.daytitle {
  width: 100%;
  height: 50px;
  background-color: #c2c2d6;
  border-color: black;
  margin-left: 10px;
  margin-top: 0px;
  font-size: 30px;
  text-align: center;
  font-family: 'Oswald', sans-serif;
  font-size: 30px;
  font-weight: 400;
  color: black;
}

.daytitle:hover {
  background-color: #555;
}

.content {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}
<button class="daytitle"> Day <i class="arrow"></i></button>
    <div id="content1" class="content">
      <div id="Attraction1" class="attraction">
        <div class="atr_image"><img src="images/oldtown.jpg" alt=""></div>
        <div class="atr_container">
          <div class="atr_name"><a>Atr Name </a></div>
          <div class="atr_region">Atr Region</div>
          <div class="atr_desc">
            <p>Atr Description</p>
          </div>
          <div class="atr_time_container">
            <div class="atr_time">
              <p>3 Hours</p>
            </div>
            <span class="dot"></span>
            <div class="atr_hours">
              <p>10:00-13:00</p>
            </div>
          </div>
          <button class="button1" id="R1" onclick="collapse()">Remove Attraction</button>
        </div>
      </div>
    </div>

However, one drawback of this approach is that you need to double click the day button to expand the content after collapsing it. Other than that, it should function correctly.

Answer №2

This specific accordion does not rely on any JavaScript programming.

The concept behind it is that the status of each content container is governed by the state of the input. The input can be a checkbox, allowing for multiple selections, or a radio button, permitting only one selection at a time. These inputs are categorized by the name property.

HTML

<div class="wrapper">
    <div class="tab grey">
        <input id="tab-0" type="checkbox" name="tabs">  <!-- change the input type to radio if you want only one accordion panel open -->
        <label for="tab-0">
            <!-- Insert the title text for the accordion here --> 
        </label>
        <div class="tab-content grey">
            <!-- Your content goes here -->
        </div>
    </div>
    <!-- repeat as many tabs as desired -->
</div>

The essential functions I believe should receive priority are explained within the following code comments below

CSS

.tab {
  position: relative;
  margin-bottom: 1px;
  width: 100%;
  color: #fff;
  overflow: hidden;
}
input {
  /* this hides the input element */
  position: absolute;
  opacity: 0;
  z-index: -1;
}
label { 
  position: relative;
  display: flex;
  padding: 0 0 0 0.3em;
  background: #16a085;
  font-weight: bold;
  line-height: 2.5;
  cursor: pointer;
  font-size: 1.5em;
}
.tab-content {
  /* default setting is invisible (height: 0) */
  max-height: 0;
  overflow: auto;
  background: #1abc9c;
  transition: max-height .35s;
}

/* :checked */
input:checked ~ .tab-content {
/* increase height if adjacent tab's input is checked */
  max-height: 25em;
}
/* Custom Icon styling - adds visual feedback when content is visible or hidden */
label::after {
  position: absolute;
  right: 0;
  top: 0;
  display: block;
  width: 3em;
  height: 3em;
  line-height: 3;
  text-align: center;
  transition: all .35s;
}
input[type=checkbox] + label::after {
  content: "+";
}
input[type=radio] + label::after {
  content: "\25BC";
}
input[type=checkbox]:checked + label::after {
  transform: rotate(315deg);
}
input[type=radio]:checked + label::after {
  transform: rotateX(180deg);
}

With some CSS customization, this design could easily transform into a tabbed layout.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Running Perl CGI script within an HTML document

I'm currently facing an issue while attempting to execute a perl script within an html context. Upon execution, I am encountering an error labeled as "Internal Server Error," which does not provide much insight. Additionally, I am seeking guidance on ...

The ngb Pagination feature in my Angular application seems to be experiencing some issues and is not functioning correctly

I recently implemented NGB Pagination in my Angular application for a table, but unfortunately it's not functioning as expected. Instead of dividing the data between pages in the table, it only shows 2 pages. Here's a snippet of my code: import ...

Unconventional border effect while hovering over image within navigation container of Bootstrap

Whenever I hover over the image inside the navigation bar, there is a strange white/gray border that appears. It's quite annoying. Does anyone know how to remove this border? Here is the code snippet causing the issue: <ul class ...

Tips for passing multiple items for the onselect event in a ng-multiselect-dropdown

I've got a multi-select dropdown with a long list of options. Currently, when I choose a single item, it triggers the Onselect event and adds data from the newArrayAfterProjectFilter array to the myDataList based on certain conditions in the OnselectE ...

Comparing "if" and "else" within the XMLHttpRequest() function will not

function banUser() { var userToBan = document.getElementById('userToBan').value; var cid = document.getElementById('chatId').value; if (userToBan.length <= 0) { var x = document.getElementById("banerror"); x.innerHTML ...

Assign a value to a locally scoped variable within an iteration in Angular 2

Within my Angular code, I have the following HTML snippet: <span *ngIf="ControllerType?.AttributeID =='Controller Type'"> <select multiple name="ControllerType.Default" [(ngModel)]="Contro ...

Fetching basic information from an API using Ember.js

I am facing an issue with my Ember.js page where I am trying to retrieve data from a REST API. The API is provided by apiary.io and it returns a simple set of data as shown below: {"semantics": [ {key : "11111", name : "Block 1"}, {key : "22222", name ...

The issue arises from the fact that the Bootstrap modal fails to open automatically

Having trouble getting my bootstrap modal to open on page load, even though the button to trigger it is working fine. Here is my code: <div id="myModal" class="modal fade" role="dialog"> <div class=" ...

Utilize data fields beyond the export default in Vue

Is there a way to access the information stored within the export default in my Vue component's JavaScript file? Specifically, I am trying to retrieve the contents of the routes array within the calculateAndDisplayRoute() function. overview.js funct ...

Setting the chosen value within a nested ng-repeat loop

I'm struggling with correctly setting up the select boxes in a form that uses nested ng-repeats. The form has parent table rows generated with an ng-repeat, and each row contains a select box that is linked to an attribute in the parent row. The optio ...

Apply CSS styles conditionally to an Angular component

Depending on the variable value, I want to change the style of the p-autocomplete component. A toggle input determines whether the variable is true or false. <div class="switch-inner"> <p [ngClass]="{'businessG': !toggle }" clas ...

The step-by-step guide on displaying API choices in an Autocomplete feature and keeping them up

Having trouble with updating autocomplete options. An error message pops up in the console log when I try to deselect a tag or select a new one: MUI: The value provided to Autocomplete is invalid. None of the options match with [{"catName":{&qu ...

In the ajax call, an empty JSON array object is sent as the data

Utilizing JSON data as a parameter for an ajax call: var startDate = dateFormatForSave($("#start_date").val().trim()); var arrayOfStudentsInfo = []; var table = $("#selected_students"); table.find('tr').each(function(i, el) { var rowId = $( ...

Adjust the height setting of the React-Highcharts viewport

My initial configuration for highcharts looks like this:- function getInitialHighChartsConfig(chartType) { return { credits: false, chart: { type: chartType, height: 325, }, title: { text: '', useHTML: tr ...

conceal a component within a different container

Is there a way to hide or show an element within a container based on the hover state of another container? Here is an example of what I have tried so far: HTML5 <div class="left-menu-container"> <div class="left-menu-inner-container"> ...

Is there a way for me to send a URL request from my website to a different server using PHP?

I am looking to initiate a request from my website to my server using a specific IP address. From there, I need the server to send another request to a different server and then display the response on the webpage. Can anyone provide guidance on how to ...

Invoke an Angular service from a separate JavaScript file

I have a few javascript and html files: User.js, index.html, Door.js I am looking to utilize a function in the User.js file. Link to my user.js file Link to my door.js file I am trying to call the getUserInfo function from User.Js within the Door.j ...

Having trouble muting the audio on my Vue audio player

I'm facing some challenges with muting the audio within my vue app. I have a list of songs that can be played, paused, shuffled, etc., but I can't seem to get the mute function working. Here's what I have in the JavaScript: mute() ...

Cannot assign type void to 'Intrinsic Attributes & Dispatch<SetStateAction<>>'

Just starting out with typescript and ran into this error: Error :Type '{ setTasks: void; }' is not assignable to type 'IntrinsicAttributes & Dispatch<SetStateAction<IStudy[]>>'. Property 'setTasks' does not e ...

Assist the floats to "ascend" and occupy the available space

The screenshot showcases boxes that have been styled with "float: left". Is there a way to make these boxes float to the first available space in a column? For example, can we move the Music Nation box to the location indicated by the red arrow in the ima ...