Click here to Skip to main content
15,883,623 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
I have a file TOC.HTML. I am adding it to index.html and other html pages.
The TOC has links to other html pages. The toc has collapse and hide functionality for subtopics and highlight on. Now when I navigate to other pages. That has TOC in iframe the TOC state must persist. What was clicked before must be highlighted and showed other collapsed.

What I have tried:

HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
    .toc-item {
        margin-left: 5px;
        padding: 10px;
        font-family: Georgia;
    
        font-size: 8px;
      }      
      
      #toc {
       
        padding: 2px;
        grid-column: 1;
        height: 800px;
        width:max-content;
        overflow: auto;        
      }
      .toc-link i {
        margin-left: 5px;
        transition: transform 0.3s;
      }
      
      .toc-anchor {
      text-decoration: none !important; 
      color:black;
      }
      .collapse {
        display: none;
        margin-left: 5px;
      }
      
      .show {
        display: block;
      }
      
      .subtopic li {
        list-style-type: none; /* Remove bullet points from <li> elements */
        margin-left: -40px; /* Add some padding to the left of the list */
        font-size: 12px;
        text-decoration: none;
        padding-top: 5px;
      }
      .toctree-l1{
        text-decoration: none;

      }
      .toc-item {
        margin-bottom: 5px;
        font-family: Georgia;
        font-size: 14px;
        text-decoration: none;        
      }
      
      .toc-link {
        text-decoration: none;
        color: #000;
        display: block;
        margin-bottom: 3px;
      }
      
      .toc-link:hover {
        color: #3498db;
      }
      /*.chevron {
      cursor: pointer;
      }*/
      .subtopic
      {
      text-decoration: none;
      color: #000;
        display: block;
        
      }
      .title
      {
        padding-bottom: 5px;
      }

      .toc-link a.active {
    color: #3498db;
    font-weight: bold;
  }
     /* .fa-chevron-down {
      transition: transform 0.2s;
      }*/
      
      .btn[aria-expanded="true"] .fa-chevron-down {
      transform: rotate(180deg);
      }
      
      .chevron-icon {
        display: inline-block;
        vertical-align: middle; /* Optional: Align the icon 
                                   vertically with the text */
        margin-left: 5px; /* Optional: Add some space between 
                             the text and the icon */
      }
      a {
    text-decoration: none;
    color: #000; /* Set the link color to your preferred color */
    }

         /* Add styles for hyperlink hover state if needed */
     a:hover {
    color: #3498db; /* Set the link color on hover 
                       to your preferred color */
     }
     </style>
</head>
<body>
    <nav class="nav-sidebartoc">

<div id="toc">        

<div class="toc-item">
  <div class="toc-link tlink">
      <a href="#product2"style="display: inline;">
             SSL Orchestrator Management</a>
      
  </div>
  <div class="collapse">
      <div class="toc-item">
          <div class="toc-link tlink">
              <a id="title" href="#href" style="display: 
              inline;">SSL Orchestrator Concepts</a>
              
          </div>
          <div class="collapse">
              <ul class="subtopic">
                <li class="toctree-l1">
                <a class="reference internal" 
                target="_top" onclick="tocLinkClicked(this)" href="sslo_management/sslo_overview.html">
Overview: SSL Orchestrator Concepts</a></li>
              <li class="toctree-l1">
              <a class="reference internal" target="_top" 
              href="sslo_management/sslo_terminologies.html">
              Overview: Terminologies and Conventions</a></li>
              <li class="toctree-l1">
              <a class="reference internal" target="_top" 
              href="sslo_management/sslo_how_to_use_bigip_next_api.html"
              >How to: Use the BIG-IP Next API</a></li>
              </ul>
          </div>
      </div>
      <div class="toc-item">
          <div class="toc-link tlink">
              <a id="title" href="#href" style="display: inline;">Inspection Services</a>
              
          </div>
          <div class="collapse">
              <ul class="subtopic">
                <li class="toctree-l1">
               <a class="reference internal" target="_top" 
               onclick="tocLinkClicked(this)" href="sslo_management/sslo_overview_inspection_services.html"
               >Overview: Inspection Services</a></li>
                <li class="toctree-l1">
               <a class="reference internal" target="_top" 
               onclick="tocLinkClicked(this)" 
               href="sslo_management/sslo_how_to_create_tap_service.html"
               >Create TAP Inspection Services</a></li>
                <li class="toctree-l1">
                <a class="reference internal" 
                target="_top" onclick="tocLinkClicked(this)" 
        href="sslo_management/sslo_how_to_create_icap_service.html"
        >Create ICAP Inspection Services</a></li>
                <li class="toctree-l1"><
                a class="reference internal" target="_top" 
                onclick="tocLinkClicked(this)" href="sslo_management/sslo_how_to_create_inline_l3_service.html"
>Create Inline L3 Inspection Services</a></li>
              </ul>
          </div>
      </div>
      <div class="toc-item">
        <div class="toc-link tlink">
            <a id="title" href="#href" style="display: inline;">Management</a>
            
        </div>
        <div class="collapse">
            <ul class="subtopic">
              <li class="toctree-l1">
             <a class="reference internal" target="_top" 
         href="sslo_management/sslo_how_to_manage_service_chain.html"
         >How To: Manage the SSL Orchestrator Service 
         Chain</a></li>
        <li class="toctree-l1"><a class="reference internal" target="_top" href="sslo_management/sslo_how_to_manage_high_availability.html"
>How To: Manage High Availability</a></li>
        <li class="toctree-l1">
