Search code examples
jquerytreeviewloadexpand

How to expand treeview for specific node on page load


I have a treeview that expands correctly manually. But I need it to partially expand on page load. Which part expands will be determined by the ID in the url. In my jsfiddle I have added id="xyz" to one of the nested sections to simulate this action. So when the page loads, the entire part of the tree above and including that element should expand, but it doesn't. Would someone please take a look?

    <style>
    ul, #myUL {
      list-style-type: none;
    }

    #myUL {
      margin: 0;
      padding: 0;
    }

    .box {
      cursor: pointer;
      -webkit-user-select: none; /* Safari 3.1+ */
      -moz-user-select: none; /* Firefox 2+ */
      -ms-user-select: none; /* IE 10+ */
      user-select: none;
    }

    .box::before {
      content: "\2610";
      color: black;
      display: inline-block;
      margin-right: 6px;
    }

    .check-box::before {
      content: "\2611"; 
      color: dodgerblue;
    }

    .nested {
      display: none;
    }

    .active {
      display: block;
    }
    </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <li><span class="caret">Beverages</span>
      <ul class="nested">
        <li>Water</li>
        <li>Coffee</li>
        <li><span class="caret">Tea</span>
          <ul class="nested">
            <li>Black Tea</li>
            <li>White Tea</li>
            <li><span class="caret" id="xyz">Green Tea</span>
              <ul class="nested">
                <li>Sencha</li>
                <li>Gyokuro</li>
                <li>Matcha</li>
                <li>Pi Lo Chun</li>
              </ul>
            </li>
          </ul>
        </li>  
      </ul>
    </li>
    <li><span class="caret">Food</span>
      <ul class="nested">
        <li>Water</li>
        <li>Coffee</li>
        <li><span class="caret">Tea</span>
          <ul class="nested">
            <li>Black Tea</li>
            <li>White Tea</li>
            <li><span class="caret">Green Tea</span>
              <ul class="nested">
                <li>Sencha</li>
                <li>Gyokuro</li>
                <li>Matcha</li>
                <li>Pi Lo Chun</li>
              </ul>
            </li>
          </ul>
        </li>  
      </ul>
    </li>

    <script>
     let $carets = $('.caret').on('click', e => {
        let $caret = $(e.target);
        
        // display the clicked item
        $caret.toggleClass('caret-down');
        $caret.closest('li').children('.nested').toggleClass('active');
        
      });
      
      $("#xyz").addClass('caret-down');
      let $parentCarets = $("#xyx").parents('li').children('.caret'); 
      $("#xyx").not($parentCarets).addClass('caret-down').closest('li').find('.nested').addClass('active');
     </script>

Solution

  • You can first get the closest li near span tag using .closest() then use .find() to get all ul but not the one after the span tag and then add some class to other uls i.e : unselect just to help in hiding that ul .

    Then , you can get outer li tag and use :not to select all ul which don't have the unselect class and add active class to those uls only .

    Demo Code :

    let $carets = $('.caret').on('click', e => {
      let $caret = $(e.target);
    
      // display the clicked item
      $caret.toggleClass('caret-down');
      $caret.closest('li').children('.nested').toggleClass('active');
    
    });
    
    $("#xyz").addClass('caret-down bg');
    //get closest li -> not first ul add some class to other
    $("#xyz").closest('li').find('ul.nested:not(:first)').addClass("unselect")
    //get closest li-> find ul ->show that
    $("#xyz").closest('li.outer').find("ul:not(.unselect)").toggleClass('active');
    ul,
    #myUL {
      list-style-type: none;
    }
    
    #myUL {
      margin: 0;
      padding: 0;
    }
    
    .box {
      cursor: pointer;
      -webkit-user-select: none;
      /* Safari 3.1+ */
      -moz-user-select: none;
      /* Firefox 2+ */
      -ms-user-select: none;
      /* IE 10+ */
      user-select: none;
    }
    
    .box::before {
      content: "\2610";
      color: black;
      display: inline-block;
      margin-right: 6px;
    }
    
    .check-box::before {
      content: "\2611";
      color: dodgerblue;
    }
    
    .nested {
      display: none;
    }
    
    .active {
      display: block;
    }
    
    .bg {
      background: red;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <ul>
      <!-- added this outer class -->
      <li class="outer"><span class="caret">Beverages</span>
        <ul class="nested">
          <li>Water</li>
          <li>Coffee</li>
          <li><span class="caret">Tea</span>
            <ul class="nested">
              <li>Black Tea</li>
              <li>White Tea</li>
              <li><span class="caret" id="xyz">Green Tea</span>
                <ul class="nested">
                  <li>Sencha</li>
                  <li>Gyokuro</li>
                  <li>Matcha</li>
                  <li>Pi Lo Chun</li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li class="outer"><span class="caret">Food</span>
        <ul class="nested">
          <li>Water</li>
          <li>Coffee</li>
          <li><span class="caret">Tea</span>
            <ul class="nested">
              <li>Black Tea</li>
              <li>White Tea</li>
              <li><span class="caret">Green Tea</span>
                <ul class="nested">
                  <li>Sencha</li>
                  <li>Gyokuro</li>
                  <li>Matcha</li>
                  <li>Pi Lo Chun</li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>