使用一个字段的多个值过滤属性 - List.js和Filter.js

时间:2015-06-29 16:04:32

标签: javascript jquery lodash listjs

我目前正在使用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>

所以在这种情况下,我希望我的过滤器检测到有一种Boat Trip和Other trip类型,并将这些选项显示为过滤选项。如果选择其中任何一个,则返回此包。但是,它似乎忽略了第二种类型。

我甚至尝试过这样的操作,因为我预计它会像一个阵列一样,但事实并非如此。它只是将两个项目混合在一起以创建一个随机选项。

 <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,由于其不寻常的语法,我有点不确定它实际上在做什么。

1 个答案:

答案 0 :(得分:0)

使用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);

Codepen

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