Is it possible to independently toggle multiple divs when one div is active using JQuery?

I am currently constructing a website where different layers of divs display various sections. The structure is as follows:

  1. GROUP
    • Multiple options (buttons; choose one of the subgroups)
  2. SUBGROUP
    • Multiple options (buttons; choose one of the subsubgroups)
  3. SUBSUBGROUPS etc.

My approach involves using JQuery to activate these different divs. However, I am seeking a way to navigate between the divs by clicking outside of them to deactivate them or by clicking on another div/button to override the current active div.

Is there a simple solution in JQuery and/or CSS to achieve this? Despite my attempts with methods like removeClass, addClass, toggleClass, or toggle, along with an .active class that controls the display property, I seem to be missing the correct mathematical solution especially when dealing with multiple layers and combinations.

// ACTIVATE DIVS
$(document).ready(function() {
  // 1. CONTINENTS
  $(".select-europe").click(function() {
    $("#official_countries").addClass("active");
  });
  // 2. RECOGNIZED STATES
  // 2.EU EUROPE
  $(".select-france").click(function() {
    $("#france-country").addClass("active");
  });
  $(".select-netherlands_the").click(function() {
    $("#netherlands_the-country").addClass("active");
  });
  // 3. STATE
  // 3.EU.FR FRANCE
  $(".select-france-divisions").click(function() {
    $("#france-divisions").addClass("active");
  });
  // 3.EU.NL NETHERLANDS, THE
  $(".select-netherlands_the-divisions").click(function() {
    $("#netherlands_the-divisions").addClass("active");
  });
});

// DE-ACTIVATE DIVS
$(document).on("click", function(event) {
  // 1. CONTINENTS
  // 2. RECOGNIZED STATES
  // 2.EU EUROPE
  var $trigger = $(".select-france");
  if ($trigger !== event.target && !$trigger.has(event.target).length) {
    $("#france-country").removeClass("active");
  }
  var $trigger = $(".select-netherlands_the");
  if ($trigger !== event.target && !$trigger.has(event.target).length) {
    $("#netherlands_the-country").removeClass("active");
  }
  // 3. STATE
  // 3.EU.FR FRANCE
  var $trigger = $(".select-france-divisions");
  if ($trigger !== event.target && !$trigger.has(event.target).length) {
    $("#france-divisions").removeClass("active");
  }
  // 3.EU.NL NETHERLANDS, THE
  var $trigger = $(".select-netherlands_the-divisions");
  if ($trigger !== event.target && !$trigger.has(event.target).length) {
    $("#netherlands_the-divisions").removeClass("active");
  }
});
#continents {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;

    background-color: #e6e6e6;
}

#official_countries,
#france-country,
#france-divisions,
#netherlands_the-country,
#netherlands_the-divisions {
    display: none;
    position: absolute;
    top: 0;
    height: 100%;

    border-left: 1px solid black;
}

#official_countries {
    left: 120px;
    width: calc(100% - 121px);

    background-color: #ccc;
}
#france-country,
#netherlands_the-country {
    left: 240px;
    width: calc(100% - 241px);

    background-color: #b3b3b3;
}

#france-divisions,
#netherlands_the-divisions {
    left: 360px;
    width: calc(100% - 361px);

    background-color: #999;
}

#official_countries.active,
#netherlands_the-country.active,
#france-country.active,
#france-divisions.active,
#netherlands_the-divisions.active {
  display: block;
}

.select-country {
  display: block;
}
.section {
  display: block
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="continents">
  <button class="select-europe">Europe</button>
</div>
<div id="official_countries">
  <div class="overview">
    <button class="select-country select-france">France</button>
    <button class="select-country select-netherlands_the">Netherlands, the</button>
  </div>
</div>
<div id="france-country">
  <header>French Republic</header>
  <div class="overview">
    <div class="section">
      <button class="select-france-divisions">France</button>
    </div>
  </div>
</div>
<div id="netherlands_the-country">
  <button class="select-netherlands_the-divisions">Netherlands, the</button>
</div>
<div id="france-divisions"></div>
<div id="netherlands_the-divisions"></div>

My expectations were that each preceding div which activated the one above it would close again upon clicking outside the higher div. However, some divs disappear when clicking on other divs either below or above them.

Answer №1

To customize the appearance and structure to fit your specific requirements:

$('li').on("click", function(e) {
e.stopPropagation();
let $el = $(this);
  if(!$el.children('ul').hasClass('active')) {
  $('#tree').find('ul').removeClass('active');
  $el.parentsUntil('#tree').addClass('active');
  }
  $el.children('ul').toggleClass('active');
});
ul {
  list-style-type: none;
  display:none;
}

#tree {
  display:block;
}

li {
  cursor: pointer;
  background: #F1F1F1;
  padding: 5px;
  border: 1px solid #CECECE;
}

