Reveal and Conceal accordion elements

https://i.sstatic.net/y4KNM.png

I am looking to create an accordion effect similar to the one shown in the image. When a lesson is completed, it should hide and display the next lesson in line. Additionally, I want to ensure that only one accordion remains open at a time. How can I achieve this using Laravel, Bootstrap, and JS?

Answer №1

Here is an example that can serve as a reference

  [aria-expanded="false"] > .expanded, [aria-expanded="true"] > .collapsed {
        display: none;
    }
    
    p {
      margin-left:14px;
      font-size:12px;
      color:#333;
      margin-bottom:-6px;
    }
<link href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" rel="stylesheet"/>
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
        
        
 
<div id="accordion">
    <div class="card">
        <div class="card-header">
            <a class="card-link" data-toggle="collapse" href="#menuone" aria-expanded="false" aria-controls="menuone">
                <span class="collapsed"><i class="fa fa-chevron-right"></i></span> 
                <span class="expanded"><i class="fa fa-chevron-down"></i></span> 
                <strong>Section-1</strong>
                <p>
                  0/1 | 30 Min
                </p>
            </a>
        </div>
        <div id="menuone" class="collapse">
          <div class="card-body">
              section description-1
          </div>
        </div>
    </div>
 
    <div class="card">
        <div class="card-header">
            <a class="card-link" data-toggle="collapse" href="#menutwo" aria-expanded="false" aria-controls="menutwo">
                <span class="collapsed"><i class="fa fa-chevron-right"></i></span> 
                <span class="expanded"><i class="fa fa-chevron-down"></i></span> 
                <strong>Section-2</strong>
                <p>
                  0/2 | 45 Min
                </p>
            </a>
        </div>
        <div id="menutwo" class="collapse">
          <div class="card-body">
                  section description-2
          </div>
        </div>
    </div>
 
    <div class="card">
        <div class="card-header">
            <a class="card-link" data-toggle="collapse"  href="#menu3" aria-expanded="false" aria-controls="menu3">
                <span class="collapsed"><i class="fa fa-chevron-right"></i></span> 
                <span class="expanded"><i class="fa fa-chevron-down"></i></span> 
                <strong>Section-3</strong>
                <p>
                  0/3 | 23 Min
                </p>
            </a>
        </div>
        <div id="menu3" class="collapse">
          <div class="card-body">
                  section description-3
          </div>
        </div>
    </div>
</div>

Demo jsfiddle : https://jsfiddle.net/4oue8cL9/

Answer №2

This script is designed to check each checkbox within a dropdown menu. If all checkboxes are checked, it will advance to the next dropdown. If it's the last dropdown, it will simply close itself.

      const dropdowns = document.querySelectorAll(".dropdown");
      dropdowns.forEach((e, i) => {
        const h = e.querySelector(".info");
        h.addEventListener("click", () => {
          dropdowns.forEach((ee, ii) => {
            const c = ee.querySelector(".content");
            if (ii != i) c.style.display = "none";
            else {
              if (c.style.display == "none" || c.style.display == "") c.style.display = "flex";
              else c.style.display = "none";
            }
          });
        });

        const c = e.querySelector(".content");
        const checks = c.querySelectorAll("input[type='checkbox']");
        checks.forEach((e) => {
          e.addEventListener("change", () => {
            const cs = Array.from(c.querySelectorAll("input[type='checkbox']")).map((e) => e.checked);
            if (cs.indexOf(false) == -1 && i < dropdowns.length - 1) {
              dropdowns.forEach((ee, ii) => {
                const c = ee.querySelector(".content");
                if (ii != i + 1) c.style.display = "none";
                else {
                  if (c.style.display == "none" || c.style.display == "") c.style.display = "flex";
                  else c.style.display = "none";
                }
              });
            } else if (cs.indexOf(false) == -1) {
              c.style.display = "none";
            }
          });
        });
      });
      .dropdown {
        background-color: green;
      }

      .dropdown > .info {
        background-color: lightgray;
        border-bottom: 1px solid gray;
        display: flex;
        flex-direction: column;
        padding: 10px;
        cursor: pointer;
      }

      .dropdown > .content {
        background-color: grey;
        display: flex;
        flex-direction: column;
        padding: 10px;
        display: none;
      }

      h2,
      p {
        margin: 0;
        padding: 0;
      }
<div class="dropdown">
      <div class="info">
        <h2>header</h2>
        <p>information</p>
      </div>
      <div class="content">
        <p><input type="checkbox" name="" id="" /> Lesson 1</p>
        <p><input type="checkbox" name="" id="" /> Lesson 2</p>
        <p><input type="checkbox" name="" id="" /> Lesson 3</p>
      </div>
    </div>

    <div class="dropdown">
      <div class="info">
        <h2>header</h2>
        <p>information</p>
      </div>
      <div class="content">
        <p>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia, optio in? Consequuntur voluptatibus
          repellat neque, aliquid maiores quisquam. Laborum ut minima id accusamus exercitationem, in obcaecati alias
          ducimus et ipsum.
        </p>
      </div>
    </div>

    <div class="dropdown">
      <div class="info">
        <h2>header</h2>
        <p>information</p>
      </div>
      <div class="content">
        <p><input type="checkbox" name="" id="" /> Lesson 1</p>
        <p><input type="checkbox" name="" id="" /> Lesson 2</p>
        <p><input type="checkbox" name="" id="" /> Lesson 3</p>
      </div>
    </div>

    <div class="dropdown">
      <div class="info">
        <h2>header</h2>
        <p>information</p>
      </div>
      <div class="content">
        <p><input type="checkbox" name="" id="" /> Lesson 1</p>
        <p><input type="checkbox" name="" id="" /> Lesson 2</p>
        <p><input type="checkbox" name="" id="" /> Lesson 3</p>
      </div>
    </div>

    <div class="dropdown">
      <div class="info">
        <h2>header</h2>
        <p>information</p>
      </div>
      <div class="content">
        <p><input type="checkbox" name="" id="" /> Lesson 1</p>
        <p><input type="checkbox" name="" id="" /> Lesson 2</p>
        <p><input type="checkbox" name="" id="" /> Lesson 3</p>
      </div>

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

