3
votes

I have a multi level sidebar navigation tree with font awesome icons inside li items. I want an icon to turn from plus to minus when it is expanded, and back to plus when it is collapsed. Clicking one li item should not affect the state of another li item.

This is the jQuery script that I am using:

$('.tree-toggle').click(function () {
        $(this).parent().children('ul.tree').toggle(1);
        $(this).parent().toggleClass('active');
    });

    $('.aside-list li').click(function(){
        $(this).children('label').children('i').toggleClass('fa-plus-square fa-minus-square')
        $(this).children('label').children('i').toggleClass('fa-caret-up fa-caret-down')
    });

This is my HTML structure:

<div class="well">
        <ul class="nav nav-list aside-list">
            <li>
            <label class="tree-toggle nav-header">Category <i class="fa fa-caret-down"></i></label>
                <ul class="nav nav-list tree">
                    <li><label class="tree-toggle nav-header"><i class="fa fa-plus-square"></i> In id sodales leo</label>
                        <ul class="nav nav-list tree">
                            <li><label class="tree-toggle nav-header"><i class="fa fa-plus-square"></i> Tortor masa</label>
                                <ul class="nav nav-list tree">
                                <li><a href="#">Lorem ipsum dolor sit amet</a></li>
                                <li><a href="#">Adipiscing elit</a></li>
                                    <li><label class="tree-toggle nav-header"><i class="fa fa-plus-square"></i> Integro commodo</label>
                                        <ul class="nav nav-list tree">
                                            <li><a href="#">Colors</a></li>
                                            <li><a href="#">Sizes</a></li>
                                        </ul>
                                    </li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul><!-- end aside-list -->
    </div><!-- end well -->

Right now the functionality is faulty as clicking one item alters the icon state of all items of the list.

I made a JS Fiddle for the code as well:
https://jsfiddle.net/njm9Lz4e/#&togetherjs=PRGpaib46U

2
Why do you have 4 different icons on one element? If there isn't any class on a toggleClass that class will be added. - zer00ne

2 Answers

4
votes

By opening a LI element you expose other LI elements.
Clicking that inner LI - the click will propagate to the parent LIs causing your issue, therefore

prevent the click to propagate to parent elements like:

$('.aside-list li').click(function(evt) {
   evt.stopPropagation();

jsFiddle example

0
votes

Use event.target for li clicks, it works fine.

$('.tree-toggle').click(function() {
      $(this).parent().children('ul.tree').toggle(1);
      $(this).parent().toggleClass('active');
    });

    $('.aside-list li').click(function(event) {
      $(event.target).children('label').children('i').toggleClass('fa-plus-square fa-minus-square')
      $(event.target).children('label').children('i').toggleClass('fa-caret-up fa-caret-down')
    });
.tree {
  display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div class="well">
        <ul class="nav nav-list aside-list">
            <li>
            <label class="tree-toggle nav-header">Category <i class="fa fa-caret-down"></i></label>
                <ul class="nav nav-list tree">
                    <li><label class="tree-toggle nav-header"><i class="fa fa-plus-square"></i> In id sodales leo</label>
                        <ul class="nav nav-list tree">
                            <li><label class="tree-toggle nav-header"><i class="fa fa-plus-square"></i> Tortor masa</label>
                                <ul class="nav nav-list tree">
                                <li><a href="#">Lorem ipsum dolor sit amet</a></li>
                                <li><a href="#">Adipiscing elit</a></li>
                                    <li><label class="tree-toggle nav-header"><i class="fa fa-plus-square"></i> Integro commodo</label>
                                        <ul class="nav nav-list tree">
                                            <li><a href="#">Colors</a></li>
                                            <li><a href="#">Sizes</a></li>
                                        </ul>
                                    </li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul><!-- end aside-list -->
    </div><!-- end well -->