Expanding-Collapsable HTML List- ul - li - Javascript
Asked Answered
S

3

6

I am implementing a ul and li list, from json data and with expand/collapse function.

The problem is that when trying the expand/collapse, all the subitems are expanding together, but i want only the clicked one to be collapsed/expanded;

Here is my code :

<html>
   <head>
      <script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
      <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
      <style type="text/css">
         ul li ul {
         display: none;
         } 
         a {
         color: red;
         }
      </style>
      <title></title>
   </head>
   <body>
      <ul id="menu" class="list">
      </ul>
      <script type="text/javascript">
         $(window)
                 .load(
                         function() {
                             var JSON = {
                                 menu : [ {
                                     name : 'Title',
                                     link : '#',
                                     sub : [ {
                                         name : 'Enclosure1',
                                         link : '#',
                                         sub : null
                                     }, {
                                         name : 'Enclosure2',
                                         link : '#',
                                         sub : null
                                     }, {
                                         name : 'Enclosure3',
                                         link : '#',
                                         sub : null
                                     } ]
                                 },{
                                     name : 'Link',
                                     link : '#',
                                     sub : null
                                 },{
                                     name : 'Content',
                                     link : '#',
                                     sub : null
                                 },{
                                     name : 'Enclosures',
                                     link : '#',
                                     sub : [ {
                                         name : 'Enclosure1',
                                         link : '#',
                                         sub : null
                                     }, {
                                         name : 'Enclosure2',
                                         link : '#',
                                         sub : null
                                     }, {
                                         name : 'Enclosure3',
                                         link : '#',
                                         sub : null
                                     } ]
                                 }, {
                                     name : 'Authors',
                                     link : '#',
                                     sub : [ {
                                         name : 'Author1',
                                         link : '#',
                                         sub : null
                                     }, {
                                         name : 'Author2',
                                         link : '#',
                                         sub : null
                                     } ]
                                 },{
                                     name : 'Published At',
                                     link : '#',
                                     sub : null
                                 }, {
                                     name : 'Stream',
                                     link : '#',
                                     sub : [ {
                                         name : 'STR1',
                                         link : '#',
                                         sub : null
                                     }, {
                                         name : 'STR2',
                                         link : '#',
                                         sub : null
                                     } ]
                                 } ]
                             }

                             $(function() {

                                 function parseMenu(ul, menu) {
                                     for (var i = 0; i < menu.length; i++) {
                                         var li = $(ul).append(
                                                 '<li>'+ menu[i].name
                                                         + '</li>');
                                         if (menu[i].sub != null) {
                                             var subul = $('<ul class="list"></ul>');
                                             $(li).append(subul);
                                             parseMenu($(subul), menu[i].sub);
                                                 }
                                     }
                                 }

                                 var menu = $('#menu');
                                 parseMenu(menu, JSON.menu);
                             });
                         });//]]>​
      </script>
      <script type="text/javascript">$(document).on('click', '.list > li ', function () {
         $(this).parent().children('ul').toggle();
         })
      </script>
   </body>
</html>
Special answered 20/2, 2017 at 12:46 Comment(1)
related: #31509000Refer
H
3

In your script , change to toggle the "next" UL tag.

<script type="text/javascript">$(document).on('click', '.list > li ', function () {
    $(this).next('ul').toggle();
})</script>

http://codepen.io/anon/pen/xgoapR

And to start with submenu collapsed, change

ul li ul {
         display: none;
         } 

to

ul >  ul {
    display: none;
} 

EDIT: Check a full working example with collapse, animation, and +/- toggle in http://codepen.io/anon/pen/mWbLpm

Hagerty answered 20/2, 2017 at 13:0 Comment(12)
working fine ! but i want the list to be closed in default (not expanded in default)Special
I added a CSS fix to start with collapsed itemsHagerty
Great !! thank you, what about the sub-lists, how can i do to customize their fonts and size ?Special
Customize sub-lists Adding CSS rules for .list > ul > li or #menu > ul >liHagerty
Great ! and what about adding a slide down animation between lists and sublists ?Special
Simply add a "timer" parameter in toggle(), for example toggle(200).You can find more options in api.jquery.com/toggleHagerty
Great !! Thank you !! a final thing, is that i want to kind of indicate whether any of my members have a sublist or not (kind of a left shadow to tell whether this list is expandable (has children) or not) ? do you have any idea ?)Special
See codepen.io/anon/pen/VpZMbQ, line 128 for adding a class name to LI with sublist, and line 23 for adding a CSS class for .multi . You can use some special character (only text) in content propertyHagerty
Yes, but it works only on the first level, with sublist of sublists, it doesn't work !Special
Change #menu > .multi::after (only for fisrt level) for a more generic style ul > .multi::after. The example doesn't have multiple levels.Hagerty
Yapp it's working ! and if i want to change the character once i click on a member, how can i do ? (from a '+' to a '-')Special
Check in codepen.io/anon/pen/mWbLpm. Toggle a "opened" class in the click event, add $(this).toggleClass('multi-opened'); and create a css rule for ul > .multi-opened::after with content ' -'Hagerty
V
2

checkout this one, there is a small validation problem with your code, you can not have ul inside ul, but you can put it inside li.

var JSON = {
  menu: [{
    name: "Title",
    link: "#",
    sub: [{
      name: "Enclosure1",
      link: "#",
      sub: null
    }, {
      name: "Enclosure2",
      link: "#",
      sub: null
    }, {
      name: "Enclosure3",
      link: "#",
      sub: null
    }]
  }, {
    name: "Link",
    link: "#",
    sub: null
  }, {
    name: "Content",
    link: "#",
    sub: null
  }, {
    name: "Enclosures",
    link: "#",
    sub: [{
      name: "Enclosure1",
      link: "#",
      sub: null
    }, {
      name: "Enclosure2",
      link: "#",
      sub: null
    }, {
      name: "Enclosure3",
      link: "#",
      sub: null
    }]
  }, {
    name: "Authors",
    link: "#",
    sub: [{
      name: "Author1",
      link: "#",
      sub: null
    }, {
      name: "Author2",
      link: "#",
      sub: null
    }]
  }, {
    name: "Published At",
    link: "#",
    sub: null
  }, {
    name: "Stream",
    link: "#",
    sub: [{
      name: "STR1",
      link: "#",
      sub: null
    }, {
      name: "STR2",
      link: "#",
      sub: null
    }]
  }]
};


$(function() {

  function parseMenu(ul, menu) {
    for (var i = 0; i < menu.length; i++) {
      var li = $(ul).append(
        '<li>' + menu[i].name + '</li>');
      if (menu[i].sub != null) {
        var subul = $('<ul class="list"></ul>');
        $(li).append(subul);
        parseMenu($(subul), menu[i].sub);
      }
    }
  }

  var menu = $('#menu');
  parseMenu(menu, JSON.menu);
});



$(document).on('click', '.list > li ', function() {
  $(this).next('ul').toggle();
});
ul ul {
  display: none;
}

a {
  color: red;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="menu" class="list"></ul>
Valedictory answered 20/2, 2017 at 13:1 Comment(0)
S
0

Quick fix would be to replace last script with this snippet:

<script type="text/javascript">$(document).on('click', '.list > li ', function () {
$(this).next('.list').children().toggle();
})</script>

What this will do is expand and collapse the list that is right after your heading element.

A better solution would be to restructure your HTML DOM content by creating nested "ul" under "li".

Hope this helps.

Sevilla answered 20/2, 2017 at 13:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.