Как искать во вложенном списке с помощью jQuery? - PullRequest
2 голосов
/ 29 марта 2012

Я собрал простое поле поиска, чтобы просмотреть список, но у меня есть вложенные списки, и он ограничен одним списком уровней - как вы можете изменить

Я поместил его вскрипка;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 ]

1 голос
/ 09 декабря 2015

пример в учебнике очень хорош, но он не работал для моих вложенных списков. Я создал другой код на основе примера, и он работает очень хорошо.

например. списка (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));
1 голос
/ 29 марта 2012

Поиск работает, но только когда текстовое поле теряет фокус или нажата клавиша ввода.

Измените следующую строку с:

$(input).change(function(){

на:

$(input).keyup(function(){

и функциональность, кажется, начинает работать нормально.

Я также заметил, что модификация contains не выполняет поиск без учета регистра, поэтому изменение следующей строки так же должно исправить это:

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

Вот обновленный jsFiddle .

0 голосов
/ 30 марта 2012

Мне удалось исправить мои проблемы с этим сейчас.

Моя первоначальная проблема с попыткой получить доступ к списку заключалась в том, что я не мог использовать селекторы классов для существующего содержимого в моем экспортированном 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;
      })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...