JSFiddle - React, Tailwind, and code Playground

by mattography

HTML

<li tabindex="0" class="has-children" id="ocomproduct-cloudapplication" aria-expanded="false" role="treeitem" aria-checked="false">
  <label for="ocomproduct-Cloud-Applications">
    <span>Cloud Applications</span>
    <input type="checkbox" tabindex="-1" class="parent-filter-checkbox" id="ocomproduct-Cloud-Applications">
  </label>
  <div class="chevron-right"></div>
</li>

<ul role="group" aria-labelledby="ocomproduct-cloudapplicationssaas" class="subfilter-list collapsed">
  <li tabindex="0" class="subfilter" role="treeitem" aria-checked="false">
    <label>
      <span>Enterprise AI</span>
      <input type="checkbox" class="sub-filter-checkbox" id="ocomproduct-Enterprise-AI" aria-label="ocomproduct-Enterprise-AI">
      </label>
  </li>
  <li tabindex="0" class="subfilter" role="treeitem" aria-checked="false">
    <label>
      <span>Enterprise database</span>
      <input type="checkbox" class="filter-checkbox" id="ocomproduct-Enterprise-Database" aria-label="ocomproduct-Enterprise-Database">
      </label>
  </li>
</ul>


<li tabindex="0" class="has-children" id="ocomproduct-cloud" aria-expanded="false" role="treeitem" aria-checked="false">
  <label for="ocomproduct-Cloud">
    <span>Cloud</span>
    <input type="checkbox" tabindex="-1" class="parent-filter-checkbox" id="ocomproduct-Cloud">
  </label>
  <div class="chevron-right"></div>
</li>

<ul role="group" aria-labelledby="ocomproduct-artificial-intelligence" class="subfilter-list collapsed">
  <li tabindex="0" class="subfilter" role="treeitem" aria-checked="false">
    <label>
      <span>Machine Learning</span>
      <input type="checkbox" class="sub-filter-checkbox" id="ocomproduct-Machine-Learning" aria-label="ocomproduct-Machine-Learning">
      </label>
  </li>
  <li tabindex="0" class="subfilter" role="treeitem" aria-checked="false">
    <label>
      <span>Enterprise Planning & Sourcing</span>
      <input type="checkbox" class="filter-checkbox" id="ocomproduct-Enterprise-Planning-&-Sourcing"...

JavaScript

document.addEventListener('DOMContentLoaded', function() {
  const hasChildrenItems = document.querySelectorAll('.has-children');

  function updateQueryParameters(remainingChecked) {
    const url = new URL(window.location.href);
    url.searchParams.set('remainingChecked', remainingChecked.join(','));
    history.replaceState(null, '', url.toString());
  }

  function restoreStateFromQueryParameters() {
    const urlParams = new URLSearchParams(window.location.search);
    const remainingChecked = urlParams.get('remainingChecked');
    
    if (remainingChecked) {
      const remainingCheckedArray = remainingChecked.split(',');
      remainingCheckedArray.forEach(function(id) {
        const checkbox = document.getElementById(id);
        if (checkbox) {
          checkbox.checked = true;
          // Ensure the parent `has-children` checkbox is checked if any subfilter is checked
          const hasChildrenItem = checkbox.closest('.has-children');
          if (hasChildrenItem) {
            const hasChildrenCheckbox = hasChildrenItem.querySelector('input[type="checkbox"]');
            hasChildrenCheckbox.checked = true;
          }
        }
      });
    }
  }

  restoreStateFromQueryParameters();

  hasChildrenItems.forEach(function(hasChildrenItem) {
    const hasChildrenCheckbox = hasChildrenItem.querySelector('input[type="checkbox"]');
    const subfilterList = hasChildrenItem.nextElementSibling;
    if (!subfilterList) return; // Skip if there is no subfilter list
    const subfilterCheckboxes = subfilterList.querySelectorAll('.subfilter input[type="checkbox"]');
    
    hasChildrenCheckbox.addEventListener('change', function() {
      subfilterCheckboxes.forEach(function(checkbox) {
        checkbox.checked = hasChildrenCheckbox.checked;
      });

      // Update the URL with the remaining checked checkboxes
      const remainingChecked = Array.from(document.querySelectorAll('.subfilter input[type="checkbox"]:checked'))
       ...