How to toggle attribute in jQuery
Solution 1
I'd do this by passing a function to prop
(since jQuery 1.6, attr
before). The return value of this is set as the new property value.
$(this)
.closest('li')
.find('input:checkbox').prop('checked', function(idx, oldProp) {
return !oldProp;
});
The key fact here is that you can pass true
or false
to prop
to set the checked
property. oldProp
is the existing value of the property (which will be either true
or false
), so !oldProp
is the inversion: checked elements are unchecked and vice versa.
Note that I have also changed your code to look for the closest ancestor li
element with closest
, which should be more reliable and effective.
Solution 2
You could add a rather basic jQuery extension, that works in the same way as "toggle()" and "toggle(showOrHide)" but for attributes - "toggleAttr(attribute)" and "toggleAttr(attribute, addOrRemove)"
$.fn.toggleAttr = function(a, b) {
var c = (b === undefined);
return this.each(function() {
if((c && !$(this).is("["+a+"]")) || (!c && b)) $(this).attr(a,a);
else $(this).removeAttr(a);
});
};
Note, this is xhtml compatible, and is designed for attributes such as "disabled", "enabled", "checked", "selected" and so on.
Example of use (for your scenario):
$('#imageCheckBoxes img').click(function() {
$(this).parent('span').find('input:checkbox').toggleAttr('checked');
}
EDIT - though as pointed out by artlung - a label is probably best for your scenario
Solution 3
Another possible approach:
$('#imageCheckBoxes').delegate('img', 'click', function(){
var $associatedCheckbox = $(this).siblings('input:checkbox');
if ($associatedCheckbox.is(':checked')){
$(this).removeClass('checked');
$associatedCheckbox.removeAttr('checked');
} else {
$(this).addClass('checked');
$associatedCheckbox.attr('checked', 'checked');
}
});
I'm using delegate()
, though you could just as easily use your standard click()
or a bind()
call to add the listening function.
I also have added some code to add a class to the image. If you, say, wanted to give visual feedback to the user, you could implement that with your .checked
class on those images.
#imageCheckboxes img {
border: 2px solid #fff;
}
/* feedback for your users! */
#imageCheckboxes img.checked {
border: 2px solid #6f6;
}
Now, it strikes me that you could also avoid JavaScript for this, and simple put <label>
tags around your images, and then associate them with your checkboxes to get the same effect. Just replace your <span>
s in your html with <label>
.
Solution 4
Try this.
$('#imageCheckBoxes img').click(function() {
var el = $(this).parent('span').find('input:checkbox');
if(el.is(':checked'))
el.attr('checked', '');
else
el.attr('checked', 'checked');
});
Related videos on Youtube
TJ Desantes
Updated on July 05, 2022Comments
-
TJ Desantes almost 2 years
I'm trying to use images as checkboxes. The following would work fine if it were radios instead of checkboxes that I was targeting but with checkboxes the problem is I can't select an element by clicking on it again after selecting it.
// image checkbox $('#imageCheckBoxes img').click(function() { $(this).parent('span').find('input:checkbox').attr('checked', 'checked'); });
<div id="imageCheckBoxes"> <ul> <li><a href="">Africa</a> <span><img src="images/checkbox-inactive.png" /><input type="checkbox" name="" value="" /></span> </li> <li><a href="">Asia/Pacific Islands</a> <span><img src="images/checkbox-inactive.png" /><input type="checkbox" name="" value="" /></span> </li> <li><a href="">Australia</a> <span><img src="images/checkbox-inactive.png" /><input type="checkbox" name="" value="" /></span> </li> <li><a href="">Central/South America</a> <span><img src="images/checkbox-inactive.png" /><input type="checkbox" name="" value="" /></span> </li> <li><a href="">Europe/Russia</a> <span><img src="images/checkbox-inactive.png" /><input type="checkbox" name="" value="" /></span> </li> <li><a href="">North America</a> <span><img src="images/checkbox-inactive.png" /><input type="checkbox" name="" value="" /></span> </li> <li><a href="">United Kingdom</a> <span><img src="images/checkbox-inactive.png" /><input type="checkbox" name="" value="" /></span> </li> </ul> </div>
I need to basically toggle the check
attr()
part.How to do that?
-
brenjt over 11 yearsUse a
<label>
tag around the contents in the<li>
would be the simplest way to do this. No JS required -
Ciro Santilli OurBigBook.com almost 10 yearsVery similar for
disabled
: stackoverflow.com/questions/4702000/…
-
-
TJ Desantes almost 13 yearshmm not working. Using your code I can still select the checkboxes like before but when I click a second time the checked boxes don't get unchecked.
-
Felix Kling almost 13 years"I need to basically toggle the check attr() part." I don't see how you address that issue... you just provide an alternative way to select the elements. But the original selector works fine as well.
-
brenjt almost 13 yearsYou are right. I just updated the answer. My bad, thanks for catching my mistake.
-
TJ Desantes almost 13 yearsAhh ok, reason why it wasn't working earlier was because I swapped the checkbox image in a part of the code I ommited here so when $(this) was being clicked again it was no longer the same image. Thanks working now.
-
Felix Kling almost 13 yearsIf the structure is always like this,
$(this).next()
will work too. -
Felix Kling almost 13 yearsUsing
label
s is probably the best idea. +1 for that. -
Yuval A. over 11 yearsThe Ternary operator makes for shorter code: el.attr('checked',(el.is(':checked'))?'':'checked');
-
user2918201 about 11 yearsI ended up using jquery's
toggleClass()
for my purposes. However, I too liked your solution. -
Ideogram almost 10 yearsNice. Making an extension for it, makes the rest of the code more readable.
-
radbyx about 8 years+1. AH! A callback function for 'prop' second parameter is SO neat! Brilliant answer. I've refactored my if-else right away :)