为一个字段过滤具有多个值的 属性 - List.js 和 Filter.js

Filtering a property with multiple values for one field - List.js and Filter.js

我目前正在使用 list.js 插件及其过滤器扩展来生成搜索结果页面,该页面允许用户过滤最终结果,以便他们更容易准确地找到他们正在寻找的内容为.

我一直在使用他们的 API 来尝试提出一个解决方案,但老实说,它有点过时并且不确定上次更新的时间。

http://www.listjs.com/docs/list-api

我的代码如下:

HTML

<div id="search-results">
  <div class="col-md-3">
    <div class="panel panel-warning">
      <div class="panel-heading">Filters</div>
      <div class="panel-body">
        <div class="search-filter">
          <ul class="list-group">
            <li class="list-group-item">
              <div class="list-group-item-heading">
                <h4>Filter Options</h4>
              </div>
            </li>
            <li class="list-group-item">
              <div class="nameContainer">
                <h5 class="list-group-item-heading">Name</h5>
              </div>
            </li>
            <li class="list-group-item">
              <div class="typeContainer">
                <h5 class="list-group-item-heading">Type</h5>
              </div>
            </li>
            <li class="list-group-item">
              <div class="difficultyContainer">
                <h5 class="list-group-item-heading">Difficulty</h5>
              </div>
            </li>
            <li class="list-group-item">
              <label>Tour contains</label>
              <input class="search form-control" placeholder="Search" />
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  <div class="col-md-9">
    <div class="panel panel-primary">
      <div class="panel-heading">Results</div>
      <div class="list panel-body">
         <div class="package well">
           <div class="name">Niagra Falls</div>
           <div class="type hidden">Boat Trip</div>
           <div class="difficulty">Relaxed</div>
         </div>
        <div class="package well">
           <div class="name">Pyramids</div>
           <div class="type hidden">History Holiday</div>
           <div class="difficulty">Relaxed</div>
         </div>
        <div class="package well">
           <div class="name">Great Barrier Reef</div>
           <div class="type hidden">Snorkling Holiday</div>
           <div class="difficulty">Dangerous</div>
         </div>
        <div class="package well">
           <div class="name">Boar Hunting</div>
           <div class="type hidden">Hunting Trip</div>
           <div class="difficulty">Active</div>
         </div>
        <div class="package well">
           <div class="name">Thames Cruise</div>
           <div class="type hidden">Cruise</div>
           <div class="difficulty">Easy</div>
         </div>
      </div>
      <ul class="pagination"></ul>
    </div>
  </div>
</div>

Javascript

var options = {
            valueNames: ['name', 'type', 'difficulty'],
            page: 3,
            plugins: [
               ListPagination({})
            ]
        };
        var userList = new List('search-results', options);
        var updateList = function () {
            var name = new Array();
            var type = new Array();
            var difficulty = new Array();

            $("input:checkbox[name=name]:checked").each(function () {
                name.push($(this).val());
            });

            $("input:checkbox[name=type]:checked").each(function () {
                type.push($(this).val());
            });

            $("input:checkbox[name=difficulty]:checked").each(function () {
                difficulty.push($(this).val());
            });

            var values_type = type.length > 0 ? type : null;
            var values_name = name.length > 0 ? name : null;
            var values_difficulty = difficulty.length > 0 ? difficulty : null;

            userList.filter(function (item) {
                return (_(values_type).contains(item.values().type) || !values_type)
                        && (_(values_name).contains(item.values().name) || !values_name)
                        && (_(values_difficulty).contains(item.values().difficulty) || !values_difficulty)
            });
        }

        userList.on("updated", function () {
            $('.sort').each(function () {
                if ($(this).hasClass("asc")) {
                    $(this).find(".fa").addClass("fa-sort-alpha-asc").removeClass("fa-sort-alpha-desc").show();
                } else if ($(this).hasClass("desc")) {
                    $(this).find(".fa").addClass("fa-sort-alpha-desc").removeClass("fa-sort-alpha-asc").show();
                } else {
                    $(this).find(".fa").hide();
                }
            });
        });

        var all_type = [];
        var all_name = [];
        var all_difficulty = [];

        updateList();
        _(userList.items).each(function (item) {
            all_type.push(item.values().type)
            all_name.push(item.values().name)
            all_difficulty.push(item.values().difficulty)
        });

        _(all_type).uniq().each(function (item) {
            $(".typeContainer").append('<label><input type="checkbox" name="type" value="' + item + '">' + item + '</label>')
        });

        _(all_name).uniq().each(function (item) {
            $(".nameContainer").append('<label><input type="checkbox" name="name" value="' + item + '">' + item + '</label>')
        });

        _(all_difficulty).uniq().each(function (item) {
            $(".difficultyContainer").append('<label><input type="checkbox" name="difficulty" value="' + item + '">' + item + '</label>')
        });

        $(document).off("change", "input:checkbox[name=type]");
        $(document).on("change", "input:checkbox[name=type]", updateList);
        $(document).off("change", "input:checkbox[name=name]");
        $(document).on("change", "input:checkbox[name=name]", updateList);
        $(document).off("change", "input:checkbox[name=difficulty]");
        $(document).on("change", "input:checkbox[name=difficulty]", updateList);

