jQuery多重选择器过滤器

时间:2019-01-30 22:58:15

标签: javascript jquery

我有一个所需的有效代码示例,但需要一些改进。

$("#filtroSolicitacoes").on("submit", function(){
    
    $("#solicitacoes div").show();
    
    var filter = "";
    
    $(this).find("[data-form]").each(function(){
    
        if( $(this).val() != "" ) filter += ("[" + $(this).attr("data-form") + "='" + $(this).val() + "']");
    
    });
    
    if(filter.length > 0) $("#solicitacoes div").not(filter).hide();

    return false;

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="filtros">
    <form id="filtroSolicitacoes" type="post" name="filtroSolicitacoes">
        Protocolo: <input data-form="id" type="text" name="filtroProtocolo" id="filtroProtocolo" size="5"/>
        Solicitante: <input data-form="title" type="text" name="filtroSolicitante" id="filtroSolicitante" size="10"/>
        Status: 
        <select data-form="status" name="filtroStatus" id="filtroStatus">
        <option value="">-- Selecione Status--</option>
        <option value="3">Aguardando Aprova&ccedil;&atilde;o</option>
        <option value="18">Encaminhado</option>
        <option value="2">Iniciado</option>
        <option value="1">N&atilde;o Iniciado</option>
        <option value="4">Pendente de Esclarecimento</option>
        <option value="16">Reiniciado</option>
        <option value="6">Reprovado</option>
        </select>
        Analista: 
        <select data-form="analista" name="filtroAnalista" id="filtroAnalista">
            <option value="">-- Selecione Analista--</option>
            <option value="23">Robert</option>
            <option value="46">Allan</option>
            <option value="49">Edward</option>
            <option value="32">Jake</option>
            <option value="14">Stella</option>
        </select>
        <button type="submit" id="filtrar" style="float:right; margin-right:10px">:: Filtrar ::</button>
    </form>
</div>
<div id="solicitacoes">
    <div id='1' title='Mike' status='18' analista='23'>Whatever content 1</div>
    <div id='2' title='John' status='16' analista='46'>Whatever content 2</div>
    <div id='3' title='Tom' status='2' analista='49'>Whatever content 3</div>
    <div id='4' title='Mike' status='4' analista='23'>Whatever content 4</div>
    <div id='5' title='Kate' status='3' analista='32'>Whatever content 5</div>
    <div id='6' title='Steve' status='1' analista='14'>Whatever content 6</div>
</div>

可过滤项具有单个属性:

<div id='6' title='Steve' status='1' analista='14'>Whatever content 6</div>

此处status ='1'属性只能具有一个值(在这种情况下为1)。我需要能够在一个属性中添加多个值,如下所示:

<div id='6' title='Steve' status='1 2' analista='14 15'>Whatever content 6</div>

具有相应值的项目必须在过滤后显示。

很遗憾,我的知识不承认我对此有所改善,我们非常感谢您的帮助。

谢谢!

1 个答案:

答案 0 :(得分:0)

您的主要问题在于如何构造过滤器:

if( $(this).val() != "" )
    filter += ("[" + $(this).attr("data-form") + "='" + $(this).val() + "']");

这意味着您只能选择完全匹配该值的属性,因此,如果在属性中使用空格分隔值,例如analista='14 15',过滤器[analista='14'][analista='15']将永远不匹配。当然,可能会发现使用*=比较器的简单方法,但这是非常不可靠的,因为这意味着[analista*='14']将匹配包含analista="14 15"以及{{1}的任何元素}。

我提出的解决方案将略微重写您的过滤逻辑,所以请分步执行:

  1. 请记住对非标准属性使用analista="140000"属性,即可以保留data-id,但可以使用titledata-status而不是{ {1}}和data-analista
  2. 在您的JS中,我们可以缓存status集合以提高性能。
  3. 我们没有创建串联的字符串analista,而是简单地创建了一个空对象。它将用作字典,其中包含存储为键的属性,并将输入字段值作为值。
  4. 创建该词典后,我们使用$("#solicitacoes").find("div")语法来遍历词典中的所有键。
    • 在每次迭代中,我们都可以访问我们要过滤的属性和我们感兴趣的值。这就是您对字典的 entry
    • 有了这个,您可以遍历filter的缓存集合。我们要访问感兴趣的属性的值,然后用空格字符分割/分解字符串,因此例如,for (var x in ...)将转换为$("#solicitacoes").find("div")的数组。
    • 检查数组是否包含字典条目中的值

请参阅下面的概念验证:我在第一个data-analista="14 15"处添加了其他用空格分隔的值,以说明该示例。

[14, 15]
<div>


如果您使用的是ES6,则奖励:可以使一切变得更简单。这是当您意识到实际上一直不需要jQuery时;)

$("#filtroSolicitacoes").on("submit", function() {
  // Cache collection
  var $divsToFilter = $("#solicitacoes").find("div");
  
  $divsToFilter.show();

  var dictionary = {};

  $(this).find("[data-form]").each(function() {
    if (this.value)
      dictionary[$(this).attr('data-form')] = this.value;
  });

  // Loop through the dictionary to access individual entries
  for (var key in dictionary) {
  
    // We have the key, use it to get the value
    var value = dictionary[key];
    
    // Filter the divs
    $divsToFilter.filter(function() {
    
      // Explode/split all space-separate values stored in attribute into an array
      var dataValues = $(this).attr(key);
      
      // Check if our dictioanry entry's value matches any in the array
      // If it is missing, we want to keep it in the filter so that we can hide it
      return dataValues.indexOf(value) === -1;
      
    }).hide();
  }

  return false;

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="filtros">
  <form id="filtroSolicitacoes" type="post" name="filtroSolicitacoes">
    Protocolo: <input data-form="id" type="text" name="filtroProtocolo" id="filtroProtocolo" size="5" /> Solicitante: <input data-form="title" type="text" name="filtroSolicitante" id="filtroSolicitante" size="10" /> Status:
    <select data-form="data-status" name="filtroStatus" id="filtroStatus">
      <option value="">-- Selecione Status--</option>
      <option value="3">Aguardando Aprova&ccedil;&atilde;o</option>
      <option value="18">Encaminhado</option>
      <option value="2">Iniciado</option>
      <option value="1">N&atilde;o Iniciado</option>
      <option value="4">Pendente de Esclarecimento</option>
      <option value="16">Reiniciado</option>
      <option value="6">Reprovado</option>
    </select>
    Analista:
    <select data-form="data-analista" name="filtroAnalista" id="filtroAnalista">
      <option value="">-- Selecione Analista--</option>
      <option value="23">Robert</option>
      <option value="46">Allan</option>
      <option value="49">Edward</option>
      <option value="32">Jake</option>
      <option value="14">Stella</option>
    </select>
    <button type="submit" id="filtrar" style="float:right; margin-right:10px">:: Filtrar ::</button>
  </form>
</div>
<div id="solicitacoes">
  <div id='1' title='Mike' data-status='18 16 2' data-analista='23 46 49'>Whatever content 1</div>
  <div id='2' title='John' data-status='16' data-analista='46'>Whatever content 2</div>
  <div id='3' title='Tom' data-status='2' data-analista='49'>Whatever content 3</div>
  <div id='4' title='Mike' data-status='4' data-analista='23'>Whatever content 4</div>
  <div id='5' title='Kate' data-status='3' data-analista='32'>Whatever content 5</div>
  <div id='6' title='Steve' data-status='1' data-analista='14'>Whatever content 6</div>
</div>