Filtering between range of two dropdown field values with jQuery


#1

I have two drop down menus (min age and max age). I can filter on both them but individually but what I want to be able to do is only show the divs whose data-age attribute is equal or within the range of both values (21 to 26 for example would return 22 etc but not 20 or 27).

Code for existing filter:

                     <div class="col-xs-6">
                        <div class="form-group">
                            <label class="filter-col" style="margin-right:0;" for="pref-perpage">Min Age</label>
                            <select id="age-min" class="form-control">
                                <option value="18">18</option>
                                <option value="19">19</option>
                                <option value="20">20</option>
                                <option value="21">21</option>
                            </select>                                
                        </div> <!-- form group [rows] -->
                        </div>

                        <div class="col-xs-6">
                        <div class="form-group">
                            <label class="filter-col" style="margin-right:0;" for="pref-perpage">Max Age</label>
                            <select id="age-max" class="form-control">
                                <option value="18">18</option>
                                <option value="19">19</option>
                                <option value="20">20</option>
                                <option value="21">21</option>
                            </select>                                
                        </div> <!-- form group [rows] -->
                        </div>

                        <script type="text/javascript">
                          $("#age-min").change(function(){
                              if (this.value === 'all') {
                                $("div[data-age]").show();
                              } else {
                                $("div[data-age]").hide();
                                $("div[data-age=" + this.value +"]").show();
                              }
                            });
                        </script>

#2

i wouldn't use change event here, i would add a button and then a click event to button. This way, the user can submit whenever they like.

hide and show only works when the elements already exist on the page, which doesn't seem to be the case with the code you included

create a div, so we can .append() our data-age divs to it, and we can clear the div when the user submits for a second time


#3

Apologies I should have explained in my original post - the fields are filtering a bunch of divs on the same page that contain a matching attribute - in this case data-age the location field I am using to filter based on location looks for data-town.


#4

please include this code, otherwise helping becomes really difficult


#5

The only code I've not included is the following.

The javascript in my OP filters based on the data attributes.

<div class="col-xs-6">
    <div class="form-group">
        <label class="filter-col" style="margin-right:0;" for="pref-perpage">Min Age</label>
        <select id="age-min" class="form-control">
                                <option value="18">18</option>
                                <option value="19">19</option>
                                <option value="20">20</option>
                                <option value="21">21</option>
                            </select>
    </div>
    <!-- form group [rows] -->
</div>

<div class="col-xs-6">
    <div class="form-group">
        <label class="filter-col" style="margin-right:0;" for="pref-perpage">Max Age</label>
        <select id="age-max" class="form-control">
                                <option value="18">18</option>
                                <option value="19">19</option>
                                <option value="20">20</option>
                                <option value="21">21</option>
                            </select>
    </div>
    <!-- form group [rows] -->
</div>

<script type="text/javascript">
    $("#age-min").change(function() {
        if (this.value === 'all') {
            $("div[data-age]").show();
        } else {
            $("div[data-age]").hide();
            $("div[data-age=" + this.value + "]").show();
        }
    });
</script>

<div class="box" data-town="all Manchester" data-age="20">
Div content here
</div>

<div class="box" data-town="all Birmingham" data-age="25">
Div content here
</div>

#6

please explain your logic here:

if (this.value === 'all')

this.value will be an integer, how will that ever equal a string "all"?

given you want all the values in a given range, seems you need a loop. I experimented here, see what you think of it, i placed the trigger event on button, i dislike the change event for this. You can easily change it back


#7

Thanks for that - it works perfectly.

Just updated the code slightly to include the all in the data attributes.

All is also set in the divs data attributes so that all div elements are shown if the user selects the default value again after having filtered the divs before. The age fields used to have 'Select min age' as a default option.

I have other filters - location for example - and i had an issue where it wasn't possible to get back to all results so built that in.


#8

so all good now?

shame people never answer your question when you help them further, because they got the working code


#9

I just did - see above (https://discuss.codecademy.com/t/filtering-between-range-of-two-dropdown-field-values-with-jquery/109944/7?u=benyates1)

I said it worked perfectly AND explained what the all referred to.


#10

did this work? So far you gave me insight in your code, this.value is always an integer, so will never equal a string of "all", or just seeing it

Good you understand it all :slight_smile:


#11

Not in relation to the age filters - I should have removed the all conditions. It was left over fro the location filter I also have set up, for clarity I've copied that code below too.

<select id="town-select" class="soflow">
        <option value="all">Select your location...</option>
        <?php foreach(get_alllocations() as $locationlist): ?>
          <option value="<?php echo htmlentities($locationlist['city'], ENT_QUOTES, 'UTF-8'); ?>"><?php echo htmlentities($locationlist['city'], ENT_QUOTES, 'UTF-8'); ?></option>
        <?php endforeach; ?> 
      </select>

    <script type="text/javascript">
      $("#town-select").change(function(){
        if (this.value === 'all') {
          $("div[data-town]").show();
        } else {
          $("div[data-town]").hide();
          $("div[data-town=" + this.value +"]").show();
        }
      });
    </script>

<div class="box" data-town="all Manchester" data-age="20">
Div content here
</div>

<div class="box" data-town="all Birmingham" data-age="25">
Div content here
</div>

Yes, it did work. If for some reason the default value was selected again - all the divs would display until another value was selected.


#12

yea, this will work, given you have an option field with value "all".

$("div[data-town]") will select all divs which have attribute of data-town, so yea, that will work perfectly :slight_smile:

the age needed different code (the on i wrote) given you are dealing with a range, which is not the case for cities


#13

Yes, thanks, that was the logic I was looking for. I could get it to display results that matched exactly the age but not ones included between the two values.

The plan is chain the filters eventually so that if a location is selected, the age range is only taken from the already filtered divs. But that is for another day :slight_smile:


#14

@stetim94 thinking about a little - I have decided to go with a button rather than the change event but is there a quick and easy function that can clear the filters (like a reset button) that I can include too.


#15

simply use hide like i did in the bin:

$('.box').hide();

? or is that not good enough?:


#16

Wouldn't that hide the divs?

I was asking about another button that would clear the filters applied and show all the divs again without having to refresh the page.


#17

you can make a separate button, that is fine. You should be able to handle this?

just give the buttons a name or id so you can separate the buttons when clicked


#18

Cool, yes I can. But would the code be $('.box').show();?


#19

that should do the trick :slight_smile:


#20

Thanks for your help :thumbsup: