A better way to show and hide things with jQuery
Earlier today a friend asked me if I knew of a slick plugin for jQuery that makes it easy to show and hide form fields based on the selected value in a <select> box. Unfortunately, I don't — I've always just done stuff like that manually. And that definitely starts to get hairy with large complex forms where you want to show and hide different combinations of fields.
A light bulb went off in my head though, and I quickly put together this example for him. Using a combination of jQuery and some cleverly placed CSS class names, you can very easily find the elements you want to show, and from there it's cake.
So what I've put together here is a form with a select box, and each option has a value from 0 to 4. The form also contains 5 paragraphs (could just as easily be table rows, divs, fieldsets, or a plethora of other things), with class names like "show0" and "show3" — indicating which status of the drop-down they should be displayed for. Luckily for us, you can assign multiple classes to an object which makes it insanely simple to setup different combinations of visible elements.
In the example below, only a single paragraph is displayed for options 0, 1, and 4 — but for options 2 and 3, two different paragraphs are shown. Selecting option 3 shows paragraphs 2 and 3 because they both have the class "show3", while selecting option 2 only shows paragraph 2 because while it does have the class "show2" none of the other paragraphs do.
Update: Thanks to Charlie Griefer for reminding me of some of the root functionality of jQuery that I mistakenly left out of this example. I'm updating my example according to his comments.
Here's a working demo for you.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#mySelect').change(function() {
$("#formContainer p:not('.alwaysShow')").hide();
$("#formContainer .show" + $('#mySelect').val()).show();
});
//optional:
$('#mySelect').change(); // simulate a change event to trigger the above
});
</script>
<div id="formContainer">
<form>
<p class="alwaysShow">
<select id="mySelect">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</p>
<p class="show0">I am displayed for option 0</p>
<p class="show1">I am displayed for option 1</p>
<p class="show2 show3">I am displayed for option 2 and option 3</p>
<p class="show3 show4">I am displayed for option 3 and option 4</p>
<p class="show4">I am displayed for option 4</p>
</form>
</div>
Posted in JavaScript | jQuery | 5 Responses
Also, the days of selectBox.options[selectBox.selectedIndex].value are long gone. Assuming the selectbox has an ID of "mySelect" (yes, I know... how original), you can just do $('#mySelect').val().
And... (last one, I promise), instead of that 2nd find(), you can construct a selector like "selector1 selector2" which means "selector2 is a descendent of selector1" (as opposed to "selector1 > selector2", which looks for selector2 to be a direct child of selector1).
You can lose the first find() as well by constructing a specific enough selector. I'm guessing that using the appropriate selector will perform better than a find() (but I have no data to back that up) :)
Something like this...
http://pastebin.com/m46a07817 (that'll be there for a month) :)
I've never tried the "assigning multiple classes to one element trick" before so thanks for posting this - that's pretty cool. One way that you can probably simplify this slightly is by using the toggle effect in your jQuery code. It automatically uses show if an element is hidden or hide if an element is displayed. This was the very first thing that I ever tried with jQuery and if you want a very quick example of it you can look here...
http://www.cfpadawan.com/index.cfm/2009/9/16/My-first-foray-into-the-world-of-jQuery
I've been playing around a lot with jQuery last few months, figured I'd share some of the jQuery goodness that I've picked up.