【问题标题】:How do I filter results with multiple select groups using jQuery?如何使用 jQuery 过滤多个选择组的结果?
【发布时间】:2012-09-12 00:45:46
【问题描述】:

我现在尝试过滤两个选项,但稍后会添加第三个,也许是第四个(例如:现在我在价格和评论之间进行过滤,但想要添加更多价格列表以及另一个过滤器类别,例如“评分”,由 3、4 或 5 颗星组成)。

使用我在下面列出的逻辑可以正常工作,但我觉得它会变得非常冗长和复杂(并且不必要)。我知道有一种方法可以重构代码我只是想知道最好的方法是什么? HTML:

  <select class="deals">
    <option value="deals-all">All deals</option>
    <option value="50">$50</option>
    <option value="25">$25</option>
  </select>

  <select class="reviews">
    <option value="reviews-all">All reviews</option>
    <option value="reviews-positive">Positive reviews</option>
    <option value="reviews-negative">Negative reviews</option>
  </select>

jQuery

 $('.reviews, .deals').change(function() {

var reviewsVal = $('.reviews :selected').val();
var dealsVal = $('.deals :selected').val();



 if((reviewsVal == 'reviews-all') && (dealsVal == 'deals-all')) {

      $('.review-positive').show();
 $('.review-negative').show();
 $('.deals-25').show();
 $('.deals-50').show();
 } 


else if((dealsVal == '50') && (reviewsVal == 'reviews-positive')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').show();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').hide();

 }

 else if((dealsVal == '50') && (reviewsVal == 'reviews-negative')) {
 $('.review-negative.deals-50').show();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').hide();
 }

else if((dealsVal == '25') && (reviewsVal == 'reviews-positive')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').show();
}

else if((dealsVal == '25') && (reviewsVal == 'reviews-negative')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').show();
 $('.review-positive.deals-25').hide();
}

 else if((dealsVal == 'deals-all') && (reviewsVal == 'reviews-positive')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').show();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').show();
}

else if((dealsVal == 'deals-all') && (reviewsVal == 'reviews-negative')) {
 $('.review-negative.deals-50').show();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').show();
 $('.review-positive.deals-25').hide();
}

else if((dealsVal == '50') && (reviewsVal == 'reviews-all')) {
 $('.review-negative.deals-50').show();
 $('.review-positive.deals-50').show();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').hide();
}

else if((dealsVal == '25') && (reviewsVal == 'reviews-all')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').show();
 $('.review-positive.deals-25').show();
}

else {
 $('.review-positive').show();
 $('.review-negative').show();
 $('.deals-25').show();
 $('.deals-50').show();
} 
});

$('.reviews-positive').click(function() {
$('.review-negative').hide();
$('.review-positive').show();
});

$('.reviews-negative').click(function() {
$('.review-positive').hide();
$('.review-negative').show();
});


});​

希望您能看到我的目标,感谢您的意见。

*编辑:jsfiddle:http://jsfiddle.net/TXywp/1/

【问题讨论】:

  • 你可以为 requiremnet 发布一个 jsFiddle 吗.. 可以更容易处理

标签: javascript jquery html refactoring filtering


【解决方案1】:

我可以想到两种不同的方法来简化代码并使其更易于维护和发展:

  1. 您可以根据条件通过算法推导出应该隐藏或显示哪些项目。

  2. 您可以创建一个条件和操作表,以便添加新条件和操作只是向表中添加一个新项目。

  3. 更改您的 HTML 以使其对应显示的内容进行自我描述。

表驱动方法如下所示:

$('.reviews, .deals').change(function() {

    var allDeals = '.review-negative.deals-50, .review-positive.deals-50, .review-positive.deals-25, .review-negative.deals-25';

    var table = [
        {rv: 'reviews-all', dv: 'deals-all', show: '.review-positive, .review-negative, .deals-25, .deals-50'},
        {rv: 'reviews-positive', dv: '50', show: '.review-positive.deals-50'},
        {rv: 'reviews-negative', dv: '50', show: '.review-negative.deals-50'},
        {rv: 'reviews-positive', dv: '25', show: '.review-positive.deals-25'}
        {rv: 'reviews-negative', dv: '25', show: '.review-negative.deals-25'},
        {rv: 'reviews-positive', dv: 'deals-all', show: '.review-positive.deals-50, .review-positive.deals-25'},
        {rv: 'reviews-negative', dv: 'deals-all', show: '.review-negative.deals-50, .review-negative.deals-25'},
        {rv: 'reviews-all', dv: '50', show: '.review-negative.deals-50, .review-positive.deals-50'},
        {rv: 'reviews-all', dv: '25', show: '.review-negative.deals-25, .review-positive.deals-25'}
    ];

    var reviewsVal = $('.reviews :selected').val();
    var dealsVal = $('.deals :selected').val();

    $(allDeals).hide();

    var item, found = false;
    for (var i = 0, len = table.length; i < len; i++) {
        item = table[i];
        if (dealsVal == item.dv && reviewsVal == item.rv) {
            $(item.show).show();
            found = true;
            break;
        }
    }

    if (!found) {
        $('.review-positive, .review-negative, .deals-25, .deals-50').show();
    } 
});

