jQuery in Action
Putting events (and more) to work
117
a listener for a click event on the check boxes in which we can adjust the visibility
of the options based upon the state of the check box. Let's look at the following
statement, which establishes this listener:
of the options based upon the state of the check box. Let's look at the following
statement, which establishes this listener:
$(':checkbox').click(function(){
var checked = this.checked;
$('div',$(this).parents('div:first'))
.css('display',checked ? 'block':'none');
$('input[type=text]',$(this).parents('div:first'))
.attr('disabled',!checked)
.css('color',checked ? 'black' : '#f0f0f0')
.val(1)
.change()
.each(function(){ if (checked) this.focus();});
});
All that just to hide and show a
<div>
?
Well, no. Hiding and showing the options is just one of the things that we need
to do when the state of one of the check boxes changes. Let's look at each step in
this fragment to see what it does for us.
this fragment to see what it does for us.
First, the click handler stores the checked state of the check box in a variable
named
checked
. This makes for easy reference in the code, and it establishes a
local variable that we can use in any closures that we create.
Next, the handler locates the
<div>
containing the appetizer options and sets
its
CSS
display
value to hide those options when the check box is unchecked or to
show them when the check box is checked. The jQuery expression that we use
to locate the element to be shown or hidden is
to locate the element to be shown or hidden is
$('div',$(this).parents('div:
first'))
, which equates to "find the
<div>
elements in the first ancestor element
of
this
that is a
<div>
." Because we know from our
HTML
structure that there will
be only one match, we don't need to differentiate any further.
Being astute, you'll have noted that, because we know the initial state of the
check box is unchecked and the options are hidden, we could have written less
code by using the
code by using the
toggle()
command without needing to query the state of the
check box. That type of assumptive code can be fragile and break easily when its
assumptions change, so it's generally better to make explicitly certain that the vis-
ibility of our options matches the state of their respective check boxes.
assumptions change, so it's generally better to make explicitly certain that the vis-
ibility of our options matches the state of their respective check boxes.
Our handler isn't done yet; it still needs to adjust the state of the quantity text
boxes. These boxes are initially disabled and will only be enabled when an appe-
tizer is checked. We locate the text box with
tizer is checked. We locate the text box with
$('input[type=text]',$(this)
.parents('div:first'))
, a similar selector to the one we just employed that says
"locate the
<input>
element of type text in my first parent
<div>
."