2015-06-29 4 views
1

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

ответ

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