Guide to creating a nested list using the jQuery :header selector

Here is the structure of my html:

<h1 id="header1">H1</h1>
  <p>Lorem ipsum</p>
    <h2 id="header2">H2</h2>
      <p>lorem ipsum</p>
    <h2 id="header3">H2</h2>
      <p>lorem upsum</p>
       <h3 id="subHeader1">H3</h3>
       <p>Lorem Ipsum</p>

To retrieve all headings with an ID, I am using this jQuery selector:

var headings = $( ":header[id]" );

My goal is to create a nested list of all these headings in this format:

<ul><li>H1
     <ul><li>H2<li>
         <li>H2
           <ul><li>H3</li></ul>
         </li>
      </ul>
 </li></ul>

I have been struggling to achieve this and couldn't find a solution on Stack Overflow. While I can create a flat list, building a nested one has proven to be more challenging.

If anyone could offer assistance or guidance, I would greatly appreciate it. Thank you!

Answer №1

Mastering this technique requires a combination of algorithmic knowledge and familiarity with jQuery. It's not as simple as just implementing an algorithm; understanding how to use jQuery properly is crucial in coding it effectively.

The approach involves initializing a root ul, storing references to child headers within each ul, then iterating through this collection to convert each header into a nested ul. These newly created ul elements are added to a stack-like structure, which is processed in a while loop until the stack is empty.

Explaining this process can be challenging, especially for beginners new to algorithms and jQuery. Below is the code snippet demonstrating this technique:

// Initialize the root UL
var ul = $('<ul>');
for(var i = 1; i < 8; i++){
  var hs = $('h' + i);
  if(hs.length){
    ul[0].childHeaders = hs
    ul[0].childHeaderLevel = i;
    break;
  }
}

var rootUl = ul;

// Main loop
while(ul.length){    
  var nextUl = $();
  
  // Loop through each ul
  ul.each(function(){
     var innerUl = this;
     var n = this.childHeaderLevel;
     
     // Convert each childHeader into a ul
     innerUl.childHeaders.each(function(i,elem){
        var childUl = $('<ul>').append('<li>' + $(elem).html() + '</li>')
                               .appendTo(innerUl);
                               
        childUl[0].childHeaders = $(this).nextUntil('h' + n)
                                         .filter('h' + (n+1));
        childUl[0].childHeaderLevel = n + 1;            
        nextUl = nextUl.add(childUl);
     });                            
  });
  
  ul = nextUl;   
}

// Append the root UL to the body after emptying it
$('body').empty().append(rootUl);

See Demo Here.

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

Discovering the maximum font size that can be displayed on a single line in CSS

I am working with a wrapper div tag that has the capability of adjusting its dimensions. <div class="wrapper"> <p class="inside-text">Some text</p> </div> How can I use CSS to set the font-size of inside-text to be as large as ...

What could be causing the function to not execute before the rest of the code in the React App?

