Can an FAQ accordion collapse the selected element when another element is clicked?

I recently started working on a FAQ accordion project from frontendmentor. The functionality works perfectly when clicking on a question to reveal the answer and clicking again to hide it. However, I am facing an issue where if I click on one question and then on another, the first question's answer doesn't automatically hide. I have been struggling to find a solution to this problem. Any assistance would be greatly appreciated. Thank you!

Live:

Repo: https://github.com/sn-tin/faq-accordion-card-main

const accordionQuestions = document.querySelectorAll(".questions");
const boxIllustration = document.querySelector(".box-illust");

accordionQuestions.forEach(questions => {
    questions.addEventListener('click', function() {
        this.classList.toggle("active");

        const accordionAnswers = questions.nextElementSibling;

        if (questions.classList.contains("active")) {
            boxIllustration.classList.add("move-box")
            accordionAnswers.classList.toggle("collapse-answer")
        } else {
            boxIllustration.classList.remove("move-box")
            accordionAnswers.classList.remove("collapse-answer")
        }
    })
})
.faq-side {
    width: 100%;
    padding: 100px 100px 100px 0;
}

.faq-heading {
    margin-bottom: 30px;
}

.questions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    font-size: $questions-size;
    color: $bold-text-color;
    border: 0;
    background-color: transparent;
    text-align: left;
    margin-bottom: 20px;
    cursor: pointer;
    :hover {
        color: $orange-hover-text;
    }
}

.arrow-down {
    width: 15px;
    transition: all 0.2s ease-in;
}

.faq-1, .faq-2, .faq-3, .faq-4, .faq-5 {
    border-bottom: 1px solid $border-color;
    margin-top: 20px;
}

.panel {
    display: none;
}

answers {
    color: $answers-color;
    width: 95%;
    margin-bottom: 30px;
}

// To add by JavaScript

.active { 
    color: $bold-text-color;
    font-weight: $bold;
}

.active img {
    transform: rotate(180deg);
    transition: all 0.2s ease-in;
}

.collapse-answer {
    display: block;
}

.move-box {
    left: -10rem;
}
 <!-- FAQs -->
      <div class="faq-side">
        <h1 class="faq-heading">FAQ</h1>
        <div class="faqs d-flex flex-column">
          <div class="faq-1">
            <button class="questions q-1">
              How many team members can I invite?
              <img class="arrow-down" src="./images/icon-arrow-down.svg" alt="Icon arrow down">
            </button>
            <div class="panel">
              <p class="answer-1 answers">You can invite up to 2 additional users on the Free plan. There is no limit on 
                team members for the Premium plan.</p>
            </div>
          </div>
          <div class="faq-2">
            <button class="questions q-2">
              What is the maximum file upload size?
              <img class="arrow-down" src="./images/icon-arrow-down.svg" alt="Icon arrow down">
            </button>
            <div class="panel">
              <p class="answer-2 answers">No more than 2GB. All files in your account must fit your allotted storage space.</p>
            </div>
          </div>
          <div class="faq-3">
            <button class="questions q-3">
              How do I reset my password?
              <img class="arrow-down" src="./images/icon-arrow-down.svg" alt="Icon arrow down">
            </button>
            <div class="panel">
              <p class="answer-3 answers">Click “Forgot password” from the login page or “Change password” from your profile page.
                A reset link will be emailed to you.</p>
            </div>
          </div>
          <div class="faq-4">
            <button class="questions q-4">
              Can I cancel my subscription?
              <img class="arrow-down" src="./images/icon-arrow-down.svg" alt="Icon arrow down">
            </button>
            <div class="panel">
              <p class="answer-4 answers">Yes! Send us a message and we’ll process your request no questions asked.</p>
            </div>
          </div>
          <div class="faq-5">
            <button class="questions q-5">
              Do you provide additional support?
              <img class="arrow-down" src="./images/icon-arrow-down.svg" alt="Icon arrow down">
            </button>
            <div class="panel">
              <p class="answer-5 answers">Chat and email support is available 24/7. Phone lines are open during normal business hours.</p>
            </div>
          </div>
        </div>
      </div>
      <!-- End of FAQs -->

Answer №1

To improve the functionality, include a line of code in your click handler that eliminates the 'active' class from all questions.

accordionQuestions.forEach(item => item.classList.remove("active"));

Here is the complete JavaScript part:

const accordionQuestions = document.querySelectorAll(".questions");
const boxIllustration = document.querySelector(".box-illust");

accordionQuestions.forEach(question => {
  question.addEventListener('click', function() {
  
    accordionQuestions.forEach(item => item.classList.remove("active"));
    this.classList.toggle("active");

    const accordionAnswers = question.nextElementSibling;

    if (question.classList.contains("active")) {
      boxIllustration.classList.add("move-box");
      accordionAnswers.classList.toggle("collapse-answer");
    } else {
      boxIllustration.classList.remove("move-box");
      accordionAnswers.classList.remove("collapse-answer");
    }
  })
})

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

Creating a Dynamic Clear Button for a Text Area in Angular

