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>
."