My lack of expertise may be the reason, but I'm unsure how to address this issue: Here's what I have: A button labeled "Check numbers" <Button fullWidth variant="contained" onClick={this.checkOptOut ...

Creating a Reddit-inspired voting system using Laravel 5.3 and VueJS

Currently in the process of learning Vuejs (not too experienced with Laravel), and my goal is to create a basic voting system for various tasks. I've succeeded in adding, editing, and deleting tasks. However, upon implementing the upvote/downvote feat ...

How come the function is being triggered by my onclick button as soon as the page loads?

Currently, I am experiencing a challenge in my NodeJS project with Express. The issue lies with my EJS client side file when it comes to handling button click events. In my EJS file, I have imported a function from a JS file and can invoke it using <% ...

What are the steps to sending HTML emails from the default mail client on Mac and PC operating systems?

Currently, I am in the process of creating a website that allows clients to easily send an email with the content they are viewing. I want users to click on a button which will open their default mail client (compatible with both Mac and PC) and automatica ...

The automated test locator in Angular using Protractor is failing to function

I am facing a challenge with my angular web application as there are some elements that are difficult to interact with. One specific element is a checkbox that needs to be checked during testing: ` <div class="row form-group approval_label"> < ...

Creating an adjustable fixed footer using Bootstrap 3

Struggling with the application of bootstrap styling. I have a footer with columns set as col-md-3, 3, 2, 4 which sums up to a total of 12. The issue lies in the differing content within each column. My goal is to achieve equal spacing between each div in ...

Exploring geometric materials within the THREE.js framework

I'm currently working on creating a geometry in THREE.js: var dotGeometry = new THREE.Geometry(); dotGeometry.dynamic = true; var createDot = function (group, x, y, z){ group.vertices.push(new THREE.Vector3( x, y, z)); } var width = 300; var he ...

What is the correct way to accurately determine the width of a block being displayed with the flex-direction:column property?

For instance: HTML console.log($('.container').width()); // 600px as we defined in css. console.log($('.list').width()); // 600px console.log($('.box').eq('-1').position().left + $('.box').outerWidth( ...

Angular 5 mobile row aligns vertically, not inline with Bootstrap

Is there a way to make the row inline when the width is less than 579px? I want it to look the same on both mobile and desktop. "styles": [ "../node_modules/font-awesome/scss/font-awesome.scss", "../node_modules/angular-bootstrap-md/scss/bootstra ...

What is the best way to place two stacked buttons side by side in an inline format?

I am trying to rearrange the layout of a bootstrap modal that includes two multiple select elements and two buttons. My goal is to have all controls inline, with the buttons stacked on top of each other. Here's an example of what I'm aiming for: ...

Using innerHTML within a JS function causes the class to malfunction

I want to embed HTML code using innerHTML, which will add an input with the class .flatpickr-date. let newInput = '<input type="text" class="flatpickr-date">' document.getElementById('id').innerHTML = newInput; In my JavaScript ...

Running repetitive tasks in PHP using setInterval function

I've been working on adding a "friend request" feature to my website and I really want the requests to show up instantly without having to reload the page. After doing some research, it seems like using setInterval with Ajax is the way to go. I found ...

Passing parameters between various components in a React application

Is it possible to pass a parameter or variable to a different component in React with react-router 3.0.0? For example, if a button is clicked and its onClick function redirects to another component where the variable should be instantly loaded to display a ...

Firebase web authentication is most effective upon the second attempt

I am currently working on a website that interacts with Google's firebase to read and write data. The website has both anonymous and email authentication enabled. Users can view the data anonymously, but in order to edit or write new data, they must s ...

The async waterfall is encountering a Typeerror due to the nextcallback function not being defined properly

async.waterfall([1,2,3,4].map(function (arrayItem) { return function (lastItemResult, nextCallback) { // performing the same operation for each item in the array var itemResult = (arrayItem+lastItemResult); // pa ...

Ways to change the default blue dropdown color in the Chrome browser

When you click on the drop-down menu, a blue color appears when hovered over. I want it to be red instead, but for some reason, it's not working in Chrome browser. Here is the CSS class that I have used: option:checked { box-shadow: 0 0 10px 100p ...

Storing the state of web applications in AJAX applications

How can the application state be maintained across requests for thick JavaScript clients? In addition to client managed cookies and descriptive URLs, are there any other methods? Please note that by clients I am referring to thick JavaScript clients. The ...

When the user clicks, display one div and conceal the others

https://codepen.io/leiacarts/pen/PoqRxNZ I need assistance with two specific tasks related to my website layout. Firstly, I am struggling to ensure that images displayed in the red sections remain constrained and automatically resize within the content di ...

Error: The function pajinate is not defined for jQuery([...])

I'm currently experiencing difficulties with the jQuery Pajinate plugin after migrating to a new host. The script was functioning properly on my previous hosting platform, but now I seem to be encountering some problems. Below is the code snippet: ...