Element has `checked` attributes but isn't checked? - javascript

I am using ThreeDubMedia's drag and drop selection feature to check and uncheck a couple checkboxes. It will check and uncheck them once, but no more than that. What's more, when I look at the elements by using inspect, they start without the checked attribute, as they should; they gain it when selected, as they should; and they lose it when selected again, as they should. However, this is where it gets strange. If I select it a third time, it gains the checked attribute, but does not check! And if I select it a fourth time, nothing happens! I have no idea what's causing this.
http://i.snag.gy/AieOg.jpg

Currently, you are actually removing the attribute (using removeAttr()) instead of just turning it off (e.g. prop('checked', false)).
You should be using prop(). The following works:
if (this.checked) {
$(this).prop('checked', false);
} else {
$(this).prop('checked',true);
}
jsFiddle here.
Or better yet, as #Pointy mentioned:
.drop(function( ev, dd ){
this.checked = !this.checked;
});
jsFiddle here.

Related

Checkbox select/deselect trigger works first time but fails on subsequent attempts

I've got a chunk of jQuery that works based off html data-* tags to work through checkboxes in a group for a search form.
Click on the 'All' check box and all of the rest of them should become unselected (this works everytime without issue).
Now, if the 'All' is selected and you click a different option then the 'All' should become unselected, this too works as intended.
However if you want to you can unselect the 'All' checkbox which should then default to having the rest of the checkboxes selected so you can unselect your desired results.
If you haven't changed any others so far, this works for the first time but if any other checkbox bar 'All' is selected or if you've already clicked the 'All' button once it fails if you selected then deselect it again.
Any ideas as to what it's upto would be greatly appreciated (I've tried using console to spot what it's not doing but so far it's not giving any clues).
Example below.
html...
<input data-sel-group='group1' id='group1_all'/>
<input data-sel-group='group1' id='group1_1'/>
<input data-sel-group='group1' id='group1_2'/>
/html...
jQuery...
$('input:checkbox').on('click',function(){
var sel = $(this).data('sel-group'),
all = $('#'+sel+'_all'),
chk = all.is(':checked');
if($(this).attr('id')==all.attr('id')){
if(chk){
$('input[data-sel-group="'+sel+'"][id!="'+sel+'_all"]').attr('checked', false);
}else{
$('input[id!="'+sel+'_all"][data-sel-group="'+sel+'"]').attr('checked', true);
}
}else{
all.attr('checked', false);
if($('input[data-sel-group="'+sel+'"]:checked').length<=0){
all.attr('checked', true);
}
}
})
Use .prop() instead of .attr()
$(selector).prop('checked', true/false);
Also go through .prop() vs .attr()
you should use delayed execution while setting checkbox attribute checked.
Please refer this blog

jQuery CheckAll Toggle Not Quite Working Correctly

Using:
function CheckToggle(which){
jQuery(which).each(function() {
jQuery(this).attr('checked', !jQuery(this).attr('checked'));
});
}
On first click, all checkboxes get checked, click it again, and they get unchecked.
Second click, no checkmarks show in the boxes, however, the checked="checked" attribute does appear in the element, and dissapears if clicking the checkall again.
How can I keep them showing the checkmark?
In this situation, .prop() would be used instead of .attr(). But honestly, it'd be even better to not use either:
this.checked = !this.checked;
Use prop instead of attr
function CheckToggle(which){
jQuery(which).each(function() {
jQuery(this).prop('checked', !jQuery(this).attr('checked'));
});
}

Getting length of toggle classes

This might be similar to getting length of a class. But I am not getting the actual output for toggle class.
So here is the scenario: I have a table in which there is a checkbox in every row. If check all option is selected, all checkbox is marked. Now the problem is that I want to pass flag as true when all checkbox are checked and false when only some checkboxes are checked. Now I use toggling functionality. So I don't know how I get length of 'unchecked' checkboxes rather than 'unchecked checked' checkboxes.(I am using Div's for styling instead of checkboxes. )
Here is the jsfiddle
Script for counting length:
$("#cntCheck").click(function(){
alert($('.isChecked').length); //Counting Checked CheckBox(Working right).
});
$("#cntUncheck").click(function(){
alert($('.checkBox isChecked').length); //Counting Unchecked CheckBox Except CheckAll checkbox(This is not working)
});
If I understand your (very confusing) question correctly, you're asking how to count the elements that do have the checkBox class but don't have the isChecked class. If so, you can use the .not() method:
$(".checkBox").not(".isChecked").length
Or, the :not() selector:
$(".checkBox:not(.isChecked)").length
Regarding your styling:
"I am using Div's for styling instead of checkboxes."
I would strongly recommend against doing this, because users who don't like to (or are physically unable to) use a mouse or other pointing device can't click your pseudo-checkboxes.
See this fiddle - http://jsfiddle.net/Yp56c/3/
$("#cntUncheck").click(function(){
var notChecked = $('.checkBox').not('.isChecked').length;
alert(notChecked); //This is working
});

