Search code examples
jqueryhtmlasp.net-mvc

Toggle children when parent li is clicked


I'm trying to make a tree like structure where branches can be shown/collapsed when parent is clicked. Whatever I tried so far, it seems that I can't prevent the whole tree to collapse whenever any item from the tree is clicked, leaving only the root element. I tried with children, Parent, sibling, having a class to the root ul, to all the ul, on li, using unique Id instead of class ... Nothing worked for me. Always this weird behavior, errors, or nothing.

view:

<script type="text/javascript">
    $(document).ready(function() {
        $('.tree').click(function () {
            $(this).find('ul').slideToggle();
        });
    });
</script>

<h2>testArbre</h2>

<ul>
    <li class="tree">
        @Model.Name
        @ShowTree(@Model)
    </li>    
</ul>

@helper ShowTree(Tree tree)
{
    <ul>
        @foreach (var branch in tree.Branch)
        {
            <li class="tree">
                @branch.Name
                @if (branch.Branches.Any())
                {
                    @ShowTree(branch)
                }
            </li>
        }
    </ul>
}

Model:

public class ArbreDroits
    {
        public string Name { get; set; }
        public List<Tree> Branches { get; set; }

        public Tree(string name)
        {
            Name = name;
            Branches = new List<Tree>();
        }

        public ArbreDroits AddBranch(string name)
        {
            Branches.Add(new Tree(name));

            return Branches.Last();
        }
    }

the generated html looks like this:

<ul>
    <li class="tree">
        racine
        <ul>
            <li class="tree">
                noeud1
                <ul>
                    <li class="tree">
                        noeud1Fils1
                    </li>
                    <li class="tree">
                        noeud1Fils2
                        <ul>
                            <li class="tree">
                                noeud1Fils2Fils1
                                <ul>
                                    <li class="tree">
                                        noeud1Fils2Fils1Fils1
                                    </li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                    <li class="tree">
                        noeud1Fils3
                    </li>
                </ul>
            </li>
            <li class="tree">
                noeud2
            </li>
        </ul>

    </li>    
</ul>

Solution

  • My bet is you need to stop click event propagation and only target direct descendant using children():

    $(document).ready(function() {
      $('.tree').click(function(e) {
        e.stopPropagation();
        $(this).children('ul').slideToggle();
      });
    });