如何使用jQuery搜索嵌套列表?

时间:2012-03-29 09:10:00

标签: jquery list search

我已经将一个简单的搜索字段放在一起查看列表,但我有嵌套列表,它仅限于单个级别列表 - 如何修改

我把它放在一个小提琴里; http://jsfiddle.net/marksweb/4CJMe/

我需要对if(filter)做什么才能检查嵌套项目,如果结果存在则不隐藏嵌套列表的子项?

演示网站; 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));

3 个答案:

答案 0 :(得分:1)

搜索有效,但仅在文本框失去焦点或输入时才会被按下。

更改以下行:

$(input).change(function(){

为:

$(input).keyup(function(){

并且功能似乎开始正常工作。

我还注意到contains修改没有执行不区分大小写的搜索,因此修改以下行也应该解决这个问题:

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

以下是更新后的jsFiddle

答案 1 :(得分:1)

本教程中的示例非常好,但它对我的嵌套列表不起作用。我根据示例创建了一个不同的代码,它运行得很好。

例如。列表(HTML代码):

  <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>

这是jquery代码:

    (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));

答案 2 :(得分:0)

我已经设法解决了我的问题。

我尝试访问列表时遇到的最初问题是我无法在导出的HTML中使用类选择器来处理现有内容,因此我必须添加自定义ID并使用searchList($("#main"), $("#contents-list"));成功运行的ID。

然后,为了访问嵌套列表项,我必须从<a><li>中获取过滤器级别,如我在此处的问题中所示,以访问<li>并默认为{{1所以最终的过滤器看起来像这样;

<ul>