Enhanced Button Dropdown Function

I have the following HTML code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Expanding Dropdown Menu</title>
    
    [CSS styling omitted for brevity]
        
</head>
<body>
    <div class="custom-box">
      
      [Content of custom box omitted for brevity]

        <button class="custom-button" id="dropdown-button">Click Me</button>
        
        <div class="dropdown-content" id="dropdown-menu">
            <div class="dropdown-item">Dropdown Text 1<div>
            <div class="dropdown-item">>Hidden text 1</div>
            
            <div class="dropdown-item">Dropdown Text 2<div>
            <div class="dropdown-item">Hidden Text 2</div>
            
            <div class="nested-dropdown-item">Nested Dropdown Text 3<div>
            <div class="nested-hidden-text">Nested Hidden Text 3</div>
        </div>
    </div>

    <script>
        const dropdownButton = document.getElementById('dropdown-button');
        const dropdownMenu = document.getElementById('dropdown-menu');

        dropdownButton.addEventListener('click', () => {
            dropdownMenu.style.display = dropdownMenu.style.display === 'none' ? 'flex' : 'none';
        });
    </script>
</body>
</html>

In this code snippet, the "Not Dropdown Text" signifies regular text without any dropdown functionalities. On the other hand, "Dropdown Text" indicates a text element that can be expanded to reveal hidden content.

How do I implement nested dropdowns within this existing structure? Specifically, clicking on a text element with further dropdown capabilities should reveal additional hidden text within the dropdown menu.

Answer №1

One way to address the issue is by implementing a nested list structure that contains more detailed information.

The click handler for the panel has been modified to activate upon clicking the title itself, allowing users to open and close elements within the body.

document.querySelector('.tile-label')
  .addEventListener('click', function() {
    const _parent = this.parentNode;
    _parent.classList.toggle('expanded');
    const plus = _parent.querySelector('.plus');
    plus.style.transform = _parent.classList.contains('expanded') ? 'rotate(45deg)' : 'rotate(0)';
  });

const toggleChild = (e) => {

  if (e.currentTarget == e.target) {
    const el = e.target;
    el.classList.toggle("active")
  }
}

const level2 = document.querySelectorAll(".hidden-text ul li:has(ul)");

level2.forEach((li) => li.addEventListener("click", toggleChild))
.tile-container {
  padding: 5px;
  font-size: 25px;
}

.rectangle {
  background-color: #0051a5;
  padding-right: 1em;
  padding-top: 1em;
  border-radius: 1em;
  display: grid;
  grid-template-rows: 1fr auto;
  grid-template-columns: auto 1em;
  grid-template-areas: "sample plus" "extratext extratext";
}

