Filter Multi-Level List

1.4k views Asked by At

I have a deeply nested list (10 levels), and I want to filter through that list so that I can get the <li> that I searched for and if that <li> has children I want to show them as well, Here's a code example ...

$(document).ready(function () {
    $("#filter").keyup(function () {
        var filter = $(this).val();
      
        $("li").each(function () {
            if (filter == "") {
                $(this).css("visibility", "visible");
                $(this).fadeIn();
            } else if ($(this).text().search(new RegExp(filter, "i")) < 0) {
                $(this).css("visibility", "hidden");
                $(this).fadeOut();
            } else {
                $(this).css("visibility", "visible");
                $(this).fadeIn();
            }
        });
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="filter" type="text" />
<ul>
    <li>Tom</li>
    <li> <a>Peter</a>

        <ul>
            <li> <a>John</a>
                <ul>
                    <li> <a>Doe</a>

                        <ul>
                            <li> <a>Shia</a>

                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li><a>Nicolas</a>

            </li>
            <li><a>Reem</a>

            </li>
        </ul>
    </li>
    <li><a>Danial</a>
        <ul>
            <li> <a>Adam</a>

            </li>
        </ul>
    </li>
</ul>

In the above example, I managed to get the <li> I searched for, but I can't figure out how to keep it's children visible and open if he has any.

Note: you don't have to re-use the code I posted here, you can post a better, more flexible implementation if you can.

2

There are 2 answers

1
C Van On

$(document).ready(function () {
    
  
    $("#filter").keyup(function () {
        var filter = $(this).val();
      
        $("li").each(function () {
            if (filter == "") {
                $(this).css("visibility", "visible");
                $(this).fadeIn();
            } else if ($(this).text().search(new RegExp(filter, "i")) < 0) {
                $(this).css("visibility", "hidden");
                $(this).fadeOut();
            } else {
                $(this).css("visibility", "visible");
                $(this).fadeIn();
            }
        });
    });
    
    $('.hasSub').click(function () {
    $(this).parent().toggleClass('subactivated');
  $(this).parent().children('ul:first').toggle();
    
    if($(this).find('i').hasClass('glyphicon-folder-open')){
      $(this).find('i').removeClass('glyphicon-folder-open').addClass('glyphicon-folder-close');
    }else{
      $(this).find('i').removeClass('glyphicon-folder-close').addClass('glyphicon-folder-open');
    }
 }); 
  
});
.fordtreeview ul{
  display:none;
  margin: 15px -16px;
  list-style:none;
}

.fordtreeview ul.expanded{
  display:block;
}

.fordtreeview ul li{
  left:5px;
  margin-right:10px; 
  color: #333;
}

.fordtreeview > li:first-child{
  display:block !important;
}

.fordtreeview li,
.fordtreeview a{
  color: #333; 
  text-decoration:none; 
  cursor:pointer;
}

.fordtreeview i.glyphicon{
  margin-right:5px;
}

.subactivated,
.fordtreeview > li:not(:first-child):hover{
  background-color: #f5f5f5;
}
  <link rel='stylesheet prefetch' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="filter" type="text" />
<ul class="fordtreeview list-group col-md-2" >
 
    <li class="list-group-item"> <span class="hasSub"><i class="glyphicon glyphicon-folder-close"></i> Peter </span>

        <ul class="list-group ">
            <li class="list-group-item" > <a>John</a>    </li>
            <li class="list-group-item" ><a>Nicolas</a></li>
           
        </ul>
    </li>
    <li  class="list-group-item"><span class="hasSub"><i class="glyphicon glyphicon-folder-close"></i> Danial</span>
        <ul class="list-group " >
            <li class="list-group-item"> <a>Adam</a></li>
        </ul>
    </li>
 
</ul>

0
C Van On

Ok :) only add

         else if ($(this).text().search(new RegExp(filter, "i")) < 0) {

            if(!$(this).parent().parent().is('li')){
                $(this).css("visibility", "hidden");
                $(this).fadeOut();
            }

        }