21

I have two functions.

The first function translates a div click into a checked/unchecked toggle. The second function translates a checkbox change into a hide/show event.

The problem is that when I use the first function to check/uncheck the box, the second function is not called. I am new to javascript, thanks.

<script type="text/javascript">
$(document).ready(function() {
    $(":checkbox").parent().click(function(evt) {
        if (evt.target.type !== 'checkbox') {
            var $checkbox = $(":checkbox", this);
            $checkbox.attr('checked', !$checkbox.attr('checked'));
            evt.stopPropagation();
            return false;
        }
    });
});
</script>

<script type="text/javascript">
$(document).ready(function() {
    $(":checkbox").change(function() {
        if($(this).attr("checked")) {
            $('.'+this.id).show();
        }
        else {
            $('.'+this.id).hide();
        }
    });
});
</script>
sxv
  • 275
  • 1
  • 3
  • 7

3 Answers3

33

The change event does not fire when you programmatically change the value of a check box. What you can do to ensure it fires is:

 $(":checkbox").parent().click(function(evt) {
    if (evt.target.type !== 'checkbox') {
        var $checkbox = $(":checkbox", this);
        $checkbox.attr('checked', !$checkbox.attr('checked'));
        $checkbox.change();
    }
});
Matthew Manela
  • 16,572
  • 3
  • 64
  • 66
  • Your theory checks out and your solution works perfectly. Thanks. – sxv Feb 02 '11 at 09:09
  • 1
    Better to use (at least with some versions of jQuery) `$.fn.prop` vs `$.fn.attr`. Attr will assign as well as retrieve. Prop just retrieves. – dgo Apr 10 '15 at 16:36
5

Don't bother with the first snippet. Just use LABEL elements:

<label><input type="checkbox">Some option</label>

Now, when the user clicks the label (the text next to the checkbox), the checkbox will be activated.


The second snippet can be optimized:

$('input:checkbox').change(function() {
    $('#' + this.id).toggle(this.checked);
});
skeggse
  • 6,103
  • 11
  • 57
  • 81
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • the $('.' + this.id) selector wont work. Need to use '#'. And we dont know whats in the div, you are assuming he is using it as a label, it might be something else. – Victor Feb 02 '11 at 01:57
1

you are using '.' which is for class selectors instead use '#' since you are using the element ID. Like this:

$(document).ready(function() {
    $(":checkbox").bind('change', function() {
        if($(this).attr("checked")) {
            $('#'+this.id).show();
        }
        else {
            $('#'+this.id).hide();
        }
    });
});
Victor
  • 4,721
  • 1
  • 26
  • 31
  • the OP did that on purpose.. ;) he's not hiding/showing the checkboxes but the `
    ` with a class equivalent to the id of the checkbox.
    – Reigel Gallarde Feb 02 '11 at 01:56
  • @Victor That wouldn't make sense, since the check-box is the element that got that ID. – Šime Vidas Feb 02 '11 at 01:58
  • @Sime I dont try to make sense of what they are trying to do. If thats the case it was unclear. – Victor Feb 02 '11 at 02:02
  • @Reigel Fair enough, but without the markup your guess is just as good as mine. But i guess it makes sense. – Victor Feb 02 '11 at 02:02
  • 1
    @Victor So when the visitor checks the check-box it should become visible? But it already was visible, otherwise the visitor couldn't have checked it. That does not make sense. – Šime Vidas Feb 02 '11 at 02:06
  • @Sime I agree it doesnt make sense. I have seen weirder things. I guess we'll just have to wait for the OP to see what he is trying to do. – Victor Feb 02 '11 at 02:10