Reputation: 15
So I'm trying to use jquery to detect when a checkbox has been checked and unchecked (by clicking the label I should add) to change a css attribute.
Here's an example of the code for the checkbox:
<div class="block" id="block_1">
<input type="checkbox" name="images" id="image_1" class="block_input" />
<label for="image_1" class="block_button" style="background-image:url(img/bnw/block_1bnw.png);">
<span>Label text</span></label>
</div>
and here is the jQuery I have so far that only half works:
$('.block_button').click(function(){
var imgId = $(this).parent().attr('id');
if ($(this).siblings('.block_input').checked == true) {
$(this).css("background-image", "url(img/color/" + imgId + ".png)");
} else {
$(this).css("background-image", "url(img/bnw/" + imgId + "bnw.png)");
}
});
The css changes correctly when you check the box initially, but once it's unchecked nothing changes. I've tried logging the result of the .checked method on click and it seems to stay true even when you uncheck. So how do I get the else statement to work once the user decides to uncheck the box?
Thanks!!
Upvotes: 0
Views: 296
Reputation: 128
A JQuery object has no property "checked" so it will never evaluate to true.
To access the property of an HTML element through its corresponding JQuery object, you have to use the .prop() method. Or, in other words...
$('.block_button').click(function(){
var imgId = $(this).parent().attr('id');
if (! $(this).siblings('.block_input').prop('checked')) {
$(this).css("background-image", "url(img/color/" + imgId + ".png)");
} else {
$(this).css("background-image", "url(img/bnw/" + imgId + "bnw.png)");
}
});
Note, I also added in a "!" in the if statement, because this function triggers before the checkbox's state is changed. So the state here is the opposite of what it will be once the click event finishes propagating.
There is another way of doing it that makes a little more sense, too:
$('.block_input').change(function(){
var imgId = $(this).parent().attr('id');
if ($(this).prop('checked')) {
$(this).siblings('.block_button').css("background-image", "url(img/color/" + imgId + ".png)");
} else {
$(this).siblings('.block_button').css("background-image", "url(img/bnw/" + imgId + "bnw.png)");
}
});
This way, the function you're defining gets called after the input changes, not before. It also gets triggered if the user clicks on the checkbox itself, not just the image it's next to. (Which is useful if your users are tabbing around the page)
Hope this helps!
Upvotes: 1
Reputation: 96
I believe your mistake is here:
if ($(this).siblings('.block_input').checked = true) {
It should be ==
instead of =
. In fact, you could just write it as:
if ($(this).siblings('.block_input').checked) {
What is happening: when that line runs, you set the value of checked
to true
. This overrides the previous value of checked
.
Edit: A few changes were necessary to get a rudimentary working example (JSFiddle).
Changing the event to be triggered when the checkbox changes, rather than from the perspective of the label. This is also going to catch users clicking on the checkbox itself, or changing the state of the checkbox via other means (e.g., via the keyboard).
$('.block_input').change(function(){
Checking the property .checked
(see this SO answer for more details), like this:
if ($(this).prop('checked')) {
Now that the event is being triggered on the checkbox, you need to amend your reference to the label:
$(this).siblings('.block_button').css( ...
Upvotes: 1