而且,这是一种算法方式,您只需向数组中添加一个新条目即可添加新交易价值。只有两个交易,这可能比表格驱动的方法工作更多,但如果您有 4 个或更多交易级别,这将更容易维护。

$('.reviews, .deals').change(function() {
    var deals = ['25', '50'];

    function addAllDeals(base, prefix) {
        for (var i = 0; i < deals.length; i++) {
            if (base) base += ", ";
            base += prefix + deals[i];
        }
        return(base);
    }

    function addSingleDeal(prefixes, deal) {
        var sel = [];
        for (var i = 0; i < prefixes.length; i++) {
            sel.push(prefixes[i] + deal);
        }
        return(sel.join(", ");
    }

    var reviewsVal = $('.reviews :selected').val();
    var dealsVal = $('.deals :selected').val();
    var itemsToShow = "";

    // hide everything to start
    var initialHide = addAllDeals("", ".review-positive.deals-");
    initialHide = addAllDeals(initialHide, ".review-negative.deals-");
    $(initialHide).hide();

    if (reviewsVal == 'reviews-all') {
        if (dealsVal == 'deals-all') {
            itemsToShow = addAllDeals(".review-positive, .review-negative", ".deals-");
        } else {
            itemsToShow = addSingleDeal([".review-negative.deals-", ".review-negative.deals-"], dealsVal);
        }
    } else if (reviewsVal == 'reviews-positive') {
        itemsToShow = '.review-positive.deals-' + dealsVal;
    } else if (reviewVal == 'reviews-negative') {
        itemsToShow = '.review-negative.deals-' + dealsVal;
    } else {
        itemsToShow = addAllDeals(".review-positive, .review-negative", ".deals-");
    }
});

如果您可以将您的 HTML(如我上面的第三个选项)更改为:

  <select class="deals">
    <option value="deals-all" data-base=".review-positive, .review-negative">All deals</option>
    <option value="50" data-base=".deals-50">$50</option>
    <option value="25" data-base=".deals-25">$25</option>
  </select>

  <select class="reviews">
    <option value="reviews-all" data-filter="">All reviews</option>
    <option value="reviews-positive" data-filter=".review-positive">Positive reviews</option>
    <option value="reviews-negative" data-filter=".review-negative">Negative reviews</option>
  </select>

然后,你就可以使用这个简单的javascript了:

 $('.reviews, .deals').change(function() {

    var dealsBase = $('.deals :selected').data("base");
    var reviewsFilter = $('.reviews :selected').data("filter");

     // hide all
     $(".review-negative, .review-positive").hide();

     // show the desired ones
     var base = $(dealsBase);
     if (reviewsFilter) {
         base = base.filter(reviewsFilter);
     }
     base.show();
});

警告:由于您没有提供代码/HTML 的有效 jsFiddle 示例来尝试此操作,因此该代码尚未运行或检查输入错误。但是,希望您了解这两种方法。

【讨论】:

  • @SarahM - 我添加了第三个更简单的选项。在其中,您可以让选项自我描述它们应该显示/过滤的内容,这样代码就不必执行该工作。
  • jfriend,非常感谢您的帮助和意见。两种反应都非常有效。
【解决方案2】:

要获得动态结果,最好的方法是标准化命名。 您首先标准化标准选择器,给它们一个通用类并区分 id 属性。还建议遵循值的命名约定。这会产生类似于

的东西
    <select id="deal" class="criteriaSelector">
      <option value="all">All deals</option>
      <option value="50">$50</option>
      <option value="25">$25</option>
    </select>

    <select id="review" class="criteriaSelector">
      <option value="all">All reviews</option>
      <option value="positive">Positive reviews</option>
      <option value="negative">Negative reviews</option>
    </select>

然后你给除了过滤类之外的所有你想要过滤的项目一个通用类。我将以 .item 为例。您还希望能够从选定的值和标准名称构造类,因此使用 .{id}-{value} 系统将完美地工作。这将给我们留下一些

    <div class="item review-positive deal-25"></div>
    <div class="item review-negative deal-50"></div>

此设置将允许我们构建动态和可扩展的代码:

    $('.criteriaSelector').change(function() {
      // Initialize criteria string
      var criteria = '';
      // Set value for all selector
      var showAll = true;

      // Iterate over all criteriaSelectors
      $('.criteriaSelector').each(function(){
        // Get value
        var val = $(this).children(':selected').val();
        // Check if this limits our results
        if(val !== 'all'){
          // Append selector to criteria
          criteria += '.' + $(this).attr('id') + '-' + val;
          // We don't want to show all results anymore
          showAll = false;
        }
      });
      // Check if results are limited somehow
      if(showAll){
        // No criterias were set so show all
        $('.item').show();
      } else {
        // Hide all items
        $('.item').hide();
        // Show the ones that were selected
        $(criteria).show();
      }

    });

现在添加新的条件选择器不需要更改这段代码,只要遵循命名约定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 2020-04-06
    • 2019-04-08
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    相关资源
    最近更新 更多