How to search a nested list using jQuery?

I put together a simple search field to browse the list, but I have nested lists and it is limited to one list of levels - how do you change

I put it in the violin; http://jsfiddle.net/marksweb/4CJMe/

What do I need to do for mine if(filter)to also check nested elements and not hide the child of the nested list, if there is a result?

Demo site; http://dl.dropbox.com/u/3755926/cssTricks/main.html

(function ($) {
  // custom css expression for a case-insensitive contains()
  jQuery.expr[':'].Contains = function(a,i,m){
      return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0;
  };

  function searchList(header, list) { // header is any element, list is an unordered list
    // create and add the filter form to the header
    var form = $("<form>").attr({"class":"filterform","action":"#"}),
        input = $("<input>").attr({"class":"filterinput","type":"text"});
    $(form).append(input).prependTo(header);

    $(input)
      .change( function () {
        var filter = $(this).val();
        if(filter) {
            // this finds all links in a list that contain the input,
            // and hide the ones not containing the input while showing the ones that do
            $(list).find("a:not(:Contains(" + filter + "))").parent().slideUp();
            $(list).find("a:Contains(" + filter + ")").parent().slideDown();
        } else {
            // return to default
            $(list).find("li").slideDown();
        }
        return false;
      })
    .keyup( function () {
        // fire the above change event after every letter
        $(this).change();
    });
  }

  //ondomready
  $(function () {
    searchList($("#main"), $("#contents-list"));
  });
}(jQuery));
+1
source share
3 answers

I managed to solve the problems with this now.

, HTML, , searchList($("#main"), $("#contents-list"));, .

<a> <li>, , <li> <ul>, ;

        if(filter) {
            // this finds all links in a list that contain the input,
            // and hide the ones not containing the input while showing the ones that do
            $(list).find("li:not(:Contains(" + filter + "))").parent().slideUp();
            $(list).find("li:Contains(" + filter + ")").parent().slideDown();
        } else {
            // return to default
            $(list).find("ul").slideDown();
        }
        return false;
      })
0

, .

:

$(input).change(function(){

$(input).keyup(function(){

, , .

, contains , :

var hasMatch = searchTerms.length == 0 || $(this).text().toLowerCase().indexOf(searchTerms.toLowerCase()) > 0;

jsFiddle.

+1

the example in the tutorial is very good, but it did not work for my nested lists. I created another code based on an example and it works very well.

eg. list (html code):

  <h3 id="header">Search words
            <form class="filterform" action="#">
                <input class="filterinput" type="text" id="filterinput">
            </form>
        </h3>
<ul id="list"  >
            <li><span><a>1</a></span>
                <ul>
                    <li><span><a>12</a></span>
                        <ul>
                            <li><span><a>23</a></span>
                                <ul>
                                    <li><span><a>33</a></span></li>
                                    <li><span><a>31</a></span></li>
                                    <li><span><a>35</a></span></li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                    <li><span><a>14</a></span>
                        <ul>
                            <li><span><a>23</a></span>
                                <ul>
                                    <li><span><a>34</a></span></li>
                                    <li><span><a>36</a></span></li>
                                </ul>
                            </li>
                            <li><span><a>24</a></span>
                                <ul>
                                    <li><span><a>32</a></span></li>
                                    <li><span><a>34</a></span></li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li><span><a>2</a></span></li>
        </ul>

and this is jquery code:

    (function ($) {
    // custom css expression for a case-insensitive contains()
    jQuery.expr[":"].contains = jQuery.expr.createPseudo(function (arg) {
        return function (elem) {
            return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
        };
    });

    // this function calls itself, to search in every level
    function hasChild(list) {
        // the searched value
        var filter = $('#filterinput').val();
        // for every children, do function:
        list.children('li').each(function () {
            // see if the list contains the filter
// if you don't want to use span,  you can  write the following function:
 //find("a:contains(" + filter + ")")
                        if ($(this).find("span > a:contains(" + filter + ")").length > 0) {
                            // see if it has nested levels
                            if ($(this).find('ul :first').length > 0) {
                                $(this).show();
                                // recall function
                                hasChild($(this).find('ul :first').parent());
                            } else {
                                $(this).show();
                            }
                        } else {
                            $(this).hide();
                        }
                    });
                };
                $('#filterinput').keyup(function () {
                    // the id of the filtered list
                    var list = '#list';
                    // the searched value
                    var filter = $('#filterinput').val();
                    if (filter) {
                        // call previous function
                        hasChild($(list));
                    } else {
                        // show all
                        $(list).find("li").show();
                    }
                    return false;
                });
            }(jQuery));
+1
source

Source: https://habr.com/ru/post/1664534/


All Articles