How can I navigate between pages without losing the data entered in the form fields

Is there a way in Ajax or jQuery to save form data and navigate between multiple form pages without using PHP Sessions? I want the form data to be saved until the user submits it, and when they do submit, all information from different pages should be in ...

"Encountering an error: invalid CSRF token in Node.js csurf

I have been utilizing the npm module csurf to generate a token. Initially, I retrieve the token from the server and then utilize it for the /register request. When I replicate these steps in Postman, everything seems to function correctly, but unfortunatel ...

Scheduled Job unable to complete post request

(I am completely new to the world of JavaScript, node.js, and Heroku so I apologize in advance if my question is not very clear) I recently set up a Heroku node.js application with a scheduled task that should run every hour. The task does run as expecte ...

How do I determine in Selenium if I have successfully scrolled to the bottom of the page?

Imagine a situation where a list of elements is loaded dynamically in chunks at runtime. Whenever you scroll the page, more data is fetched and displayed. I am currently looking for a way to determine if I have reached the bottom of the page after scroll ...

What could be causing Mathjax to generate multiple copies?

I have integrated MathJax into my application to render MathML. The code snippet below is used to ensure that the MathML is typeset properly: $rootScope.$watch(function() { MathJax.Hub.Queue(["Typeset", MathJax.Hub]); return true; }); However, I ...

Looking for a way to execute MySQL queries using promises in Protractor?

Is there a way to query a MySQL database using promises in Protractor? I have multiple queries that I need to execute during test execution, but my `executeSelectQuery` function always runs at the beginning of the test. How can I ensure it executes at the ...

Experience the feeling of releasing momentum by click and dragging the scroll

One feature I am looking for is the ability to control the scroll speed when dragging, and have the scroll continue moving slightly after release instead of stopping instantly. CodePen: https://codepen.io/rKaiser/pen/qGomdR I can adjust the speed adequat ...

Tips for transferring a JavaScript variable to a servlet

I have implemented the selectable jquery plugin on my JSP page. I need to pass the selected string as a parameter to a servlet when the form is submitted. $(function() { $("#selectable").selectable({ stop: function() { var result = ...

most efficient method of sharing information between various angular controllers

I am looking for a way to share form data among multiple controllers before submitting it. Currently, I am using module.value() to store the data as a global variable. var serviceApp = angular.module('sampleservice', [ ]); serviceApp.valu ...

Guide on retrieving the ID after a new entry is added using a trigger in Express.js and MySQL

Currently, I am utilizing express and workbench to set up a database for handling the creation, viewing, and updating of cars. When I make a POST request to add a new car, it generates a new entry with details such as manufacturer, model, and price. I hav ...

How can I stop popup labels from appearing in MapBox GL JS when I don't want them to be visible?

Having created an application using MapBox GL JS, I have placed numerous markers all around the globe. As the mouse hovers over these markers, a description box pops up, which is what I intended. However, I am encountering an issue where these labels flick ...

Is it possible to enable tooltips to function through the innerHTML method?

Currently, I am utilizing the innerHTML attribute to modify the inner HTML of a tag. In this instance, it involves the <td></td> tag, but it could be applied to any tag: <td *matCellDef="let order" mat-cell [innerHTML]="order. ...

Establishing a Next.js API endpoint at the root level

I have a webpage located at URL root, which has been developed using React. Now, I am looking to create an API endpoint on the root as well. `http://localhost:3000/` > directs to the React page `http://localhost:3000/foo` > leads to the Next API end ...

Retrieving information stored in local storage from a different path using Vuex

Using the config panel route, I am fetching data and setting it to local storage using Vuex and StoreJS: const state = { message: [], // console.log(message); sec: 0, // other state }; const getters = { message: ( ...

Configuration of an MVC-based web application

As a newcomer to web application development, I am currently working on building a web application using the Model-View-Controller pattern. My setup includes a MySQL database for the Model, JSP pages for the Views, and a DAO for the Controller. I am looki ...

The mat card doesn't quite align with the rest of the page

I am currently utilizing Angular Material and Bootstrap in my project. My aim is to display a mat-card that fits perfectly on all screen sizes. However, I am encountering empty spaces on the right side of the card. While it fits properly on some screen ...

Looking to incorporate CGST and SGST into the Subtotal using JQuery?

I have come across this particular HTML Code in an Invoice: <tr> <td colspan="3" class="blank"></td> <td colspan="2" class="total-line">Subtotal Rs.</td> <td td class="t ...

Unable to retrieve value from a hidden input field using JavaScript

My goal is to retrieve a value from a hidden inputbox using JavaScript. However, I am encountering issues where sometimes I receive an "undefined" error and other times there is no output at all. When I utilize alert(document.getElementById('hhh& ...

SMMRY API bug stemming from a lack of necessary variables

Here is the code snippet: // Article Summary var params = { host: 'api.smmry.com', path: '/', body: { SM_API_KEY: 'B...', SM_URL: 'www.bbc.com/sampleNews' } }; http.get(params, functi ...

PHP code cannot be executed due to a problem with Angular routing

I stumbled upon this previous discussion during my search for assistance with a particular problem, but unfortunately there were no responses that could provide a solution. The issue I am facing involves submitting a form and expecting to receive a php va ...