Automatically checking / unchecking parent inputs - javascript

I'm hoping someone can help me out here.
I'm trying to automatically check parent items in an input list, but also uncheck children if the parent is unchecked.
The great thing is I found some code that replicates the desired functionality perfectly: http://jsfiddle.net/3y3Pb/14/
EDIT: To clarify - the functionality required is this: Check mark a child input & all of the parent items get checked. Uncheck a Parent - all child inputs get unchecked. See the above example.
However, this doesn't seem to be working with my particular code (it's output from a WordPress plugin - Advanced Custom Fields) so I don't want to modify it).
I've narrowed it down to what I BELIEVE is the problem. ACF wraps each input with a <label></label>. I don't know why, but this breaks the functionality:
http://jsfiddle.net/3y3Pb/223/
When I remove the <label></label> it works fine:
http://jsfiddle.net/3y3Pb/225/
Changing the markup isn't really an option here, I would REALLY appreciate it if someone could assist me in making this work!

This should work, its simple and only uses divs and a few lines of jquery:
$('[type="checkbox"]').change(function () {
var kids = $(this).next().next();
if (kids.is('div') && !$(this).prop('checked'))
{
kids.children().each(function(){$(this).prop('checked',false)});
}
var thisChecked = $(this).prop('checked');
var master = $(this).parent().prevAll('[type="checkbox"]:first');
master.prop('checked', thisChecked ? true : master.prop('checked'));
});
div {
margin-left: 25px;
}
div div {
margin-left: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" />Master Check
<br />
<div>
<input type="checkbox" />Slave Check 1
<br />
<input type="checkbox" />Slave Check 2
<br />
<input type="checkbox" />Slave Check 3
<br />
<div>
<input type="checkbox" />Slave 2 Check 1
<br />
<input type="checkbox" />Slave 2 Check 2
<br />
<input type="checkbox" />Slave 2 Check 3</div>
</div>

I have improved the javascript code.
$(document).ready(function() {
$('input[type=checkbox]').click(function(){
// if is checked
if($(this).is(':checked')){
$(this).parents('ul').children('li').children('label').find('input').prop('checked', true);
} else {
// uncheck all children
$(this).closest('li').find('input').prop('checked', false);
}
});
});
Children travels a single level down the DOM tree, whereas find goes for multiple levels down looking into descendants.

It was the label - here is the solution:
$('input[type=checkbox]').click(function(){
// if is checked
if($(this).is(':checked')){
$(this).parents('li').children('label').find('input[type=checkbox]').prop('checked', true);
} else {
// uncheck all children
$(this).closest('li').find('input[type=checkbox]').prop('checked', false);
}
});

Related

jquery - check/uncheck customized checkbox with hidden input

I have this in HTML
<div class="my-checkbox">
<label>I do agree</label>
<input type="hidden" name="agreement" value="0">
</div>
and this in jQuery
$('.my-checkbox').on('click', function()
{
if($(this).children('[type="hidden"]').val() == 0)
{
$(this).children('[type="hidden"]').val(1);
$(this).addClass('active');
}
else
{
$(this).children('[type="hidden"]').val(0);
$(this).removeClass('active');
}
});
When I click .my-checkbox, it will change the value to 1 and add class active and when I click it again vice-versa. It works correctly but in mobile device when I click it it changes the value and set to active but when I click it again, it changes the value but the active class doesn't remove. How do I know that? just by double clicking and submit the form and the result was => you should agree with agreements.
Thanks
Makes no sense to reinvent the checkbox when it is a is simple CSS to change the style to make it work the same way. No adding/removing classes. No JavaScript needed, just a simple CSS selector.
#agree + label {
color: red
}
#agree:checked + label {
color: green
}
<div class="my-checkbox">
<input type="checkbox" id="agree" name="agreement" hidden>
<label for="agree" >I do agree</label>
</div>
Now why does your code not work?
if($(this).children('[type="hidden"]').val() == 0) <-- If zero
{
$(this).children('[type="hidden"]').val(0); <-- set zero
You are not toggling to 1. You have your logic reversed.

Checkboxes, javascript runs 2 times through function if I click on text

I want to click on a checkbox and if I click this box it should run a function what gets an ID and saves it into an array or deletes it from the array if it still exists in the array.
That works, but if I click on the text beside the box the function runs twice. It first writes the ID into the array and then deletes it.
I hope you can help me so that I can click on the text and it just runs once
HTML
<label><input type="checkbox" value="XXX" >Active</label>
JavaScript/jQuery
function addOrRemoveBoxes(ID){
if(boxArr.indexOf(ID) != -1){
removeFromArray(ID)
}
else{
boxArr.push(ID);
}
}
$(".checkBoxes").unbind().click(function() {
event.stopPropagation();
addOrRemoveBoxes($(this).find('input').val());
});
The problem is probably that your label and your input are picking the click. Try to bind it only to input. Like this:
$(".checkBoxes input").unbind().click(function() {
event.stopPropagation();
addOrRemoveBoxes($(this).find('input').val());
});
Your HTML is structured bad. When your label is clicked it triggers a click event for the input so you have to separate the input form the label like: <input type="checkbox" name="opt1" id="opt1_1" value="ENG"> <label for="opt1_1">hello</label>. Also your jQuery makes no sense, why do you use unbind()? And we can't see what removeFromArray() does (we can guess but I prefer to see all code used or note that you use pseudo code).
I made this in 5 min: (hopes it helps you)
$(document).ready(function(){
window.boxArr = [];
$(document).on('click','[name=opt1]',function(){
addOrRemoveBoxes(this.value);
//show contents of boxArr
if(boxArr.length == 0){
$('#output').html('nothing :/');
}
else{
$('#output').html(boxArr.join(" -> "));
}
});
});
function addOrRemoveBoxes(ID){
var arrayIndex = boxArr.indexOf(ID);
if(arrayIndex > -1){
boxArr.splice(arrayIndex, 1);
}
else{
boxArr.push(ID);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Choose</h1>
<input type="checkbox" name="opt1" id="opt1_1" value="ENG"> <label for="opt1_1">hello</label> <br>
<input type="checkbox" name="opt1" id="opt1_2" value="DUT"> <label for="opt1_2">hallo</label> <br>
<input type="checkbox" name="opt1" id="opt1_3" value="SWE"> <label for="opt1_3">hej</label>
<br><br><h2>Array contains:</h2>
<div id="output">nothing :/</div>
Side note: with [name=opt1] we select all the elements with name="opt1" attribute.

Enabling and disabling all the child elements

I have this issue with enabling and disabling section of fields if other section of fields have specific value.
Consider jsfiddle for html code.
Conditions are
If all the fields of partA are selected as No, then enable partB.
If all the fields of partB are selected as No, then enable partC.
Try 1
First I tried disable elements of PartB and PartC which did not work.
$(function () {
$('.group').attr('name','partB').find('input').attr('disable', true);
$('.group').attr('name','partC').find('input').attr('disable', true);
});
I am not sure how would make sure if all the child elements are selected as No in a group div.
jsBin demo
Having this HTML:
<div class="group" id="partA">
<span> PART A</span><br/>
Option 1
<input type="radio" name="optionsRadios1" value="option1"/>Yes
<input type="radio" name="optionsRadios1" value="option2"/>No
<br />
Option 2
<input type="radio" name="optionsRadios2" value="option1"/>Yes
<input type="radio" name="optionsRadios2" value="option2"/>No
</div>
jQ:
$(function () {
$('#partB, #partC').find('input').prop('disabled', true);
function testChecked(){
var $par = $(this).closest('.group');
var $rad2 = $par.find('[value="option2"]');
var allNo = $rad2.filter(':checked').length == $rad2.length;
$par.next('.group').find(':radio').prop('disabled', !allNo);
if(!allNo){
$par.nextAll('.group').find(':radio').prop({'disabled':true, 'checked':false});
}
}
$('.group :radio').change(testChecked);
});
The above will work also for more than 2 radio groups per .group
Your errors:
"disable", "true" should be "disabled", "true"
<label> can control only one inner element (so I removed it.)
<div> afaik is not supposed to have a name attribute (so I assigned an ID)

Knockout does not recognize manually click

Here is sample http://jsfiddle.net/HhXGH/57/
I am clicking radio button by jquery but knockout.js does not recognize it.Still it shows first clicked value.
<p>Send me spam: <input type="checkbox" data-bind="checked: wantsSpam" /></p>
<div data-bind="visible: wantsSpam">
Preferred flavor of spam:
<div><input type="radio" name="flavorGroup" value="cherry" data-bind="checked: spamFlavor" /> Cherry</div>
<div><input type="radio" name="flavorGroup" value="almond" data-bind="checked: spamFlavor" /> Almond</div>
<div><input type="radio" name="flavorGroup" value="msg" data-bind="checked: spamFlavor" /> Monosodium Glutamate</div>
</div>
var viewModel = {
wantsSpam: ko.observable(true),
spamFlavor: ko.observable('cherry')
};
ko.applyBindings(viewModel);
$(':radio:last').click();
alert(viewModel.spamFlavor())
This because Knockout is subscribing to the click events of checked radio/checkbox elements only. If you checkout the binding handler code for checked. It does this.
var updateHandler = function() {
var valueToWrite;
if (element.type == "checkbox") {
valueToWrite = element.checked;
} else if ((element.type == "radio") && (element.checked)) {
valueToWrite = element.value;
} else {
return; // "checked" binding only
responds to checkboxes and selected radio buttons
}
So in order to get your code to work do this.
$(':radio:last').prop('checked', true).click();
However if the goal is to check the last value, why not just do
viewModel.spamFlavor("msg");
This would achieve the same result.
Hope this helps.
Adding $(':radio:last').attr('checked', true); in addition to triggering click makes it work for me:
http://jsfiddle.net/jearles/HhXGH/61/
I have two different jsFiddles since I'm not sure exactly what your after.
The first jsFiddle will respond via alert when the last radio button is manually clicked.
The second jsFiddle is your posted /57/ jsFiddle without the alert.
Using an alert or console.log with a function will actually invoke that function. That said, after you have manually set the .click() to the last radio button, it's inadvertently reset back to cherry since that's the default value.
RE-EDIT: The second jsFiddle now includes alert written in syntax that doesn't invoke the function & now uses shorted markup.

Check to see if none of the checkboxes was checked in jquery

I have two checkboxes and one of the checkboxes must be checked. I can see that it's right, no syntax errors. What should be made to my code to check if none of the checkboxes were checked?
HTML :
<input type="checkbox" value="aa" class="first" name="a"> Yes<br/>
<input type="checkbox" value="bb" class="second" name="b"> No <br/>
<button type="submit">Go!</button>
<p class="error"></p>
JavaScript:
$('button').on('click',function(){
if( $(".first:not(:checked)") && $(".second:not(:checked)") ){
$('.error').text('You must select atleast one!');
}else
$('.error').hide();
});
Example : http://jsfiddle.net/ptbTq/
Check this fiddle: http://jsfiddle.net/692Dx/
Checking code:
if($('input[type="checkbox"]:checked').length == 0) {
alert('none checked');
}
You are using selectors which do not return boolean values which is what you need when writing an if condition. Here's what you could do:
$('button').on('click',function() {
if(!$(".first").is(":checked") && !$(".second").is(":checked")) {
$('.error').text('You must select atleast one!').show();
} else {
$('.error').hide();
}
});
or if you prefer and think it could be more readable you could invert the condiciton:
$('button').on('click',function() {
if($(".first").is(":checked") || $(".second").is(":checked")) {
$('.error').hide();
} else {
$('.error').text('You must select atleast one!').show();
}
});
Also notice that you need to .show() the error message in the first case as you are hiding it in the second.
And here's a live demo.
Short:
$("input[type=checkbox]").is(":checked")
returns true if:
one of your checkboxes - from the selector ("input[type=checkbox]") - is checked.
else return false
and in your case:
$(".first, .second").is(":checked")
Do something at least one of your checkboxes is checked
Put the same class on both checkboxes and you can do something like
if ($(':checkbox.the_class:checked').length > 0) {
// at least one checkbox is checked
// ...
}
The best would be to put your checkboxes inside a div with an unique ID so you can verify all the checkboxes in there, so your code will work in all cases. Even when adding new checkboxes to the div later on.
<div id="cb">
<input type="checkbox" value="aa" class="first" name="a" /> Yes<br/>
<input type="checkbox" value="bb" class="second" name="b" /> No <br/>
<button type="submit">Go!</button>
<p class="error"></p>
</div>
Your JQuery:
$('button').click(function() {
var checked_one = $('div#cb input[type="checkbox"]').is(':checked');
if (!checked_one )
$('.error').text('You must select atleast one!');
else
$('.error').hide();
});
Live demo can be seen here: http://jsfiddle.net/ptbTq/15/

Categories

Resources