使用多个搜索条件在li中搜索

时间:2014-06-22 08:54:19

标签: jquery search criteria

列表中的多个搜索条件

我有一个如下所示的列表

<ul>
    <li>
        <dl class="p_list1">
            <dd id="name">
                <b>Car</b></dd>
            <dd id="company">
                Honda, Hyundai, Toyota, Suzuki</dd>
        </dl>
    </li>
    <li>
        <dl class="p_list2">
            <dd id="name">
                <b>Bike</b></dd>
            <dd id="company">
                Honda, Yamaha, Suzuki</dd>
        </dl>
    </li>
    <li>
        <dl class="p_list3">
            <dd id="name">
                <b>Truck</b></dd>
            <dd id="company">
                Tata, Volvo, Mahindra</dd>
        </dl>
    </li>
</ul>

我使用两个文本框txtName和txtCompany来搜索此列表。 基于一个文本框值或两个文本框值我需要显示和隐藏列表。

  1. 如果用户在txtName中搜索&#34; c&#34;它必须显示第1和第3项。 (txtCompany为空)
  2. 如果用户在txtcompany中搜索&#34; Hon&#34;它必须显示第一和第二个列表。 (txtname为空)
  3. 如果txtName喜欢&#34; c&#34;并且用户在txtCompany上搜索,然后它必须从列表中搜索第1和第3项
  4. 我使用了以下jquery

    (
            function ($) {
                jQuery.expr[':'].Contains = function (a, i, m) {
                    return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
                };
                function listFilter(list) {
    
                    $('#txtName').change(function () {
                        var filter = $(this).val(); if (filter) { $(list).find("dd[id='name']:not(:Contains(" + filter + "))").parent().parent().slideUp(); $(list).find("dd[id='name']:Contains(" + filter + ")").parent().parent().slideDown(); }
                        else
                        { $(list).find("li").slideDown(); }
                        return false;
                    }
                   ).keyup(function () { $(this).change(); });
    
    
                    $('#txtCompany').change(function () {
                        var filter = $(this).val(); if (filter) { $(list).find("dd[id='company']:not(:Contains(" + filter + "))").parent().parent().slideUp(); $(list).find("dd[id='company']:Contains(" + filter + ")").parent().parent().slideDown(); }
                        else
                        { $(list).find("li").slideDown(); }
                        return false;
                    }
                   ).keyup(function () { $(this).change(); });
    
    
                }
    
    
    
                $(function () {
                    listFilter($("#list"));
                }
                );
            } (jQuery)); 
    

    现在的问题是,当我开始使用一个文本框搜索它工作正常时,当我使用两个搜索条件时,它将开始基于当前文本框按键搜索。 我知道这是因为我已经为文本框编写了更改事件,并且没有考虑其他文本框值:(

    此处a link to the test I have created

2 个答案:

答案 0 :(得分:1)

这段代码可以解决问题:

编辑:此代码根据两个条件的OR组合过滤元素。

 (
        function ($) {
            jQuery.expr[':'].Contains = function (a, i, m) {
                return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
            };
            var nameFilter, companyFilter;    //store their values

            function onConditionChange (nameFilter, companyFilter) {

                     var hideCondition =  "dd" + (companyFilter ? "[id='company']:not(:Contains(" + companyFilter + "))" : "") + (nameFilter ? "[id='name']:not(:Contains(" + nameFilter + "))" : "");

                    if (nameFilter || companyFilter) { 

                        $(list).find(hideCondition).parent().parent().slideUp();
                        if (nameFilter) {
                                                    $(list).find("dd[id='name']:Contains(" + nameFilter + ")").parent().parent().slideDown();
                                                }
                                                if (companyFilter) {
                                                        $(list).find("dd[id='company']:Contains(" + companyFilter + ")").parent().parent().slideDown();                         
                                                }                        
                    } else { 
                        $(list).find("li").slideDown(); 
                    }
                    return false;
                }            

            function listFilter(list) {

                $('#txtName').change(function() {
                    nameFilter = $(this).val();
                    onConditionChange(nameFilter, companyFilter);
                }
               ).keyup(function () { $(this).change(); });


                $('#txtCompany').change(function() {
                    companyFilter = $(this).val();
                    onConditionChange(nameFilter, companyFilter);
                }
               ).keyup(function () { $(this).change(); });


            }



            $(function () {
                listFilter($("#list"));
            }
            );
        } (jQuery)); 

我分叉你的小提琴,以便你可以看到它here

基本上,您可以跟踪这两个条件,并将它们用于过滤器,如果它们不为空(或者至少有一个不为空)。

我尝试强制执行DRYer版本,但代码重复较少。但是,它仍然可以改进,但它应该可以解决您的问题。

修改

阅读评论后,here这是一个过滤将两个搜索条件放在AND中的元素的版本。

 (
    function ($) {
        jQuery.expr[':'].Contains = function (a, i, m) {
            return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
        };
        var nameFilter, companyFilter;    //store their values

        function onConditionChange (nameFilter, companyFilter) {

                 var showCondition =  "dd" + (companyFilter ? "[id='company']:Contains(" + companyFilter + ")" : "") + (nameFilter ? "[id='name']:Contains(" + nameFilter + ")" : "");

                if (nameFilter || companyFilter) { 
                    if (nameFilter) {                        
                        $(list).find("dd[id='name']:not(:Contains(" + nameFilter + "))").parent().parent().slideUp();
                    }
                    if (companyFilter) {
                        $(list).find("dd[id='company']:not(:Contains(" + companyFilter + "))").parent().parent().slideUp();                            
                    }

                    $(list).find(showCondition).parent().parent().slideDown();

                } else { 
                    $(list).find("li").slideDown(); 
                }
                return false;
            }            

        function listFilter(list) {

            $('#txtName').change(function() {
                nameFilter = $(this).val();
                onConditionChange(nameFilter, companyFilter);
            }
           ).keyup(function () { $(this).change(); });


            $('#txtCompany').change(function() {
                companyFilter = $(this).val();
                onConditionChange(nameFilter, companyFilter);
            }
           ).keyup(function () { $(this).change(); });


        }



        $(function () {
            listFilter($("#list"));
        }
        );
    } (jQuery)); 

答案 1 :(得分:0)

您遇到问题,因为您对多个DOM元素使用相同的ID,这是不允许的。如果要将相同的jquery函数调用到多个DOM元素,请尝试分配类而不是ID。

我在标记中标记了问题:

<ul>
    <li>
        <dl class="p_list1">
            <dd id="name"> <!--OK to have an ID here---->
                <b>Car</b></dd>
            <dd id="company"><!--OK to have an ID here---->
                Honda, Hyundai, Toyota, Suzuki</dd>
        </dl>
    </li>
    <li>
        <dl class="p_list2">
            <dd id="name"><!--ID repeated, jquery function won't run for this event---->
                <b>Bike</b></dd>
            <dd id="company"><!--ID repeated, jquery function won't run for this event---->
                Honda, Yamaha, Suzuki</dd>
        </dl>
    </li>
    <li>
        <dl class="p_list3">
            <dd id="name"><!--ID repeated, jquery function won't run for this event---->
                <b>Truck</b></dd>
            <dd id="company"><!--ID repeated, jquery function won't run for this event---->
                Tata, Volvo, Mahindra</dd>
        </dl>
    </li>
</ul>