Solution 1 :

How about this? I’ve taken the liberty of removing the elements to focus on the features you’ve mentioned. I added event handlers on the category entries, and on the section entries and a tiny bit of CSS to support visibility toggling.

  .cat, .sec { cursor: pointer; }
  .sec, .subsec { display: none; }
  ul.catIsVis .sec { display: block; }
  .subsec.subsecIsVis { display: block; }


 <ul id="categories"><!-- Top-level list that contains all category sub-lists -->
    <ul><!-- Initial category and its sections -->
      <li class="cat" catid="360002246652">Category 1 (Toggle)</li>
      <li class="sec" secid="360007912231" categoryid="360002246652" parentsecid="null">Section1</li>
      <li class="sec" secid="360007910471" categoryid="360002246652" parentsecid="null">Section2</li>
      <li class="sec" secid="360007106191" categoryid="360002246652" parentsecid="null">Section3</li>
      <li class="sec" secid="360007106171" categoryid="360002246652" parentsecid="null">Section4</li>
    <ul><!-- Second category and its sections / subsections -->
      <li class="cat"    catid="360002254991">Category 2</li>
      <li class="sec"    secid="360007012012" categoryid="360002254991" parentsecid="null" style="">Section 1</li>
      <li class="subsec" secid="360007060252" categoryid="360002254991" parentsecid="360007012012" style="">SubSectionA</li>
      <li class="subsec" secid="360007106751" categoryid="360002254991" parentsecid="360007012012" style="">SubSectionB</li>
      <li class="subsec" secid="360008585272" categoryid="360002254991" parentsecid="360007012012" style="">SubSectionC</li>
      <li class="sec"    secid="360007012692" categoryid="360002254991" parentsecid="null" style="">Section2</li>
      <li class="sec"    secid="360007012712" categoryid="360002254991" parentsecid="null" style="">Section3</li>


 $('.cat').on('click', function () {

 $('.sec').on('click', function () {
    const $thissec = $(this);
    const secid = $thissec.attr('secid');
    console.log(`sec secid is ${$thissec.attr('secid')}`)
    $.each($thissec.parent().find('.subsec'), function (anindex, asubsec) {
      const parentsecid = $(asubsec).attr('parentsecid');
      console.log(`subsec subsecid is ${parentsecid}`);
      if (secid == parentsecid) {

Problem :

I am building a 3-tiered hierarchical menu (Categories/Sections/SubSections) that is constructed as a bunch of list items in a single unordered list. I have some of the toggling functionality already in place, but I now need to be able to use the onClick method so that if a particular Section has children (SubSections), clicking on that Section will show/hide its children (SubSections). More specifically — whenever a list item with the class of ‘sec’ immediately proceeds one or more list items with the class of ‘subsec’, I want that ‘sec’ list item to serve as a toggle for the adjacent ‘subsec’ list items. The screen shot below should help to illustrate the architecture of the list and the behavior I am looking to implement:

Menu List Items

The challenge here is that there will be more than one set of SubSections in the menu, so the code that drives this thing has to be ‘generic’ enough to handle multiple instances, but have a tight enough scope so that a given section (‘sec’ list item) can only toggle the immediately adjacent subsections (‘subsec’ list items).

In summary: Whenever a Section list item (has the ‘sec’ class) immediately proceeds one or more SubSection list items (has the ‘subsec’ class), the initial Section list item should serve as a trigger that toggles the Subsection list item(s) that immediately follow it. But that particular instance of toggling behavior should stop as soon as the list presents the next Section (has the ‘sec’ class) list item.

I hope my explanation was sufficiently clear. Thanks in advance for your help.

Here is some sample (and sanitized) HTML Code taken from the actual menu:

<ul id="categories"><-- Top-level list that contains all category sub-lists -->

<ul><-- Initial category and its sections -->
<li class="cat" catid="360002246652"><a>Category 1 (Toggle)</a></li>

<li class="sec" secid="360007912231" categoryid="360002246652" parentsecid="null" style="display: none;"><a href="https://MyURL/sections/360007912231">Section1</a></li>

<li class="sec" secid="360007910471" categoryid="360002246652" parentsecid="null" style="display: none;"><a href="https://MyURL/sections/360007910471">Section2</a></li>

<li class="sec" secid="360007106191" categoryid="360002246652" parentsecid="null" style="display: none;"><a href="https://MyURL/sections/36000710619">Section3</a></li>

<li class="sec" secid="360007106171" categoryid="360002246652" parentsecid="null" style="display: none;"><a href="https://MyURL/sections/360007106171">Section4</a></li>

<ul><-- Second category and its sections / subsections -->
<li class="cat" catid="360002254991"><a>Category 2 (Toggle)</a></li>

<li class="sec" secid="360007012012" categoryid="360002254991" parentsecid="null" style=""><a href="https://MyURL/sections/360007012012">Section 1</a></li>

<li class="subsec" secid="360007060252" categoryid="360002254991" parentsecid="360007012012" style=""><a href="https://MyURL/sections/360007060252">SubSectionA</a></li>

<li class="subsec" secid="360007106751" categoryid="360002254991" parentsecid="360007012012" style=""><a href="https://MyURL/sections/360007106751">SubSectionB</a></li>

<li class="subsec" secid="360008585272" categoryid="360002254991" parentsecid="360007012012" style=""><a href="https://MyURL/sections/360008585272">SubSectionC</a></li>

<li class="sec" secid="360007012692" categoryid="360002254991" parentsecid="null" style=""><a href="https://MyURL/360007012692">Section2</a></li>

<li class="sec" secid="360007012712" categoryid="360002254991" parentsecid="null" style=""><a href="https://MyURL/sections/360007012712">Section3</a></li>



Comment posted by Marconi

Thanks for the feedback Yshmeray. Yes — I did think that perhaps the HTML should reflect the logical structure (and that a separate UL should be used for each grouping), but I figured that the different class assignments took care of the logical structure and allowed me to avoid having to add complexity to the initial AJAX call that pulls the list data and dumps it to HTML. My sense (and maybe I am mistaken) is that things could work with the current construction, but I am not all that experienced with jQuery / JavaScript, so I am struggling a bit to write the code to execute the behavior.

Comment posted by Marconi

Hi again Yishmeray, and thanks for the response. I actually just went in to the AJAX code that initially pulls the data and I have now managed to wrap each top-level list item (class of ‘cat’) within its own set of

    tags. This probably won’t help much with what I am trying to accomplish regarding the Sections and SubSections, but it does help to create an HTML listing that more closely matches the logical structure of the menu. I am of course open to additional suggestions or specific code solutions if you are able to provide them. Thanks.

    Comment posted by Marconi

    Yshmeray. Thanks again very much for your time and effort. This looks good. Over the next few days, I will explore in more detail what you have provided and see how it works for me.