Intelligent Select Box Filtering

One of the great things about building websites for a living is the challenges tend to change from day to day. There’s always a new puzzle to solve.

Join us in our newest publication:

Take today, for example. I was building a page that contained a series of select (dropdown) boxes. Now, I’ve been around the block once or twice before, and this wasn’t my first time using selects. However, this implementation came with a unique twist: all the boxes contained the exact same options, but we only wanted each to be selectable once. Specifically, each box contained a list of security questions — your mom’s best friend’s grandmother’s maiden name, that sort of thing.

The code looks something like this:

<select class="security" name="security1">
	<option value="0">Select a question.</option>
	<option value="1">Who's your daddy?</option>
	<option value="2">What's your favorite color?</option>
	<option value="3">What time is it?</option>
</select>
<select class="security" name="security2">
	<option value="0">Select a question.</option>
	<option value="1">Who's your daddy?</option>
	<option value="2">What's your favorite color?</option>
	<option value="3">What time is it?</option>
</select>

Now, naturally, we want the user to select several different security questions. But what’s to stop them from selecting the same question several times? Well, in our case, back-end validation… but I wanted to solve the problem before we got to that point. I wanted to eliminate “selected” questions from all the other dropdown boxes, so it wouldn’t even be an option. This has the added benefit of shortening the list of options as the user goes along, which would make scanning the options easier.

After a bit of playing, I came up with the following jQuery script which seems to do the trick:

$(function () {
  $('.security').change(function () {
    $('.security option').show(0);
    $('.security option:selected').each(function () {
      oIndex = $(this).index();
      if (oIndex > 0) {
        $('.security').each(function () {
          $(this).children('option').eq(oIndex).not(':selected').hide(0);
        });
      }
    });
  });
  $('.security').change();
});

I’ll walk you through what I’m doing here.

First, we’re setting the script to fire whenever the “security” select boxes are changed. In other words, whenever someone makes a new selection in one of our dropdowns.

When a selection is made, the first thing we do is re-display any previously hidden options, to put us back on even footing. Then we loop through each of the selected options in our select boxes. If the first item isn’t selected, we’ll proceed. (In our use-case, the first option was a generic “make a selection” option, so I didn’t want it to count as a question).

Once we know a true question has been selected, we’ll loop through all our select boxes. We’re making heavy use of the jQuery .index() and .eq() functions here. Both functions use the idea of zero-based array indexing to number all of our elements; the fifth option in a dropdown would have an index of 4, the third dropdown with a class of “security” would have an index of 2, and so on. The .index() function lets us grab the index number of any item we already have, and the .eq() function lets us specify which new element we want to grab.

So first up, we grab the index value of the currently selected option. Since all of our questions are in the same order in each dropdown, those questions have the same indexes across the board. Then we loop through each of our select boxes. If the option is not currently selected in that dropdown, we hide it – in other words, the only dropdown that will still contain that question is the one in which it was already selected.

And then, at the very end, we fire our change function. The first time our page loads, that won’t do much. But if anyone refreshes the browser window, the browser will save their select options… which means we need to filter them right when the page loads. Otherwise, all of our questions would be visible again whenever the page reloaded.

I put together a demo here. Take a look!

Share and Enjoy !

0Shares
0 0