views:

39

answers:

4

I have this need to show and hide a div if a checkbox is checked for multiple checkboxes.

Each div's id that needs to be shown will be the same as the checkboxes name. Is there an easy way to accomplish this without writing a function to handle each checkbox?

    $('input[name=checkbox_1]').click(function() {
        if ($('input[name=checkbox_1]').is(':checked')) {
            $('#checkbox_1').show('slow');
        }

        else {
            $('#checkbox_1').hide('slow');
        }
     });
     $('input[name=checkbox_2]').click(function() {
                   if ($('input[name=checkbox_2]').is(':checked')) {
            $('#checkbox_2').show('slow');
        }

        else {
            $('#checkbox_2').hide('slow');
        }
    });

  });
+1  A: 

You can get the ID from the name, like this:

$('input[name^=checkbox_]').click(function() {
  $('#' + this.name)[this.checked ? 'show' : 'hide']('slow');
});

This uses the attribute-starts-with selector to get the inputs, then uses their .name property to get the appropriate element by ID. If it's checked, runs .show('slow'), otherwise .hide('slow') on the element with that ID.

Nick Craver
+1  A: 
$('input[name^=checkbox]').click(function() {
    if(this.checked){
       $('#' + this.name).show('slow');
    } else{
       $('#' + this.name).hide('slow');
    }

}

Edit: Using the 'starts with' selector would be better than checking the indexOf, like others said

a.feng
There is rarely if ever a need for `$(this).is(':checked')` inside a checkbox handler, `this.checked` is much simpler/faster all around :)
Nick Craver
Good call. I'll change that in the solution -- thank you!
a.feng
@afeng - It's `this.checked` :), `$(this).checked` will always be false, it's not a property on a jQuery object, but rather a DOM element property.
Nick Craver
Ah, I see. Thanks again, haha.
a.feng
A: 

You can use toggle() instead of if ... else here to further reduce code:

('input[name^=checkbox_]').click(function(){
    $('#' + this.name).toggle('slow')
});

Toggle can also run different functions on alternate clicks instead of just hiding/showing elements:

('input[name^=checkbox_]').toggle(function(){
    $('#' + this.name).hide('slow')
}, function(){
    $('#' + this.name).show('slow')
    } );
Just Jake
I'll say from experience `.toggle()` (the handler) is not the way to go 99% of the time...what if the checkbox is checked initially? What if it's reversed? While `.toggle()` (the hide/show shortcut) "shortens" things, it's not the same effect, doing `hide` or `show` explicitly ensures that the state of the element is the same as the state of the checkbox. If a user for example clicks the checkbox before the DOM is ready, then this hasn't executed and the state is reverse of what it should be. Or, again, what if the checkbox is already checked and your out of sync initially?
Nick Craver
Then it isn't the solution for him ;)
Just Jake
A: 

It looks like you have some type of naming convention going on. You can just reach into the current context object, get the name and work your convention. You might want to give your checkbox fields some special css class to make for easy selection:

$('input.someCssClass').click(function() {

    var selector = '#' + $(this).attr('name');

    if ($(this).is(':checked'))
        $(selector).show('slow');
    else
        $(selector).hide('slow');
});
AndrewDotHay
This worked great! This site always amazes me.
Taylor