我还在 Codepen 上创建了一个工作示例。

http://codepen.io/JasonEspin/pen/bdajKo

我希望实现的是对于某些包,它们可能有多个类型值,例如:

 <div class="package well">
       <div class="name">Niagra Falls</div>
       <div class="type hidden">Boat Trip</div>
       <div class="type hidden">Other trip type</div>
       <div class="difficulty">Relaxed</div>
 </div>

所以在这种情况下,我希望我的过滤器能够检测到有一种类型的乘船旅行和其他旅行类型,并将这些选项显示为过滤器选项。如果选择其中一个,则返回此包。不过,好像忽略了第二种。

我什至试过这样,因为我希望它像数组一样工作,但事实并非如此。它只是将两个项目混合在一起以创建一个随机选项。

 <div class="package well">
       <div class="name">Niagra Falls</div>
       <div class="type hidden"><div>Boat Trip</div><div>Other Trip Type</div> </div>
       <div class="difficulty">Relaxed</div>
 </div>

那么,有没有人知道如何调整我的代码以接受多个选项?我的理想情况是为每个包裹附加多个出发日期,并使用户能够按这些出发日期进行过滤。

任何帮助将不胜感激,因为我认为问题可能出在我的 Lodash 代码上,但由于这是我第一次使用 Lodash,由于其不寻常的语法,我有点不确定它实际上在做什么。

实际上,使用 string.split() 定义和数组连接的组合实现起来相当简单。

HTML

<div id="search-results">
  <div class="col-md-3">
    <div class="panel panel-warning">
      <div class="panel-heading">Filters</div>
      <div class="panel-body">
        <div class="search-filter">
          <ul class="list-group">
            <li class="list-group-item">
              <div class="list-group-item-heading">
                <h4>Filter Options</h4>
              </div>
            </li>
            <li class="list-group-item">
              <div class="nameContainer">
                <h5 class="list-group-item-heading">Name</h5>
              </div>
            </li>
            <li class="list-group-item">
              <div class="typeContainer">
                <h5 class="list-group-item-heading">Type</h5>
              </div>
            </li>
            <li class="list-group-item">
              <div class="difficultyContainer">
                <h5 class="list-group-item-heading">Difficulty</h5>
              </div>
            </li>
            <li class="list-group-item">
              <label>Tour contains</label>
              <input class="search form-control" placeholder="Search" />
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  <div class="col-md-9">
    <div class="panel panel-primary">
      <div class="panel-heading">Results</div>
      <div class="list panel-body">
         <div class="package well">
           <div class="name">Niagra Falls</div>
           <div class="type hidden">Boat Trip|Other Trip|My Trip</div>
           <div class="difficulty">Relaxed</div>
         </div>
        <div class="package well">
           <div class="name">Pyramids</div>
           <div class="type hidden">History Holiday</div>
           <div class="difficulty">Relaxed</div>
         </div>
        <div class="package well">
           <div class="name">Great Barrier Reef</div>
           <div class="type hidden">Snorkling Holiday</div>
           <div class="difficulty">Dangerous</div>
         </div>
        <div class="package well">
           <div class="name">Boar Hunting</div>
           <div class="type hidden">Hunting Trip</div>
           <div class="difficulty">Active</div>
         </div>
        <div class="package well">
           <div class="name">Thames Cruise</div>
           <div class="type hidden">Cruise</div>
           <div class="difficulty">Easy</div>
         </div>
      </div>
      <ul class="pagination"></ul>
    </div>
  </div>
