What is the best way to conceal two Bootstrap divs that should not both be visible at the same time?

I am working with two different types of charts: an Emotion chart and a Polarity chart. To control the visibility of these charts, I have implemented two buttons, one for each chart. The functionality is such that when the first button is clicked, only the Emotion chart should be displayed, while clicking the second button should hide the Emotion chart and show the Polarity chart.

Additionally, there is a separate button designed to hide whichever chart is currently active. My question is whether it is possible to achieve this hiding functionality using only Bootstrap without any JavaScript?

I have utilized event listeners to handle the click actions on each button. For a concise example showcasing this setup, please refer to the following link:

let isEmotionsButtonActivated = false;
let isPolarityButtonActivated = true;

const emotionsButton = document.getElementById("emotions");
const polarityButton = document.getElementById("polarity");

const emotionsChart = document.getElementById("multiCollapseExample1");
const polarityChart = document.getElementById("multiCollapseExample2");


polarityButton.classList.add("active");
polarityChart.classList.add("show");

emotionsButton.addEventListener("click", () => {
  if (!isEmotionsButtonActivated) {
    isEmotionsButtonActivated = true;
    isPolarityButtonActivated = false;

    polarityChart.classList.remove("show");
    emotionsChart.classList.add("show");

    emotionsButton.classList.add("active");
    polarityButton.classList.remove("active");
  }
});