How can I remove an element from a list returned by a jQuery selector?

I would like to uncheck all checkboxes that have a specific class with the exception of the one just checked.
function PizzaToppings_OptionValueChanged(checkboxElement) {
if ($(checkboxElement).attr("checked")) {
if($(checkboxElement).hasClass('cheese_toppings'))
{
// This will uncheck all other "cheese_toppings" but I want the newly selected item "checkboxElement" to remain checked.
$('input:checkbox.cheese_toppings').attr('checked', false);
}
}
}
The code above will uncheck all "cheese_toppings" including the one just selected. I don't want to then recheck the one just selected or the event will be recalled.
I thought the best solution would be to remove "checkboxElement" from the list returned by $('input:checkbox.cheese_toppings') and then set the .attr('checked', false) to that list. But I'm not sure how to remove checkboxElement from the list.
$('input:checkbox.cheese_toppings').not(checkboxElement).attr('checked', false);
See the jQuery docs: .not()
try
$('input:checkbox.cheese_toppings').not( checkboxElement ).attr('checked', false)
//when the page is loaded
$(function() {
//select all checkboxes with class cheese_topping
var allToppingBoxes = $('input[type=checkbox].cheese_topping')
//when one of these is clicked
allToppingBoxes.click(function() {
//if the box was unchecked do nothing
if(!$(this).attr('checked'))
return;
//select all except this one that was clicked
allToppingBoxes.not(this)
.attr('checked', false); //uncheck all
});
});
Also note that you probably want to use jquery prop rather than attr.
You might also want to look at the :checked pseudoclass (IE8 down doesn't support it though)

Add attribute 'checked' on click jquery

I've been trying to figure out how to add the attribute "checked" to a checkbox on click. The reason I want to do this is so if I check off a checkbox; I can have my local storage save that as the html so when the page refreshes it notices the checkbox is checked. As of right now if I check it off, it fades the parent, but if I save and reload it stays faded but the checkbox is unchecked.
I've tried doing $(this).attr('checked'); but it does not seem to want to add checked.
EDIT:
After reading comments it seems i wasn't being clear.
My default input tag is:
<input type="checkbox" class="done">
I need it top be so when I click the checkbox, it adds "checked" to the end of that. Ex:
<input type="checkbox" class="done" checked>
I need it to do this so when I save the html to local storage, when it loads, it renders the checkbox as checked.
$(".done").live("click", function(){
if($(this).parent().find('.editor').is(':visible') ) {
var editvar = $(this).parent().find('input[name="tester"]').val();
$(this).parent().find('.editor').fadeOut('slow');
$(this).parent().find('.content').text(editvar);
$(this).parent().find('.content').fadeIn('slow');
}
if ($(this).is(':checked')) {
$(this).parent().fadeTo('slow', 0.5);
$(this).attr('checked'); //This line
}else{
$(this).parent().fadeTo('slow', 1);
$(this).removeAttr('checked');
}
});
$( this ).attr( 'checked', 'checked' )
just attr( 'checked' ) will return the value of $( this )'s checked attribute. To set it, you need that second argument. Based on <input type="checkbox" checked="checked" />
Edit:
Based on comments, a more appropriate manipulation would be:
$( this ).attr( 'checked', true )
And a straight javascript method, more appropriate and efficient:
this.checked = true;
Thanks #Andy E for that.
It seems this is one of the rare occasions on which use of an attribute is actually appropriate. jQuery's attr() method will not help you because in most cases (including this) it actually sets a property, not an attribute, making the choice of its name look somewhat foolish. [UPDATE: Since jQuery 1.6.1, the situation has changed slightly]
IE has some problems with the DOM setAttribute method but in this case it should be fine:
this.setAttribute("checked", "checked");
In IE, this will always actually make the checkbox checked. In other browsers, if the user has already checked and unchecked the checkbox, setting the attribute will have no visible effect. Therefore, if you want to guarantee the checkbox is checked as well as having the checked attribute, you need to set the checked property as well:
this.setAttribute("checked", "checked");
this.checked = true;
To uncheck the checkbox and remove the attribute, do the following:
this.setAttribute("checked", ""); // For IE
this.removeAttribute("checked"); // For other browsers
this.checked = false;
If .attr() isn't working for you (especially when checking and unchecking boxes in succession), use .prop() instead of .attr().
A simple answer is to add checked attributes within a checkbox:
$('input[id='+$(this).attr("id")+']').attr("checked", "checked");
use this code
var sid = $(this);
sid.attr('checked','checked');

Categories