Search code examples
javascripthtmljquerysidebar

Building sidenav menu based on html structure


I am trying to build a documentation template for my Django project with some easy navigation. The general structure of the HTML is this:

div.page-container#overview
   h3.page-header
   div
      h4.section-title
      div.section-wrapper
          h5.section-subtitle

div.page-container#documentation
   h3.page-header
   div
      h4.section-title
      div.section-wrapper
          h5.section-subtitle

...

Based on the HTML that is generated, I want a side nav that has the same structure of the headers on the page. So this is what I want:

HTML
-----------------
div.page-container#overview
   h3.page-header="Overview" -----------------|
   div                                        |
      h4.section-title="Introduction" --------|
      div.section-wrapper                     |
          h5.section-subtitle="System" -------|
             <p>....</p>                      |
          h5.section-subtitle="User" ---------|
             <p>....</p>                      |
                                              |
SideBar                                       |
-----------------                             |
Overview         <----------------------------|
  Introduction   <----------------------------|
    System    <-------------------------------|
    User   <----------------------------------|
Documentation                                 |
  ...
    ...

I am trying to loop over the html using JQuery but I am having trouble getting the navigation structure correct.

Here is what I have:

function buildSideNav() {
    $('.page-container').each(function() {
        var container = $(this);
        $(container).find('.page-header').each(function() {
            $('#sidebar-tree').append(`<a href="#${$(this).attr('id')}">${$(this).text()}</a>`);

            $(container).find('.section-title').each(function() {
                $('#sidebar-tree').append(`<a class="ml-2" href="#${$(this).attr('id')}">${$(this).text()}</a>`);

                $(container).find('.section-subtitle').each(function() {
                    $('#sidebar-tree').append(`<a class="ml-4" href="#${$(this).attr('id')}">${$(this).text()}</a>`);
                });
            });
        });
    })
}

I am certain my JQuery is wrong but I cant seem to get it to work properly. Any help would be appreciated.


Solution

  • You need to put values inside <li> tags to generate that structure . Currently , in your code you just have one page-header & section-title so you don't need to use loop there just use it for section subtitle . Then, whenever you append new element put them inside li tags.

    Demo Code :

    var htmls = ""; //declare this
    $('.page-container').each(function() {
      var container = $(this);
      //get page-header and put inside ul > `li`
      htmls += `<ul><li><a href="#${$(container).find('.page-header').attr('id')}">${ $(container).find('.page-header').text()}</a><ul>`
      //get section-title put inside li > ul > li
      htmls += `<li><a class="ml-2" href="#${ $(container).find('.section-title').attr('id')}">${  $(container).find('.section-title').text()}</a><ul>`
      //loop through subtitle and put inside ul > li > ul > li > ul > li
      $(container).find('.section-subtitle').each(function() {
        htmls += `<li><a class="ml-4" href="#${$(this).attr('id')}">${$(this).text()}</a></li>`
      });
      //close all tags
      htmls += `</ul></li></ul></li></ul>`
    })
    $('#sidebar-tree').html(htmls) //add inside sidebarss.
    .page-container {
      display: none
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="page-container">
      <h3 class="page-header">Overview</h3>
      <div>
        <h4 class="section-title">Introduction</h4>
        <div class="section-wrapper">
          <h4 class="section-subtitle">System</h4>
          <h4 class="section-subtitle">User</h4>
        </div>
      </div>
    
    </div>
    <div class="page-container">
      <h3 class="page-header">Documentation</h3>
      <div>
        <h4 class="section-title">Sss</h4>
        <div class="section-wrapper">
          <h4 class="section-subtitle">Soemthings</h4>
          <h4 class="section-subtitle">Soemthingsd1</h4>
        </div>
      </div>
    </div>
    <div id="sidebar-tree">
    </div>