I'm using this code:
$('fieldset input[type=checkbox]').each(function () {if($(this).attr('checked','checked')){
var switches = $(this).parent().find('.switch');
$(switches).attr('state','on')
$(switches).css({'left':"52px"});
$(switches).parent().css({'background-position': "147px -37px"});
}})
But somehow it sets all my checkboxes to checked="checked" Am I just stupid or is something else in the code interfering?
Thanks for your help :)
EDIT:
here is the HTML
<fieldset>
<input checked="checked" />
<label></label>
<div class="toggle_box">
<div class="switch" state="on"></div>
</div>
</fieldset>
<fieldset>
<input/>
<label></label>
<div class="toggle_box">
<div class="switch"></div>
</div>
</fieldset>
This piece of code is doing it...
$(this).attr('checked','checked')
...which returns the set in order for the cascade to work. An Object is always truthy in JavaScript.
Try...
this.checked
...which returns whether the checkbox is checked or not. If you wanted to do it the jQuery way, use $(this).is(':checked'). I wouldn't though, it's more verbose and less performant.
You're passing the checked value to attr() as the second argument. That causes it to be set. What's then returned is the jQuery object with that input, which is always a truthy value.
Your if condition should look like this (use the :checked pseudo-class instead):
if ($(this).is(':checked')) {
On a side note, your inner code can be refactored to this:
$(this).parent().find('.switch')
.attr('state', 'on')
.css({ 'left': "52px" })
.parent()
.css({ 'background-position': "147px -37px" });
If you have to use a cached variable (i.e. switches), you can, but don't wrap it in the jQuery function. It's a jQuery object itself, so needs not be wrapped.
The statement in the if statement is setting your checkboxes to checked. Particularly, this statement: $(this).attr('checked','checked').
Instead you can do if($(this).prop('checked'))
Read more about the jQuery Prop method.
Alternatively, you can do, this.checked which will access the DOM directly or with jQuery, $(this).is(':checked').
if($(this).attr('checked','checked')) would be your problem. You're assigning checked to each checkbox instead of checking if it's checked.
At first glance I see you're using .is('checked') when I beleive you want .is(':checked') The preceding colon being the difference.
UPDATE: I see you updated the code. The line
if ($(this).attr('checked', 'checked'))
is actually setting all 'input:checkbox' elements to checked. It should be:
if ($(this).is(':checked'))
$('fieldset input[type=checkbox]').each(function () {if($(this).attr('checked') == 'checked')){
var switches = $(this).parent().find('.switch');
$(switches).attr('state','on')
$(switches).css({'left':"52px"});
$(switches).parent().css({'background-position': "147px -37px"});
}})
There is actually a selector specifically for the checked boxes.
$('fieldset input[type=checkbox]:checked').each(function(){
var switches = $(this).parent().find('.switch');
$(switches).attr('state','on')
$(switches).css({'left':'52px'});
$(switches).parent().css({'background-position':'147px -37px'});
});
If you use that you won't have to do any of that logic by yourself.
Related
I have 'chain' of checkboxes (parent checkbox and childs), and problem is:
When first clicking on 'parent' checkbox it is working well, but after that when clicking on 'childs', the 'parent' checkbox then isn't doing what is supposed. Parent is checking/unchecking childs except the child which was pressed before.
Here is code:
JavaScript
checks_bind();
function checks_bind(){
$("#x_main").off('click');
$("#x_main").on('click',function(){
var obj = $(this);
var val = obj.is(':checked');
$("#checks").find("input[type='checkbox']").attr('checked',val);
});
}
HTML
<input id='x_main' type='checkbox'/>Main<br>
<p>--------------------------------</p>
<div id='checks'>
<input type='checkbox'/>1<br>
<input type='checkbox'/>2<br>
</div>
<p>--------------------------------</p>
<i>1 - Click on 1 or 2 <br>2 - Try <b>Main</b> checkbox. <br>
3 - Main checkbox isn't working</i>
jsfiddle example
And one more question:
Is it good to use .on('click.namespace') on checkboxes since it's working well? I can use .change() method, but I want to call .off('click.namespace') (or something to unbind) before .on() each time when calling the function.
As checked is a property, You need to use .prop() instead of .attr()
$("#checks").find("input[type='checkbox']").prop('checked', val);
Updated Fiddle, A good read .prop() vs .attr()
If you want to use .off() then its advisable to use namespaced event.
Try this: user 'prop' instead of attribute and you can check all or uncheck all as per checked condition of main check box.
Also, you can check the count of all checkbox to check /uncheck main checkbox. see below
Note: bind click handler when DOM is ready hence user $(document).ready or $(function(){})
$(function(){
$("#x_main").on("change", function(){
$("#checks").find("input[type='checkbox']").prop("checked",$(this).is(":checked"));
});
$("#checks input[type='checkbox']").on("change", function(){
var total = $("#checks").find("input[type='checkbox']").length;
var checked = $("#checks").find("input[type='checkbox']:checked").length;
$("#x_main").prop("checked",total==checked);
});
});
JSFiddle Demo
I'm having trouble coming up with a solution that pleases me.
I'm working with some composite components, and I don't have full control over them, and now I have to set values to them using JavaScript, and I thought JQuery would serve me well, as it did.
What happens is that the component's HTML output has a structure simlar to this:
<span id="externalSpan">
<span id="internalSpan">
<input type="text" class="component-value" />
</span>
</span>
So all I had to do was check the component-value input, and if it's empty, I set the default value to it.
I solved it like this:
$(document).ready(function(){
var defaultValue = $('#defaultValue').val();
$('.component-value').each(function(){
if(!$(this).val()){
$(this).val(defaultValue);
}
});
});
And that worked fine, but now there's a new condition I need to evaluate. If the component has the manualInput CSS class, I cannot set it's value, but the class is set on the externalSpan which is the input's grandfather component, and it looks like this:
<span id="externalSpan" class="manualInput">
<span id="internalSpan">
<input type="text" class="component-value" />
</span>
</span>
The simplest way that I found to do it was this:
if(!$(this).parent().parent().hasClass('manualInput')){ ... }
And it works, but it seems really smelly to me, another solution was to invoke parents() with a class selector and check the length, but it seems odd too.
Is there a cleaner way for me to do this? And if not, which of the 2 options described above is a better solution?
So add the check to the selector
$('span:not(.manualInput) > span > .component-value').each(function(){
Example JSFiddle
I would use closest :
if(!$(this).closest('#externalSpan').hasClass('manualInput')){ ... }
Source : http://api.jquery.com/closest/
You can do this --
if($(this).closest('.manualInput').length > 0){
// do your stuff
}
A much better solution, use a selector that avoids .component-value elements that are descendants of .manualInput:
$('.component-value:not(.manualInput .component-value)').each(...)
Ideally the grandparent element would have a consistent class such that you could call .closest():
if ($(this).closest('.component-value-grandfather').hasClass('manualInput')) {...}
Alternatively you could check to see if there is a .manualInput ancestor at all:
if ($(this).closest('.manualInput').length) {...}
I'd recommend the following
$('span:not(.manualInput) > span').find('.component-value:empty').each(function () {
$(this).val(defaultValue);
});
Or better yet,
$('.component-value:empty', 'span:not(.manualInput) > span').val(defaultValue);
Probably, the shorted piece of code to achieve what you desire.
Alternatively you could use
if ($(this).parents('.manualInput').length) {/*...*/}
See jquery documentation. I suppose this is the shortest way to find the parent(s) of a given element
I have got this checkbox which has value 1.
<input type="checkbox" name="option_1" id="checkbox_1" value="1">
Also I use this method to make checked/unchecked it.
$('input[id^="checkbox_"]').not('#checkbox_all').click(function () {
$('#checkbox_all').prop('checked', false);
// Get 'VALUE' of the checkbox here
});
What I need is somehow get 'VALUE' of the clicked checkbox. So In that case it should be 1.
Any clue how do it could be done?
Thank you!
In your click method use this to get the value
$(this).attr("value");
$(this) is referencing to the object that has been clicked.
EDIT:
you could also use $(this).val(); but sometimes I had problems with elder versions of IE so I did recommend $(this).attr("value") in the first place.
<html>
<head>
</head>
<body>
<input type="checkbox" name="option_1" id="checkbox_1" value="1">
</body>
</html>
$('input[id^="checkbox_"]').not('#checkbox_all').click(function () {
$('#checkbox_all').prop('checked', false);
alert($(this).val());
});
http://jsfiddle.net/heten/
Working :)
I think you just need $(this).val(); in your click event.
Also, if you need to work with that value as an int later, use
var x = parseInt($(this).val(),10);
The val jQuery method should see you right.
$('#checkbox_all').val();
http://api.jquery.com/val/
I have some set of links and select boxes. My html code is below:
<div>
<div>
<a href='#' onclick='set_checked(false,"checkbox1")'>clear</a>
<a href='#' onclick='set_checked(true,"checkbox1")'>select</a>
</div>
<div>
<input type='checkbox' name='checkbox1'/>
</div>
</div>
<div>
<div>
<a href='#' onclick='set_checked(false,"checkbox2")'>clear</a>
<a href='#' onclick='set_checked(true,"checkbox2")'>select</a>
</div>
<div>
<input type='checkbox' name='checkbox2'/>
</div>
</div>
Now my requirement is when I click on select link I have to check the checkbox based on it's arguments, and reversal for clear. Here I'm passing two parameters. One is to pass Boolean value (i.e. if true check else uncheck) and another one is to pass name argument of a checkbox field. And I'm using the following function to check or uncheck a checkbox:
function set_checked(checked,inputFeildName){
$('input[name=inputFeildName]').attr('checked',checked);
}
but the above code is not working. And this is my fiddle http://jsfiddle.net/vu6fs/5/.
I have one more requirement, before selecting any checkbox all clear links have to be disabled, after selection of checkbox respective clear link have to be enable. I'm applying opacity and also 'disabled' property in JavaScript but it's not working,can anyone suggest me where my fault is.. Can anyone please help me?
jQuery 1.6+
function set_checked(checked,inputFeildName){
$('input[name="'+ inputFeildName +'"]').prop('checked',true);
}
jQuery 1.5 and below
function set_checked(checked,inputFeildName){
$('input[name="'+ inputFeildName +'"]').attr('checked','checked');
}
Here is an example for your extension of question (more you want, About disable/enable a tag on checkbox change)
CSS
.disButton {
background: transparent;
border: none;
}
.disButton a {
text-decoration: none;
color: #ddd;
}
jQuery
$('input:checkbox').on('change', function() {
enable_clear(this, this.checked);
}).change();
function enable_clear(el, checked) {
var target = $(el).parent('div').prev('div').find('a:contains(clear)');
if (checked) {
target.unwrap();
} else {
target.wrap($('<button/>', {
disabled: true,
'class': 'disButton',
width: target.width() + 'px'
}));
}
}
$('a').on('click', function(e) {
e.preventDefault();
var target = $(this).parent().next('div').find('input:checkbox');
if (!target.is(':checked') && $(this).text() == 'select') target.click();
if ($(this).text() == 'clear') target.click();
});
DEMO
I think this is what you are trying to do... btw you have misspelt field so be careful when using the variable/attr again.
function set_checked(checked,inputFeildName){
$('input[name="'+inputFeildName+'"]').attr('checked',checked);
}
you forget to append string that i did as below , this will resolve your issue
function set_checked(checked,inputFeildName)
{
$('input[name="'+ inputFeildName+'"]').attr('checked',checked);
}
There are some errors in your fiddle:
Your function set_checked is declared in the onLoad-Handler (as selected), and is only available in that locally and not in the global scope. Remove the wrapping function by selecting "no wrap (head)" or assign your function to window.set_checked.
Please note that the checked attribute only represents the default value of the checkbox, to change the actual state you need to use the checked property (with jQuery, you can use val()).
If you wanted to change the default value, you can't do it by setting the attribute to (the string) false. The attribute represents a checked checbox through its existence, you would need to use removeAttribute() for disabling. It's easier to use the defaultChecked property with a boolean value.
last but not least there's the obvious error detected by all others: To use a variable, you will need to use it instead of putting its name into a string (like in PHP).
You also might be more happy with ids than name attributes. I've updated your fiddle with a proper solution: http://jsfiddle.net/vu6fs/7/
To disable the clear/select link when it's not appropriate:
you can't disable a link (anchor) as you can a form element (see Disable link using javascript, jQuery disable a link, Disable link using css). OK, we don't really need to disable its functionality (nothing changes), so so I guess you only think of graying it out. This can be done with CSS, and you'll need to trigger the update both on user-change events and the setting through set_checked. Example code at http://jsfiddle.net/vu6fs/9/
It might be easier to use just one link that toggles the checked state. Its lettering may change between "clear" and "select", depending on the current state.
I now have written a plugin (i.e. a jQuery prototype function) to add those links dynamically to any checkbox elements. That means it also can use (scoped) click handlers instead of a global-scope-polluting set_checked function.
The function has a little error:
function set_checked(checked,inputFeildName){
$(**'input[name='+inputFeildName+']'**).attr('checked',checked);
}
Something is very awkward about my situation... i have something like this:
<div id="selector">
<input type='radio' />
<input type='radio' />
<input type='radio' />
</div>
if I use $("#selector input[type=radio]") all three elements are found, but if I use $("#selector").find("input[type=radio]") or even find("input") only the first one is found.
Is this a bug in jQuery? Am I not using find() properly?
Clarification : I want to use find() to get all the inputs, but anything I try finds only the first one.
edit: i'm using jquery 1.3.2
What you really want is:
$("#selector > :radio")
As for why you're getting only one, I'd need to see the actual code that's being run because find() doesn't stop at one and will find all matches so it may be how you're using it afterwards that is the issue.
The two code fragments should return the same result.
Are you saying that when you run the following code, the first alert will show "3" and the second "1" ?
var a = $("#selector input[type=radio]");
var b = $("#selector").find("input[type=radio]");
alert(a.length);
alert(b.length);
Can you please verify?
Try
$("#selector").find("input[type=radio]")
See here
All the three returns the same result!
$(function() {
console.log($("#selector input[type=radio]")); // 3
console.log($("#selector").find("input[type=radio]")); // 3
console.log($("#selector").find("input")); // 3
});
$("#selector").children("input[#type=radio]")