Positioning Multi-level Drop Down Div in Javascript - How to do it efficiently?

I'm currently working on a horizontal menu using CSS and JavaScript with multiple levels. I've implemented a toggle function to show the submenu container, but it's causing the links below it to be pushed down. Is there a way to make the displayed div container appear beneath the other links when clicked? Additionally, I'd like to restrict only one link to be selected, but I'm not sure how to achieve that. I have limited experience with JavaScript and CSS so any help would be appreciated.

Most of the styling has been removed from my code for clarity, but here is the basic functionality:

#togglebox {
  display:none;
}

#togglebox li{
  display: inline-block;
}

#extrabox {
  display:none;
  background: #E6ECF2;
  text-align: center;
  min-width: 100%;
}

#extrabox li{
  display: inline-block;
}

#extrabox2 {
  display:none;
  background: #E6ECF2;
  text-align: center;
  min-width: 100%;
}

#extrabox2 li{
  display: inline-block;
}

function toggle_visibility(id) {
   var e = document.getElementById(id);
   if(e.style.display == 'block')
      e.style.display = 'none';
   else
      e.style.display = 'block';
}

<ul class="sub-menu" style="display:inline;">
  <a href="#"><li id="NSM1">Normal Sub Menu</li></a></td>
  <a href="#" onclick="toggle_visibility('togglebox');"><li id="SMEL">Sub-menu Item with Second Level</li></a>
  <a href="#"><li id="NSM2">Normal Sub Menu</li></a>  
  <br />          
</ul>

<div id="togglebox">
  <a href="#"><li id="NSSL1">[Normal Link]</li></a>
  <a href="#" onclick="toggle_visibility('extrabox');"><li id="SSL2">[Has extra Level]</li></a>
  <div id="extrabox">
    <a href="#"><li id="sublinkea">3rd level item1</li></a>
    <a href="#"><li id="sublinkeb">3rd level item2</li></a>
    <a href="#"><li id="sublinkea">3rd level item3</li></a>
    <a href="#"><li id="sublinkeb">3rd level item4</li></a>                    
  </div>
                        
  <a href="#" onclick="toggle_visibility('extrabox2');"><li id="SSL3"><li id="sublinksc">[Has Extra Level]</li></a>
                                
  <div id="extrabox2">
    <a href="#"><li id="sublinkea">3rd level item1</li></a>
    <a href="#"><li id="sublinkeb">3rd level item2</li></a>
    <a href="#"><li id="sublinkea">3rd level item3</li></a>
    <a href="#"><li id="sublinkeb">3rd level item4</li></a>                    
  </div>
  
  <a href="#"><li id="NSSL2">[Normal Link]</li></a>
</div>

Answer №1

It seems like the issue lies in having #extrabox nested within #togglebox as a child when it should be a sibling. This arrangement causes #extrabox to impact the positioning of any block-level elements that follow it under #togglebox. To resolve this, consider the following adjustment:

<div id="togglebox">
  <ul>
    <li id="NSSL1">
      <a href="#">[Normal Link]</a>
    </li>
       // Updated for better element structure
    <li id="SSL2">
      <a href="#" onclick="toggle_visibility('extrabox');">
        [Has extra Level]
      </a>
    </li>
  </ul>
</div>
// Revised placement to address display issues
<div id="extrabox">
  <!-- place #extrabox contents here -->
</div>

(Additionally, I have corrected the nesting of the a tags within the ul; only li tags are valid children of ul.)

Similarly, ensure that #extrabox2 is moved outside of #extrabox to prevent disturbance to its sibling elements.

If you could provide clarification on your statement "Also I would like to make it where only one link can be selected," I would be glad to assist further.

I hope this information proves helpful!

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

Is there a way to duplicate and insert a function in node.js if I only have its name?

I'm currently working on a code generation project and I've encountered a problem that I initially thought would be easy to solve. However, it seems to be more complicated than I anticipated. My task involves taking a method name as input, naviga ...

Guide to generating an HTML table with database information employing jquery and ajax

I am faced with the challenge of creating a table using information retrieved from a database. Despite being able to view all the data through console.log, I am struggling to convert that into a table format. My latest version now displays at least one op ...

Tips for refreshing the default style of Material UI select

I'm having trouble customizing the default background color of the first menuItem in the select component. The class I need is not visible when inspecting the element, as the background color disappears upon inspection. Steps to reproduce: 1. Click ...