polarityButton.addEventListener("click", () => {
  if (!isPolarityButtonActivated) {
    isEmotionsButtonActivated = false;
    isPolarityButtonActivated = true;
    
    emotionsChart.classList.remove("show");
    polarityChart.classList.add("show");

    emotionsButton.classList.remove("active");
    polarityButton.classList.add("active");
  }
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3b5954544f484f495a4b7b0e1508150a">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="62000d0d16111610031222574c514c53">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="btn-group btn-group-sm">
  <button class="btn btn-primary" id="emotions" type="button" data-bs-toggle="collapse" data-bs-target="#multiCollapseExample1" aria-expanded="false" aria-controls="multiCollapseExample1">Emotions</button>
  <button class="btn btn-primary" id="polarity" type="button" data-bs-toggle="collapse" data-bs-target="#multiCollapseExample2" aria-expanded="false" aria-controls="multiCollapseExample2">Polarity</button>
  
</div>
<button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target=".multi-collapse" aria-expanded="false" aria-controls="multiCollapseExample1 multiCollapseExample2">Hide</button>
<div class="row">
  <div class="col">
    <div class="collapse multi-collapse" id="multiCollapseExample1">
      <div class="card card-body">
        Emotions Chart Placeholder
      </div>
    </div>
  </div>
  <div class="col">
    <div class="collapse multi-collapse" id="multiCollapseExample2">
      <div class="card card-body">
        Polarity Chart Placeholder
      </div>
    </div>
  </div>
</div>
</body>
</html>

The current implementation of the Hide button hides the active chart while displaying the hidden chart simultaneously. Is there a way to modify this behavior within Bootstrap settings alone, without relying on JavaScript?

Removing the data-bs-target attribute from each button results in the immediate disappearance of the active chart upon button click, without any animation effect. Does this align with Bootstrap's expected behavior or is there a workaround? As someone new to Bootstrap, I initially assumed that eliminating the data-bs-target would prevent the button from having a targeted element to display.

Answer №1

Avoiding Custom JavaScript Solutions

This particular inquiry delves into the method of concealing Bootstrap Collapse components without resorting to custom JavaScript solutions.

It can indeed be achieved by encapsulating both components within another set of Collapses, which serves to either display or hide them.

The pivotal aspect in enabling toggling functionality is incorporating the .show class into the initial inner Collapse element. By doing so, Bootstrap seamlessly alternates between the two, ensuring that only one remains visible at a time. This approach eliminates the necessity for the original's extensive custom JavaScript code.

Sample Extract

<p>
Uncheck the hide button and toggle between charts with radio buttons.
</p>

<div class="btn-group" role="group" aria-label="Basic radio toggle button group">
  
    <input type="radio" 
      id="btnradio1"
      class="btn-check" 
      name="btnradio"
      autocomplete="off"
      checked
      data-bs-toggle="collapse" 
      data-bs-target=".multi-collapse">
    <label class="btn btn-outline-primary" for="btnradio1">
    Emotions
    </label>

    <input type="radio" 
      class="btn-check" 
      name="btnradio" 
      id="btnradio2" 
      autocomplete="off" 
      data-bs-toggle="collapse" 
      data-bs-target=".multi-collapse">
    <label class="btn btn-outline-primary" for="btnradio2">
    Polarity
    </label>

    <input type="checkbox" 
      class="btn-check" 
      id="check1" 
      autocomplete="off" 
      checked
      data-bs-toggle="collapse" 
      data-bs-target="#exampleCollapse">
    <label class="btn btn-outline-danger" for="check1">
    Hide
    </label>
    
</div>

<hr>

<div  id="exampleCollapse" class="collapse"> <!-- Added wrapper -->

  <div class="row">
    <div class="col">
      <div class="multi-collapse collapse show">  <!-- Added .show -->
        <div class="card card-body">
          Emotions Chart Placeholder
        </div>
      </div>
    </div>
    <div class="col">
      <div class="multi-collapse collapse">
        <div class="card card-body">
          Polarity Chart Placeholder
        </div>
      </div>
    </div>
  </div>

</div>

<!-- Bootstrap 5.3 -->
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d1b3bebea5a2a5a3b0a191e4ffe2ffe0">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="44262b2b30373036253404716a776a75">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"/>

UPDATE - Innovative Approach

In a subsequent question, the Original Poster (OP) inquired about the ability to programmatically sequence the collapse components while preserving the inherent animation. The issue with the initial code stems from directly toggling the .show class, resulting in an interruption of the animation flow. Bootstrap incorporates a CSS transition that gets disrupted when the .show class is removed post-toggling, causing interference in both animation and collapse events.

A more straightforward workaround involves utilizing Bootstrap's designated show/hide methods, as illustrated in the following demonstration.

Alternative Code Snippet

let button = document.getElementById('toggleButton');

let collapse1 = bootstrap.Collapse.getOrCreateInstance('#collapseExample1');

let collapse2 = bootstrap.Collapse.getOrCreateInstance('#collapseExample2');

let index = 0;

button.addEventListener('click', (e) => {

    // Logic for displaying graphs in a specific order

    index++;
  if (index > 3) index = 0;

  if (index === 0) {
    collapse1.hide();
    collapse2.hide();
  }
    else if (index === 1) {
    collapse1.show();
    collapse2.hide();
  }
    else if (index === 2) {
    collapse1.hide();
    collapse2.show();
  }
  else {
    collapse1.show();
    collapse2.show();
  }

});
<button id="toggleButton" class="btn btn-primary m-2" type="button">
    Toggle
</button>

  <div class="row">
    <div class="col">
      <div class="collapse" id="collapseExample1">
        <div class="card card-body">
          <h3>GRAPH 1</h3>
          <img class="img-fluid" src="https://i.sstatic.net/JOiNx.png">
        </div>
      </div>
    </div>
    <div class="col">
      <div class="collapse" id="collapseExample2">
        <div class="card card-body">
          <h3>GRAPH 2</h3>
          <img class="img-fluid" src="https://i.sstatic.net/JOiNx.png">
        </div>
      </div>
    </div>
  </div>
 
<!-- Bootstrap 5.3 -->

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1f7d70706b6c6b6d7e6f5f2a312c312d">[email protected]</a>/dist/css/bootstrap.min.css">

<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="31535e5e45424543504171041f021f03">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></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

Find the flowplayer when the page loads

Is there a way to make a flowplayer seek at the page load without it resetting? I've tried this: $(document).ready(function() { $f(0).seek(5); }); also tried: $(document).ready(function() { while(!$f(0).isLoaded()) { $f(0).seek(5); } }); ...

Adjust the size of the mouse cursor in real time

I'm currently in the process of developing a project where I want to create a web application with a mouse cursor that appears as a circle with a customizable radius, which can be altered by the user. The main requirement is for this custom cursor to ...

Having trouble getting a local npm installation to work from a specific file path?

After following the instructions from this helpful link to install an npm package through a file path, I encountered an error when attempting to use it: Cannot find module '<module_name>' or its corresponding type declaration Are there an ...

Load Angular template dynamically within the Component decorator

I am interested in dynamically loading an angular template, and this is what I have so far: import { getHTMLTemplate } from './util'; const dynamicTemplate = getHTMLTemplate(); @Component({ selector: 'app-button', // templat ...

Combine an array of objects into a regular object

Imagine having an array structure as shown below: const student = [ { firstName: 'Partho', Lastname: 'Das' }, { firstName: 'Bapon', Lastname: 'Sarkar' } ]; const profile = [ { education: 'SWE', profe ...

Understanding JSON Arrays using jQuery

I've been attempting to display JSON objects in the console, but unfortunately, I'm facing some issues. The JSON data is obtained from a small API that I crafted using PHP. Here's a snippet of my JSON: { TotalResults: 2, Results: [ ...

Integrating information from various sources to create a cohesive online platform

I am looking to incorporate data from various sources into a single web page: Social networks (Facebook, Twitter, LinkedIn, etc.) RSS feeds Article meta tags (particularly OpenGraph and Twitter cards) This data may change dynamically based on user inter ...

Step-by-step guide on programmatically activating a radio button

I am working with a radio button and input field. I need the ability to programmatically toggle the radio button so that when this.iAreaOfCoverageForThresholdPasser.average-height is set to true, the radio button appears highlighted. Snippet of HTML: < ...

Is there a way for redux-saga to pause until both actions occur at least once, regardless of the order in which they happen?

Just diving into Redux saga. I'm working on creating a saga that will fetch the initial state for the redux store from our API server. This task involves utilizing two asynchronous sagas: getCurrentUser and getGroups. The goal is to send these ajax ...

How can I programmatically trigger the opening of a Material-UI Accordion in ReactJS?

All of the Accordions are assigned unique IDs: const CategoryDisplay: React.FC<Props> = (props) => { ... return ( <> <Accordion id={`category-${accordion.id}`}/> </> ); }; export default CategoryDisplay ...

Deviations in Scriptaculous Callbacks during Movement Effects

I am looking to create a dynamic menu item that moves out 5px on mouseover and returns to its original position using Scriptaculous. I have implemented the afterFinish callback to ensure that the bump-out effect is completed before the item moves back in. ...

Addressing component validation conflicts in Vuelidate on VUE 3

I am currently experiencing an issue with VUE 3 Vuelidate. In my project, I have 2 components that each use Vuelidate for validation (specifically a list with CRUD functionality implemented using modals). However, when I navigate from one component to anot ...

Create HTML elements based on the information in a JSON object

My goal is to create span elements for each word in my subtitle text, which is stored in a JSON object. Here is the JSON data I am working with: var sub_info = [ {'start': 3.92, 'end': 6.84, 'words ...

Node-pty in NWjs application causing DLL malfunction

When attempting to run a terminal emulator / command prompt in NW.js using xterm JS and node-pty, I encountered a DLL Error. The following is the log: Uncaught Error: A DLL Initialization Routine Failed. \\?\C:\Users\volke.a\ ...

Error found in Paper.js at line 81: Uncaught TypeError - Unable to access properties of undefined (specifically '1') while utilizing Material UI and Joy UI

I am encountering an issue while using react js with material UI and JoyUI, where I am getting a blank screen. Below is the code snippet causing the problem: import React from 'react'; import { CssVarsProvider } from '@mui/joy/styles'; ...

Attempting to develop a filtering feature using ReactJS

Having some trouble with the if statement in my filter list function. Can't seem to figure out why it's not working properly. Here is the code snippet: filterList (event) { var updatedList = this.props.array; var filterText = this.stat ...

Launching a Node.js script with pm2 and implementing a delay

Utilizing the amazing pm2 package to maintain the longevity of my node.js applications has been extremely helpful. However, I have encountered a problem that I am unsure how to resolve. One of my applications involves multiple scripts, a server, and sever ...

How do useCases interact with each other within Clean Architecture principles in NodeJS?

I'm currently working on implementing Bob Martin's Clean Architecture in my project, and I have a question. How do use-cases interact with each other? For instance: In my project, there are entities for Department and Employee. The Department ...

Region Covered by Mouse Over Does Not Extend Across Whole Div

On my website, there is an arrow located on the middle right side that, when hovered over with the mouse, reveals a sidebar. Clicking on each icon in the sidebar further extends it to reveal more content. However, the issue I am facing is that the sidebar ...

Issue with Google Maps iFrame not loading when utilizing JavaScript variables in the "src" attribute

Currently, I am facing an issue with utilizing JavaScript variables containing GPS latitude and longitude values in the "src" attribute of an iFrame in an HTML file for displaying image EXIF data on a Google Maps iFrame. When I hardcode specific latitude ...