</div>

JAVASCRIPT

var options = {
        valueNames: ['name', 'type', 'difficulty'],
        page: 3,
        plugins: [
           ListPagination({})
        ]
    };
    var userList = new List('search-results', options);
    var updateList = function () {
        var name = new Array();
        var type = new Array();
        var difficulty = new Array();

        $("input:checkbox[name=name]:checked").each(function () {
            name.push($(this).val());
        });

        $("input:checkbox[name=type]:checked").each(function () {
    if($(this).val().indexOf('|') > 0){
       var arr = $(this).val().split('|');
       var arrayLength = arr.length;
       type = type.concat(arr);
       console.log('Multiple values:' + arr);
    }else{
       type.push($(this).val());
       console.log('Single values:' + arr);
    }
        });

        $("input:checkbox[name=difficulty]:checked").each(function () {
            difficulty.push($(this).val());
        });

        var values_type = type.length > 0 ? type : null;
        var values_name = name.length > 0 ? name : null;
        var values_difficulty = difficulty.length > 0 ? difficulty : null;

        userList.filter(function (item) {
    var typeTest;
    var nameTest;
    var difficultyTest;

    if(item.values().type.indexOf('|') > 0){
      var typeArr = item.values().type.split('|');
      for(var i = 0; i < typeArr.length; i++){
         if(_(values_type).contains(typeArr[i])){
            typeTest = true;   
         }
      }
    }

            return (_(values_type).contains(item.values().type) || !values_type || typeTest)
                    && (_(values_name).contains(item.values().name) || !values_name)
                    && (_(values_difficulty).contains(item.values().difficulty) || !values_difficulty)
        });
    }

    userList.on("updated", function () {
        $('.sort').each(function () {
            if ($(this).hasClass("asc")) {
                $(this).find(".fa").addClass("fa-sort-alpha-asc").removeClass("fa-sort-alpha-desc").show();
            } else if ($(this).hasClass("desc")) {
                $(this).find(".fa").addClass("fa-sort-alpha-desc").removeClass("fa-sort-alpha-asc").show();
            } else {
                $(this).find(".fa").hide();
            }
        });
    });

    var all_type = [];
    var all_name = [];
    var all_difficulty = [];

    updateList();

    _(userList.items).each(function (item) {
  if(item.values().type.indexOf('|') > 0){
    var arr = item.values().type.split('|');
    all_type = all_type.concat(arr);
  }else{
    all_type.push(item.values().type)
  }

        all_name.push(item.values().name)
        all_difficulty.push(item.values().difficulty)
    });

    _(all_type).uniq().each(function (item) {
        $(".typeContainer").append('<label><input type="checkbox" name="type" value="' + item + '">' + item + '</label>')
    });

    _(all_name).uniq().each(function (item) {
        $(".nameContainer").append('<label><input type="checkbox" name="name" value="' + item + '">' + item + '</label>')
    });

    _(all_difficulty).uniq().each(function (item) {
        $(".difficultyContainer").append('<label><input type="checkbox" name="difficulty" value="' + item + '">' + item + '</label>')
    });

    $(document).off("change", "input:checkbox[name=type]");
    $(document).on("change", "input:checkbox[name=type]", updateList);
    $(document).off("change", "input:checkbox[name=name]");
    $(document).on("change", "input:checkbox[name=name]", updateList);
    $(document).off("change", "input:checkbox[name=difficulty]");
    $(document).on("change", "input:checkbox[name=difficulty]", updateList);

代码笔

http://codepen.io/JasonEspin/pen/bdajKo