Broaden the menu options to allow for expanding or collapsing all menus, regardless of their current state

I currently have 4 expandable menus and 5 buttons. The button labeled Collapse first controls the first menu, while the Collapse second button controls the second menu, and so on.

The current behavior: The Collapse all button for each menu will close it if it is expanded and expand it if it is closed.

Desired outcome: However, I would like the Collapse all button to expand all menus that are closed and leave them unchanged if they are already expanded. Then, if clicked again, it should close any open menus without affecting those that are already closed. Here is a fiddle I created for the current behavior: expand menu fidlle

.row {
  background: #f8f9fa;
  margin-top: 20px;
}

.col {
  border: solid 1px #6c757d;
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet"/>

<p>
  <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseExample1, #collapseExample2, #collapseExample3, #collapseExample4" aria-expanded="false" aria-controls="collapseExample">
    Collapse all
  </button>
   <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseExample1" aria-expanded="false" aria-controls="collapseExample">
    Collapse first
  </button>
  <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseExample2" aria-expanded="false" aria-controls="collapseExample">
    Collapse second
  </button>
  <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseExample3" aria-expanded="false" aria-controls="collapseExample">
    Collapse third
  </button>
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseExample4" aria-expanded="false" aria-controls="collapseExample">
    Collapse fourth
  </button>
</p>
<div class="collapse" id="collapseExample1">
  <div class="card card-body">
    hi first
  </div>
</div>
<div class="collapse" id="collapseExample2">
  <div class="card card-body">
    hi second
  </div>
</div>
<div class="collapse" id="collapseExample3">
  <div class="card card-body">
    hi third
  </div>
</div>
<div class="collapse" id="collapseExample4">
  <div class="card card-body">
    hi fourth
  </div>
</div>

How can I achieve this?

Answer №1

One possible simple solution that comes to mind is to create a custom handler for the collapse all button click event. This handler can show or hide all collapsibles based on the state of the collapse all button, instead of using Bootstrap's built-in data-toggle="collapse" and data-target="*".

<p>
    <button id="toggle-all" class="btn btn-primary" type="button">
        Collapse all
    </button>
    <button class="btn btn-primary" type="button" data-toggle="collapse" ... />
    ...
</p>
<div class="collapse" />
...

By managing the state of the Collapse all button within its click event, you can use a state variable (via data-) to determine whether to show or hide all collapsibles. Depending on this variable, you can then manually call either .collapse('show') or .collapse('hide') on all collapsibles.

The show method will not re-show a collapsible if it is already shown, and the hide method will not re-hide a collapsible if it is already hidden.

$(function() {
    $('#toggle-all').click(function() {
        // Declare a variable, `data-to-show`, to store the state of showing/hiding all collapsibles.
        // Initially set to true for showing all collapsibles.
        if (!$(this).data('to-show')) {
            $(this).data('to-show', true);
        } else {
            $(this).data('to-show', !$(this).data('to-show'));
        }
        
        if ($(this).data('to-show')) {
            $('.collapse').collapse('show');
        } else {
            $('.collapse').collapse('hide');
        }
        return false;
    });
});

https://i.sstatic.net/gDHsf.gif


demo: https://jsfiddle.net/davidliang2008/cvy2kbpz/28/


Another alternative approach could involve introducing an additional data attribute like

data-toggle-all-at-the-same-time="true"
, and modifying Bootstrap's .collapse() function accordingly. This modification would prevent toggling elements that are already in the desired state when the specified data attribute is true.

Unfortunately, I haven't discovered a straightforward way to achieve this yet.

Answer №2

One effective solution is to implement the toggle function provided by jQuery. For more information, refer to the official documentation here.

This particular function effectively conceals an element if it is currently visible, or reveals it if it is hidden. It operates smoothly and efficiently without the need for extensive validation checks.

Answer №3

  • To incorporate jQuery into your HTML page, place the script at the bottom of the file, making sure it is the last element within the body tag.
  • Next, include all JavaScript files from the Bootstrap folder (if you have downloaded it).

Add the following tags to your script, just before the closing body tag:

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="69190619190c1b47031a295847585f4758">[email protected]</a>/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>

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

JQuery error displaying [object Object]

I'm currently working on a calendar project where I have created a page to display events scheduled for a specific day. To ensure a seamless user experience without the need to reload the page every time a new event is added, I am utilizing Ajax. Us ...

The serialization method in ajax is not providing the expected values as needed

Having trouble retrieving all the necessary form inputs using AJAX, jQuery, and Bootstrap modal. The serialize method is not returning all the required values. Specifically, I am missing the user_id and btn_action values. What could be the issue? I'v ...

Using a directive to implement Angular Drag and Drop functionality between two tables with 1000 records

My code is functional, but there seems to be a delay in the appearance of the helper(clone) when dragging starts. I have two tables - one for the include list and another for the exclude list. Users can drag table rows from the include table to the exclud ...

Handling onclick events in Scrapy Splash: A comprehensive guide

I am attempting to extract data from the following website I have managed to receive a response, but I am unsure how to access the inner data of the items below for scraping: It seems that accessing the items requires handling JavaScript and pagination. ...

Showing JSON data as a table in an HTML format

After receiving the JSON String from the server as a response, which can be viewed here, I've implemented the following Jquery Code: function loadCategories() { $.ajax({ type: "POST", url: "/Services/ControllerService. ...

Encountering a JavaScript error in IE 11 and below where a closing parenthesis is expected, along with AJAX functionality not functioning properly in IE 11

Within my script, an AJAX call is being made as follows: (function() { var setup, validation; var errorMessage = ''; var errorClass = ''; var element = ''; var errorElement = ''; var allOk = true; var testTelefon = ...

I am experiencing some difficulties with my animation in three js. Despite clicking on the button, the animation does not seem to play. What could

My goal is to create an animation where boxes move when the start button is clicked. However, I am facing an issue where clicking the start button does not initiate any movement in the boxes. Could someone help me identify and solve this problem? For ref ...

Currency Conversion Rates Showcased

Why does the exchange rate consistently show as N/A in the code below after selecting a currency pair, and how can this issue be resolved effectively? I anticipate that the exchange rate value will be displayed accurately once a pair is selected. What st ...

Choosing between cjs and esm for a React components library

I'm working on a components library that will soon be published to npm for use in a razzle app. My main query revolves around the best practices for building these packages - should they be built with CommonJS (cjs) or ECMAScript Modules (esm)? And wh ...

Using Javascript Regular Expressions to validate that the first number in an amount is non-zero

Need a solution to only accept numbers that do not start with zero, but can contain zeros after the first digit. Currently using var.replace(/[^1-9]/g, ''); which prevents input of 0 altogether. Examples of valid inputs: 10 9990 Examples of in ...

Sharing Data Between Controllers in AngularJS

I am faced with a challenge involving two Angular controllers: function Ctrl1($scope) { $scope.prop1 = "First"; } function Ctrl2($scope) { $scope.prop2 = "Second"; $scope.both = Ctrl1.prop1 + $scope.prop2; //Ideally, I would like to achieve t ...

Adjust the list separator based on screen size fluctuations using media queries

I'm trying to figure out how to manage separators (such as a "-") between each element of a list. It's easy when it's just one line, but I'm having trouble with multiple lines. On a large screen, my site looks like this: Example cente ...

Not every menu item will have radius corners applied to its end

Here is my customized menu - <div ><ul id="menu"> <li class="one"><a href="http://www.domain.com">Home</a></li> <li class="two"><a href="<?php echo bp_loggedin_user_domain() ?>">Profil ...

Randomize the array values and assign them to div elements using jQuery or JS

Currently, I am in the process of constructing a unique CSS masonry layout that accommodates varying heights and widths. There are 5 different sizes available which will be assigned randomly to each <li>. Additionally, every subsequent <li> ele ...

Instructions for inserting text into a donut chart created with Google, utilizing basic HTML, JavaScript, or jQuery syntax

Are there any attributes in Google Chart that I should know about? I am just starting to use Google Charts and would appreciate some guidance. Here is the code snippet I am working with: function drawChart() { var data = google.visualization.arrayTo ...

What is the best way to retrieve the transpiled string from babel-core?

I've been attempting to utilize babel with npm and it seems like the necessary package is babel-core. My goal is to provide it with a string of ES6 code and receive a transpiled code string in return. It sounds simple enough, but I'm having troub ...

Ways to assign numerical values to vertical bars using HTML and CSS

Is there a way to create a Y-axis style line in HTML and CSS that looks like an actual Y-axis? I've attempted the following approach, which technically works but doesn't have the desired appearance. #mySpan{ writing-mode: vertical-lr; ...

I'm having trouble with Material Design Slide Toggle as it lacks event.StopPropagation functionality. Any suggestions on what alternative I

When working with the Slide Toggle in Material Design, I noticed that it does not have a stopPropagation event. This is because the "MdSlideToggle.prototype._onChangeEvent" already includes a call to stopPropagation. So, what should be used instead? <m ...

Is OnPush Change Detection failing to detect state changes?

Curious about the issue with the OnPush change detection strategy not functioning properly in this demonstration. My understanding is that OnPush change detection should activate when a property reference changes. To ensure this, a new array must be set e ...

Illuminate the current page

I have been working on a website with around 20 pages that all have a side navigation bar. To make it easier to manage, I decided to centralize the links in a JavaScript (JS) file and include it on each HTML page. This way, any changes can be made quickly ...