When using the npm command, errors may occur that are directly related to the lifecycle and initialization

Currently, I am delving into the world of OpenLayers and JavaScript. I came across a helpful tutorial that provides step-by-step guidance on creating a simple OpenLayers project using JavaScript. I followed the instructions diligently but encountered an er ...

What is the best way to create a backup copy of my project using git?

To ensure the safety of my project, I took the necessary steps to back it up. First, I initialized a repository using git init Following that, I committed all files by executing git add . git commit -am "first commit" Now, the next step involves pushin ...

MongoDB table collections (table names in other databases)

After setting up my express server to connect to mongodb, I encountered an issue despite everything working fine initially. I created a collection in my mongodb called projects (plural form). In my project.model.js file, I defined the model as follows: c ...

An error was thrown at line 474 in module.js

After recently installing nodejs on my laptop, I'm struggling to run a js file in the node environment. I attempted using this command: node C:\Program Files\nodejs\file.js, but encountered the following error: module.js:474 thr ...

When first accessing the page, the map may not load properly. However, a simple refresh of the page in VueJS should resolve this issue and allow the

After initially loading the page, the map may not work properly in Vue.js. However, refreshing the page fixes this issue. Can anyone provide assistance with this problem? Here is the relevant code: mounted() { this.geolocate(); }, methods: { ...

Detecting errors on the client side with JSON payload in Next.js and a personalized server

Working with Next.js and a custom Express server, I've encountered an issue regarding basic API error handling. I have set up a simple error handling middleware that looks like this: app.use((err, req, res) => { res.status(400).send(message); ...

muiSlider limited to specific range

I am currently using the Mui Slider component for a user interface where I need to restrict its value within a certain range. For example, I want the slider's handle to become unmovable after reaching 50. Users can still select values up to 50, but th ...

Send the selected option from the dropdown menu to a different page

I am in the process of designing a unique shopping cart system where, upon clicking on the "add to cart" link, both the selected quantity from the drop-down menu and the product ID are transmitted to the addCart page. While I have successfully managed to p ...

"Shopping just got easier with our new drag and drop feature! Simply drag items

I want to develop a Virtual Shopping Cart system. Items will be retrieved from a database. A virtual basket will be available. Users can drag items and drop them into the basket, similar to shopping in a mall. Once the user clicks the save button, the s ...

Tips for displaying a loading spinner during the rendering of a backbone view

I'm looking for some assistance in rendering a Backbone view that contains a large amount of information. Ideally, I would like to incorporate an animation (spinner) while the information is being rendered. Can anyone offer guidance or help with this ...

An unusual type of data is being stored in a MySQL database through Navicat Premium while using Django

Recently, I've encountered an issue while trying to insert data from an HTML form into my database. Strangely, upon submission, the values for "gender" and "website rating" get replaced with "on" instead of the actual input provided through the websit ...

Is there a way to adjust the speed of the transitions between animations?

I've been experimenting with ways to increase the time between animations in my cycle. Adjusting the duration of the keyframes animation hasn't yielded the desired effect. span { animation: rotateWordsFirst 15s linear infinite 0s; ...

jQuery Algorithm for calculating totals

Here is an algorithm for formatting amounts using jQuery: Visit jsfiddle for the code However, there are some issues. For instance, if I enter 900.800,00 and then delete the "9", it still displays 00.800,00. How can this be resolved? I have fixed severa ...

What is the best way to achieve a never-ending vertically scrolling image using CSS?

I want to incorporate a vertically scrolling image similar to the one on Adam Whitcroft's amazing landing page. I have tried examining his source code, but I am unable to grasp how he achieved it. The concept is to have the "I'm a scientist" text ...

Uploader and viewer tool for HTML5 documents

My website is currently built using PHP and allows users to add and view documents. The current upload process is basic, requiring users to manually input information and then view the document with minimal formatting on a webpage. I am looking to upgrade ...

Is there a way to disable text selection in AngularJS when double-clicking using ng-dblclick?

My element has ng-dblclick='doSomthing()' functionality that is functioning correctly, however, it also selects the text in the element which is not visually appealing. Is there a way to avoid this issue? ...

Execute React program within VM Azure

After setting up my React application on Azure's virtual machine, I encountered an issue. When trying to access the public URL (DNS) of the VM, I received a "site can't be reached" message. This is the process I followed to launch my project on ...