Search code examples
jqueryradio-button

Filter by multiple classes with radio buttons and jquery


I'm trying to create a filter using radio buttons and jquery.

I have a list of items like the following:

<ul class="all-options">
    <li class="1 a">
        <img src="path/to/image"/>
        <h3>Price</h3>
        <h2>$1000</h2>
    </li>
    <li class="1 b">
        <img src="path/to/image"/>
        <h3>Price</h3>
        <h2>$1500</h2>
    </li>
    <li class="2 a">
        <img src="path/to/image"/>
        <h3>Price</h3>
        <h2>$1200</h2>
    </li>
    <li class="2 b">
        <img src="path/to/image"/>
        <h3>Price</h3>
        <h2>$1300</h2>
    </li>
</ul>

I want to view just ONE item at a time, based on the user's selection from the following radio buttons:

<label>Numbers</label><br/>
    <input type="radio" name="number" value="1">1<br/>
    <input type="radio" name="number" value="2">2<br/>
<label>Letters</label><br/>
    <input type="radio" name="letter" value="a">a<br/>
    <input type="radio" name="letter" value="b">b

So, in order for one item to be shown, I know that BOTH classes would have to match the selection of the radio buttons. I'm very new to jquery though, so I'm hoping someone can point me in the right direction.


Solution

  • This may not be the most efficient way, but it is the first thing that comes to my mind, and it works:

    Assuming you have a filter button with id="apply"...

    $("#apply").click(function (e) {
        e.preventDefault();
        var number = $("[name='number']:checked").val();
        var letter = $("[name='letter']:checked").val();
        $("li").hide();
        $("li[class='" + number + " " + letter + "']").show();
    });
    

    Here is a working example


    Better Version

    As the above will fail if your li elements have any other classes, here is an alternative approach using JQuery's filter method:

    $("#apply").click(function (e) {
        e.preventDefault();
        var number = $("[name='number']:checked").val();
        var letter = $("[name='letter']:checked").val();
        $("li").hide();
        $("li").filter(function (index) {
            return $(this).hasClass(number) && $(this).hasClass(letter);
        }).show();
    });
    

    Here is a working example


    You can apply this logic to any event, such as change for the radio buttons...

    $("input[type='radio']").change(function () {
        var number = $("[name='number']:checked").val();
        var letter = $("[name='letter']:checked").val();
        //check if both radios have selected values before proceeding
        if (!number || !letter) return;
        $("li").hide();
        $("li").filter(function (index) {
            return $(this).hasClass(number) && $(this).hasClass(letter);
        }).show();
    });
    

    Here is a working example

    Of course, if any of your numbers are 0 then they will not pass the value check as it stands.