.active {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="tree">
  <li>EU
    <ul>
      <li>FR
        <ul>
          <li>Division 1</li>
          <li>Division 2</li>
        </ul>
      </li>
      <li>NL
        <ul>
          <li>Division 1</li>
          <li>Division 2</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>US
    <ul>
        <li>TX
          <ul>
            <li>Division 1</li>
            <li>Division 2</li>
          </ul>
        </li>
        <li>NY
          <ul>
            <li>Division 1</li>
            <li>Division 2</li>
          </ul>
        </li>
      </ul>
  </li>
</ul>

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

Retrieve the observable value and store it in a variable within my Angular 13 component

Incorporating Angular 13, my service contains the following observable: private _user = new BehaviorSubject<ApplicationUser | null>(null); user$ = this._user.asObservable(); The ApplicationUser model is defined as: export interface ...

Error: The page "..." contains an invalid "default" export. The type "..." is not recognized in Next.js

Currently, I have a functional component set up for the Signup page. My goal is to define props within this component so that I can pass the necessary values to it from another component. This is my current approach: export default function SignupPage({mod ...

The unprojection of the vector in Threejs from this camera has not been defined

Why am I encountering a "function is undefined" error for vector.unproject even though it is clearly mentioned in the documentation? You can find it here: (one of the last items) Even after console logging it, the function still returns as undefined, des ...

A step-by-step guide on integrating dynamic components in vue-class-component

After successfully using vue-class-component in my project, I decided to introduce a new component for production only: import store from '../store/Index' let storeTmp = process.env.NODE_ENV === 'production' ? store : null @Component({ ...

What causes the appearance of 'GET/ 304 --' in my code? (vue.js, express)

While attempting to fetch data on the client-side using axios in vue.js, I encountered a server-side error with the code 'GET/ 304 --' The reason for this occurrence is unclear to me and I am unsure of how to troubleshoot or resolve it. If I re ...

A guide on accessing $bvToast in Vue class components

I am fairly new to vue.js but I have managed to figure out some things. I initially started with regular js, but then transitioned to typescript with class style vue components. For styling the components, I rely on bootstrap-vue. In my main.ts file, I im ...

conceal the mustard-colored dots within the overlay

Whenever I trigger the link, a modal window pops up, but it comes with an unwanted black background color and yellow dots. How can I prevent the yellow dots from showing up on the overlay? http://jsfiddle.net/y88WX/18/embedded/result/ <nav class="da-d ...

Error handling: Encountered unexpected issues while parsing templates in Angular 2

I'm a beginner with Angular 2 and I'm attempting to create a simple module, but encountering an error. app.component.html import { Component } from '@angular/core'; import { Timer } from '../app/modules/timer'; @Component({ ...

What is the best way to invoke a function inside a directive using an external controller?

After researching online, it appears that there are numerous questions similar to mine but unfortunately, none of the solutions provided worked for me. In my current situation, I have a directive which includes a function like this (within the directive): ...

Is incrementing x by 1 equivalent to x + 1?

I have a very basic angular application. It simply increases the value by 1 when clicked on using ng-click. Take a look at JSFiddle <div ng-app="app" ng-controller="ctrl"> <div ng-click="hello=hello+1">THIS WORKS ON CLICK: {{hello}}</d ...

experiencing difficulties utilizing the prompt package in nodeJS

Exploring the world of nodeJS as a novice, I recently dived into taking user input through the console in nodeJS. My journey led me to discover the prompt package. Here is snippet of the code I've been experimenting with: var prompt = require('p ...

Getting data with a data attribute - a step-by-step guide

I'm attempting to retrieve data from our API using a unique html method involving the data- attribute. I am able to successfully fetch the data directly and load it without any issues. However, when trying to access the data variable from the data att ...

When working with basic shapes such as "rect" or "circle," the inline SVG may not be displayed

This is the code we are using to style our checkboxes: .checkbox-default { display: inline-block; *display: inline; vertical-align: middle; margin: 0; padding: 0; width: 22px; height: 22px; background: url('data:image/ ...

Place the image within the div to the right side

My div element is narrower than the image it contains, and I've set the overflow property to hidden. As a result, only a portion of the image is visible from the left side. However, I would like to see a portion of the image from the right side inste ...

What's the connection between CSS and frameset?

Currently, I have an .html document with XHTML 1.0 Frameset doctype and the following code: <frameset rows="20%, 80%" border="1"> ... </frameset> Upon validating this code on W3C Validator, it gives me the error message: there is no a ...

"AngularJS View Source Page: Unveiling the Power of Dynamic Metatags

Hey there, I have a requirement where I need to update the metatags content dynamically. I successfully updated the content in INSPECT ELEMENT, but I am unable to see the updated content in the view source page. I want to update the metatags in the view ...

``After resizing the window height, the overlay is not expanding to fill the entire

Check out my CSS and HTML code snippets below: .overlay_ { position: absolute; width: 100%; height: 100vh; background: rgba(0, 0, 0, 0.9); z-index: 9999; } Html <body> <div class="overlay_"></div> </bo ...

The Navbar's expansion is being enhanced by non-collapsible items in the Boostrap 4 dropdown menu

I recently came across a helpful snippet in this question Bootstrap 4 - Navbar items outside the collapse that allowed me to create non-collapsible items for smaller viewports. However, I encountered an issue with a dropdown menu inside one of these items ...

Two consecutive instances of the outcome recorded in the ajax table

I am trying to add data to a table, but one of my results is appearing twice. Here is the JSON response I received: groupname […] 0 {…} survey_id 2 group_name DEMO 1 {…} survey_id 1 group_name TEST This is what my AJAX success function ...

Clicking outside of a Bootstrap 3 dropdown causes it to close

Let's analyze the code below: $(document).ready(function () { $('#dropdownMenu1').attr('aria-expanded', true); $('.dropdown').addClass('open'); $('#dropdownMenu1').on('hide.bs.dropdow ...