Multiple filters with Jquery

22,169

Solution 1

You should use the filter() function:

var filteredList = elements
                      .filter("[status=status1]")
                      .filter("[title*=something]");
// and so on

In your example:

$("#filtroSolicitacoes").submit(function() {
    $("#solicitacoes > div").show();
    var filtroProtocolo = $("#filtroProtocolo").val();
    var filtroSolicitante = $("#filtroSolicitante").val().toUpperCase();
    var filtroStatus = $("#filtroStatus").val();
    var filtroAnalista = $("#filtroAnalista").val();
    var filtroResultado = $("#filtroResultado:checked").length;

    var elements = $("[id=filtros]");

    if(filtroStatus !== "0"){
        elements = elements.filter("[status='"+filtroStatus+"']");
    }
    if(filtroProtocolo !== ""){
        elements = elements.filter("[id='"+filtroProtocolo+"']");
    }

    // and so on

    $("#solicitatcoes > div").not(elements).hide();

    return false;
});

Solution 2

Just remove the commas.

So instead of:

filtros +=",[status='"+filtroStatus+"']";

Use

filtros +="[status='"+filtroStatus+"']";

You want your resulting query to look like this:

"[status=status][title*='whatever']"

Also, the way you are calling it isn't filtering it correctly. This is how I would change your function to make it work (You can view a working demo of your code, and play with it.):

$("#filtroSolicitacoes").submit(function() {
    var filtroProtocolo = $("#filtroProtocolo").val();
    var filtroSolicitante = $("#filtroSolicitante").val().toUpperCase();
    var filtroStatus = $("#filtroStatus").val();
    var filtroAnalista = $("#filtroAnalista").val();
    var filtroResultado = $("#filtroResultado:checked").length;

    var filtros = "";

    if(filtroStatus !== "0"){
        filtros +="[status='"+filtroStatus+"']";
    }
    if(filtroProtocolo !== ""){
        filtros +="[id='"+filtroProtocolo+"']";
    }
    if(filtroSolicitante !== ""){
        filtros +="[title*='"+filtroSolicitante+"']";
    }
    if(filtroAnalista !== "0"){
        filtros +="[analista='"+filtroAnalista+"']";
    }

    if(filtros !== ""){
        $("#solicitacoes > div").hide().filter(filtros).show();
    } else {
        $("#solicitacoes > div").show();
    }
    return false;
});

Solution 3

Put the name of the attribute on each element and the solution will be more dynamic, it only needs the "data-form" attribute to select the correct elements:

$("#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;

});

jsfiddle

Share:
22,169
Admin
Author by

Admin

Updated on December 01, 2020

Comments

  • Admin
    Admin over 3 years

    I have some div´s in my page (build with php+jquery) and I want to filter them according to their attributes (if there´s more than 1 attribute filtering, than it will narrow down the search). The div´s look like this:

    <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>
    

    Then, I have a form to filter the div´s attributes:

    <div id="filtros">
    <form id="filtroSolicitacoes" type="post" name="filtroSolicitacoes">
    Protocolo: <input type="text" name="filtroProtocolo" id="filtroProtocolo" size="5"/>
    Solicitante: <input type="text" name="filtroSolicitante" id="filtroSolicitante" size="10"/>
    Status: 
    <select name="filtroStatus" id="filtroStatus">
    <option value="0">-- 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 name="filtroAnalista" id="filtroAnalista">
        <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>
    

    Now, I´ve alredy done most of the Jquery part and the filter is working ---> But I want to NARROW DOWN the search if there´s more than 1 filtering attribute, NOT to concatenate it, and that´s what´s happening with my code bellow:

    $("#filtroSolicitacoes").submit(function() {
        $("#solicitacoes > div").show();
        var filtroProtocolo = $("#filtroProtocolo").val();
        var filtroSolicitante = $("#filtroSolicitante").val().toUpperCase();
        var filtroStatus = $("#filtroStatus").val();
        var filtroAnalista = $("#filtroAnalista").val();
        var filtroResultado = $("#filtroResultado:checked").length;
    
        var filtros = "[id=filtros]";
    
        if(filtroStatus !== "0"){
            filtros +=",[status='"+filtroStatus+"']";
        }
        if(filtroProtocolo !== ""){
            filtros +=",[id='"+filtroProtocolo+"']";
        }
        if(filtroSolicitante !== ""){
            filtros +=",[title*='"+filtroSolicitante+"']";
        }
        if(filtroAnalista !== "0"){
            filtros +=",[analista='"+filtroAnalista+"']";
        }
    
        if(filtros !== "[id=filtros]"){
            $("#solicitacoes > div:not("+filtros+")").hide();
        }
        return false;
    });
    

    I´ve tried to use "&&" instead of "," in

    filtros +=",[analista='"+filtroAnalista+"']";
    

    But it didn´t work.

    any ideas?

    PS: Sorry for my poor English, I´m brazilian :)