Working on my Angular application, I have implemented a form with a textarea element. My goal is to incorporate a clear button inside the textarea element that should: Appear only when the textarea is focused Disappear when the textarea is out of focus ( ...

When the click event is triggered, the second function guess() does not execute

I am currently developing a number guessing application. It consists of two functions, the first one called startGame() works correctly (it receives the maximum number and then disappears by adding the hidden class). However, the second function that is ...

When the value is blank, do not include the class attribute when appending

http://jsbin.com/guvixara/1/edit I have a situation where I am dynamically inserting a button... $(".confirm-add-button").on("click", function() { var $ctrl = $('<button/>').attr({ class: $('.newbtnclassname').val()}).html($(& ...

Unable to load Highcharts from php json, however it is able to load from data.json file

I attempted to create a highchart using JSON data. I created a PHP file that generates the JSON and inserted the address into the getJSON() function like this: $(document).ready(function() { $.getJSON("data.php", function(json) { chart = new ...

Navigating with Reach Router only updates the URL, not the component being rendered

Is there a way to programmatically navigate using Reach Router in React? I have noticed that when updating the URL, the route does not render. Even though the URL changes, the original component remains displayed according to the React developer tools. Ho ...

Issue with Firefox causing problems with smooth scrolling Javascript on internal links

I recently created a one-page website using Bootstrap. The navigation menu items are internal links that point to different sections within the page, and I added some smooth scroll JavaScript for a more polished scrolling effect. While the website functio ...

css problem with stacking order of child elements

Trying to arrange 3 HTML elements on the z-plane: .bank { width: 200px; height: 200px; background-color: grey; position: absolute; z-index: 100; transform: translateY(10%); } .card { width: 100px; height: 100px; background-color ...

Is it possible to iterate over an enum using Object.entries<T>(Enum).map() in TypeScript, or does it only function with string-based enums?

Currently, I am in the process of developing a react form that requires users to select options related to a job. These options are represented by enums, with some being string-based and others number-based. For instance, here is an example of a string-ba ...

How to stop an AJAX request using Chrome developer tools?

Is there a way to cancel an initiated ajax request from Chrome Developer Tools? I want to test if my fallback message displays correctly without changing the code. Setting No throttling to Offline will make all calls fail, but I just need one API to fail f ...

Transformation of JSON data from Array to Object

I have a JSON data structure that looks like this: { tag: 'new-tag', stream_subjects: [1, 2, 3] } My goal is to transform it into the following format: { tag: 'new-tag', stream_subjects: [ {subject_id: 1}, {subject_id ...

Execute various settimeout or display functions on various elements of a webpage

Just a heads up, I'm not really experienced in development. More on the newbie side of things, but eager to learn. I've been looking for an answer to my question, but so far haven't come across anything that fits my specific situation. It m ...

Letters are frolicking in varying sizes and designs

Currently, I am encountering a strange issue with the text on my webpage. Some fonts are displaying with completely different shapes and sizes despite using <meta charset="UTF-8"> to ensure font consistency. Unfortunately, this did not resolve the pr ...

Using Slim Framework and AJAX to handle the forward slash character as a parameter

I am using an ajax call to communicate with a web service built on the Slim framework. This service is responsible for storing notes in my database. One issue I am facing is that users are allowed to input strings like "send 1/2 piece". This causes a prob ...

Manipulating data rows in a table using jquery

I have a button called #add that, when clicked, adds a new row to a table. The last cell of the newly inserted row contains a delete icon that, when clicked, should remove the entire row. I thought I had everything set up correctly, but for some reason, c ...

Retrieving data from an Array containing a mix of string and integer values represented as strings, organized by the length of the

Imagine you have an array structured like this: employeeArr = ['Steve', '80000', 'Jen', '90000', 'Bob', '40000'] Where employeeArr[0] and employeeArr[2] represent employee names, and employeeA ...

Mixed Protocol Error (HTTP/HTTPS)

I'm experiencing a mixed content error on my website, as it is using both http and https protocols. Chrome console displays the following error: Mixed Content: The page at '' was loaded over HTTPS, but requested an insecure XMLHttpReques ...

Replicate all Column Cell Input Values using the value of the first Cell in the Column as a

Is there a way to copy the input value from the first cell of a specific column in an HTML table, and paste that value into the remaining cells of that column? Essentially, the user would enter a value in the first cell, then by clicking a button, that v ...

Vue.js: The Power of Manipulating Strings

Why is the filter method not working with this.userId, but it is working with the hard-coded value "admin"? How can I resolve this issue? computed: { UidMessages: function() { return this.Messages.filter(function(m) { return m ...

Developing Dynamic Key-Driven State Management in ReactJS Using JavaScript

I am facing a challenge with a specific aspect of my ReactJS code, which is more about my comprehension of how JavaScript key/value arrays operate than anything else. How can I allow the key to be passed-in dynamically in the given example? The issue lies ...

Retrieve the Latest Information from the Asp.Table

My table setup is as follows: <asp:Table ID="model" runat='server'> <asp:TableRow> <asp:TableHeaderCell class="col-xs-2"> Name </asp:TableHeaderCell> <asp:TableHeaderCell class="col- ...