plus {
  grid-area: plus;
  background: linear-gradient(#0051a5 0 0), linear-gradient(#0051a5 0 0), #fff;
  background-position: center;
  background-size: 60% 2.5px, 2.5px 60%;
  background-repeat: no-repeat;
  transition: transform 0.3s ease;
}

.radius {
  border-radius: 50%;
  width: 1em;
  height: 1em;
  margin-right: 1em;
}

.tile-label {
  grid-area: sample;
  font-family: 'PT Sans Narrow', sans-serif;
  font-size: 1em;
  text-transform: uppercase;
  cursor: pointer;
  font-weight: 600;
  color: #fff;
  padding-left: 1em;
  height: 2em;
}

.tile-accent {
  color: #FFC72C;
}

.hidden-text {
  grid-area: extratext;
  display: none;
  font-family: 'PT Sans Narrow', sans-serif;
  font-size: 0.75em;
  background-color: #fff;
  color: #000;
  margin: 1em;
  padding-top: 0.5em;
  padding-left: 1em;
}

.expanded>.hidden-text {
  display: block;
  animation: fade-in 1s;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
  }

...
</body>

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 to apply an icon image using the background property in CSS in Vue 3

Need help setting background image from the public folder |_public | |_images | |_icon.png |_src |_components |_TheHeader.vue I'm having difficulty trying to set an image as a background in TheHeader.vue using CSS, but the image is located in ...

Divide a list Observable into two parts

In my code, I have an Observable called 'allItems$' which fetches an array of Items. The Items[] array looks something like this: [false, false, true, false] My goal is to split the 'allItems$' Observable into two separate Observables ...

NodeJS: Issue when implementing try/catch with async/await causing SyntaxError

As a newcomer to Node Js, I am struggling to understand why the code below is throwing a syntax error with catch(). I recently updated to Node JS V14. Any assistance would be greatly appreciated. async function demoPromise() { try { let message ...

Vue3 CheckBox Component: A versatile option for interactive user interfaces

Struggling with incorporating checkboxes into a separate component. I have a child component with a basic card template and checkbox - essentially, a product list where each card should have a checkbox for deletion. Currently, as I loop through an array to ...

The scroll bar is acting peculiarly when the height is adjusted

I need assistance creating a chat widget that has a maximum height for the entire chat and allows the content to fill in without specifying fixed heights within the chat itself. Below is my code: HTML <section class="boxlr-chat"> <div class= ...

Using AJAX to dynamically update a div's class following a POST request

Upon double clicking a row, I am attempting to trigger the function outlined below. Despite my efforts, I have not been able to update the div class with any changes. function book(id) { $.ajax({ type: "POST", url: "ajax_servlet. ...

Two flexible-sized containers placed side by side, with an ellipsis displayed on the left container

Can you achieve a layout where two elements are inside a container and float side-by-side? The right element should adjust its size based on the content while the left element fills the remaining space in the container with an ellipsis to truncate overflow ...

Obtaining a Gatsby image from Sanity.io results in displaying an image that is of poor quality and smaller in size

Currently, I'm in the process of developing a Gatsby site and pulling my content from Sanity.io. The issue I am facing is that some of the images fetched from the Sanity.io CDN are noticeably lower in quality compared to the images sourced from my own ...

Stopping the Game Loop in Windows Phone 8.1 with WinJS

Despite everything working smoothly, I am facing an issue with stopping the game loop when the Start button is pressed and the app is moved to the background. The event handler for suspend, app.oncheckpoint = function(args) {}, does not seem to fire for t ...

I encountered an issue when trying to run the npm start command. Can anyone help

I have encountered some errors in my React project and attached an image. Can someone guide me on how to resolve these issues? I am new to React and struggling with this. ...

The Angular Material dialog fails to display content when triggered within an event listener in Google Maps

Within my project, I am utilizing Angular 6.0.6 and Angular Material 6.3.0. One issue I have encountered is with a dialog component that I have added to the entryComponents in the app module. Strangely, when I attempt to open this dialog within the rightcl ...

Developing a feature that allows users to switch between different sets of information

I'm currently exploring a new project and attempting to design a toggle that switches between monthly and annual payments based on the user's selection, much like the functionality found here: . At present, I have implemented two sets of price c ...

The currency exchange script is malfunctioning and not functioning properly

Is there a solution for accessing the JSON value that is currently eluding me? If anyone has any suggestions, I would greatly appreciate it. function forex() { var to = document.getElementById("to").value; alert(to); var from = document.getE ...

Display a preview window once the image has been chosen

I have created an image preview div to show the selected image's thumbnail. Everything was working fine so far. But now, I want this div to be hidden when the page initially loads and only become visible when a user selects an image to upload. Here is ...

Trouble with Bootstrap popover displaying content

I've been working on implementing the bootstrap popover feature on a website and have had some success. I managed to get the popover to appear when the link is clicked, but unfortunately, I'm not seeing any content in the box other than the title ...

Unable to modify the state that has been passed down to each image on its own

I'm a beginner in React and I am currently working on two components that need to share and update the same state. To achieve this, I have lifted the state up to the parent component. The purpose of this shared state is to display a loading animation ...

Stop the automatic hiding of the sticky header when reaching the bottom of the page

I have implemented the position: sticky property for my website's header. However, I am facing an issue where the header becomes hidden when I scroll halfway down the page (bottom on mobile devices). Can anyone suggest a solution to fix this problem? ...

Choose particular text within the editorState

I'm in the process of developing a sophisticated text editor utilizing draftjs. Take a look at this basic codesandbox to get a better understanding of the issue at hand. One of the challenges I'm facing is with a helper function called getCurren ...

Styling with CSS: Changing the Background Color of Text

Looking for a solution to apply line-height to text without affecting the background color? Check out the code snippet below and share your ideas if you have any. Thanks! .nb-semnox-impact-grid { display: block; font-size: 6 ...

Tips for choosing the following row in an Angular user interface grid

How can I deselect the currently selected row and select the one that follows it by clicking a button? I am using AngularHotkeys.js for this purpose. It gets even more complicated because I can sort the table with different columns. It would be helpful to ...