<a class="reference internal" target="_top" href="sslo_management/sslo_how_to_manage_traffic_summary_logging.html"
>How To: Manage Traffic Summary Logging</a></li>
            </ul>
        </div>
    </div>
      
  </div>

</div>

</div>        
  
 <!-- insert content here -->
  
      </nav>
      <script> // Function to  show or collapse items 
        const tlinks = document.querySelectorAll('.tlink');
        tlinks.forEach(tlink => {
            tlink.addEventListener('click', () => {
                const collapse = tlink.nextElementSibling;
                tlink.classList.toggle('expanded');
                collapse.classList.toggle('show');
            });
        });
    </script>
    
    <script>
        // Function to handle link clicks and highlight the active link
        function handleLinkClick(event) {
          const links = document.querySelectorAll('.toc-item .toc-link a');
          links.forEach(link => link.classList.remove('active'));
          event.target.classList.add('active');
        }
      
        // Attach click event listener to all links
        const links = document.querySelectorAll('.toc-item .toc-link a');
        links.forEach(link => link.addEventListener('click', handleLinkClick));
      </script>     
        
     <!-- <script>
        const chevrons = document.querySelectorAll('.chevron');
        chevrons.forEach(chevron => {
            chevron.addEventListener('click', () => {
                const collapse = chevron.nextElementSibling;
                chevron.classList.toggle('expanded');
                collapse.classList.toggle('show');
            });
        });
    </script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>-->    

    <script>

// Function to update the selected link in the TOC
function updateSelectedLink(selectedLink) {
  const tocFrame = document.getElementById('tocFrame');
  const tocLinks = tocFrame.contentDocument.querySelectorAll('.toc-link a');

  tocLinks.forEach(link => {
    if (link === selectedLink) {
      link.classList.add('active');
    } else {
      link.classList.remove('active');
    }
  });
}

// Function to update the collapsed/expanded state of TOC items
function updateTocState() {
  const tocFrame = document.getElementById('tocFrame');
  const tocItems = tocFrame.contentDocument.querySelectorAll('.toc-item');

  tocItems.forEach(item => {
    if (item.classList.contains('collapse')) {
      const isCollapsed = item.querySelector('.collapse').classList.contains('show');
      if (isCollapsed) {
        item.classList.add('collapse');
      } else {
        item.classList.remove('collapse');
      }
    }
  });
}

</script>
  <script src="_static/js/index.js"></script>
  <script src="_static/js/jquery.appear.js"></script>
  <script src="_static/js/printThis.js"></script>
  <script src="_static/js/bootstrap.min.js"></script>
  
  <script src="_static/js/clouddocs.js"></script>
  <script src="_static/js/CoveoJsSearch.Lazy.min.js"></script>
  <script type="text/javascript" 
  src="https://resources.digital-cloud-west.medallia.com/wdcwest/102748/onsite/embed.js"
    async></script>
  
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="_static/js/index.js"></script>
    <script src="_static/js/jquery.appear.js"></script>
    <script src="_static/js/printThis.js"></script>
    <script src="_static/js/bootstrap.min.js"></script>
    <script src="_static/js/clouddocs.js"></script>
    <script src="_static/js/CoveoJsSearch.Lazy.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/js/all.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
      
</body>
</html>
Posted
Updated 10-Aug-23 6:48am
v2

1 solution

If you want the state to persist between reloads, then you'll need to use the Web Storage API[^] to save your state as it changes, and reload it when the page loads.

For example, add a unique ID to each link and section toggle, and store the ID of the clicked link and the IDs of the expanded sections.
JavaScript
const stateKey = "TOC-State";

const state = { 
    selectedLink: null, 
    expandedLinks: [] 
};

function loadState() {
    const json = window.sessionStorage.getItem(stateKey);
    return json ? JSON.parse(json) : null;
}

function saveState() {
    window.sessionStorage.setItem(stateKey, JSON.stringify(state));
}

function setSelectedLink(linkId) {
    document.querySelectorAll(".tlink.active").forEach(l => l.classList.remove("active"));
    document.getElementById(linkId)?.classList.add("active");
}

function toggleLink(linkId, expand) {
    const tlink = document.getElementById(linkId);
    if (!tlink) { return; }
    
    tlink.classList.toggle("expanded", expand);
    tlink.nextElementSibling.classList.toggle("show", expand);
}

// Load the state when the page loads:
document.addEventListener("DOMContentLoaded", () => {
    const savedState = loadState();
    if (savedState) {
        state = savedState;
        if (state.selectedLink) { setSelectedLink(state.selectedLink); }
        if (state.expandedLinks) { state.expandedLinks.forEach(id => toggleLink(id, true)); }
    } else {
        state.selectedLink = document.querySelector(".reference.selected")?.id;
        state.expandedLinks = [...document.querySelectorAll(".tlink.expanded")].map(l => l.id);
    }
});

// Set the clicked reference link as active, and save the state:
document.addEventListener("click", ({ target }) => {
    if (target.tagName !== "A") { target = target.closest("a"); }
    if (!target || !target.classList.contains("reference")) { return; }

    setSelectedLink(target.id);
    state.selectedLink = target.id;
    saveState();
});

// Expand or collapse the section, and save the state:
document.addEventListener("click", ({ target }) => {
    if (target.tagName !== "DIV" || !target.classList.contains("tlink")) { target = target.closest("div.tlink"); }
    if (!target) { return; }
    
    const id = target.id;
    const index = state.expandedLinks.indexOf(id);
    if (target.classList.contains("expanded")) {
        if (index !== -1) { state.expandedLinks.splice(index, 1); }
        toggleLink(id, false);
    } else {
        if (index === -1) { state.expandedLinks.push(id); }
        toggleLink(id, true);
    }
});
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900