Фильтрация свойства с несколькими значениями для одного поля - List.js и 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, я немного не уверен в том, что он делает на самом деле из-за его необычного синтаксиса.

1 ответ

Решение

На самом деле это было довольно просто реализовать, используя комбинацию определений 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

Другие вопросы по тегам