Why do my nested checkboxes only work once? - javascript

I'm adjusting an existing page where there are nested checkboxes, like this:
<ul>
<li>
<label><input type="checkbox" class="categorycheckbox">Group 1</label>
<ul>
<li>
<label><input type="checkbox" class="productcheckbox">Item 1</label>
</li>
<li>
<label><input type="checkbox" class="productcheckbox">Item 2</label>
</li>
</ul>
</li>
<li>
<label><input type="checkbox" class="categorycheckbox">Group 2</label>
<ul>
<li>
<label><input type="checkbox" class="productcheckbox">Item 1</label>
</li>
<li>
<label><input type="checkbox" class="productcheckbox">Item 2</label>
</li>
</ul>
</li>
</ul>
And so on. I'm using jQuery to give the users the ability to select/deselect all child inputboxes, like this:
var updateCheckedState = function () {
var list = $(this).closest("li").find("ul");
$(".productcheckbox", list).attr("checked", this.checked);
};
$(".categorycheckbox").change(updateCheckedState);
This works for checking once and unchecking once for each group. Then it stops working, and I don't understand why. I've created a fiddle: http://jsfiddle.net/AQ76y/

use prop instead of attr.
$(".productcheckbox", list).prop("checked", this.checked);
Fiddle
Because sometimes updating the attribute does not update the element property but using an prop and updating the property it is ensured that it will work across browsers.
In earlier verisons of jquery attr used to do the work of prop, so it used to work then

Related

Modify text of next element from id

My HTML:
<li>
<input type="checkbox" id="check-1">
<label for="check-1">foo</label>
</li>
I am trying to change "foo" to "bla" with this JS code:
$("#check-1 label").text("bla");
but nothing happens and I am getting no errors. I also tried with :first-child.
Any ideas?
You can use this
$('label[for=check-1]').text('bla');
The label is not a child of the input. It's the next element:
$("#check-1").next().text('bla');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
<input type="checkbox" id="check-1">
<label for="check-1">foo</label>
</li>
In input there is not child elements, you can use $.next to get next element after input
$("#check-1").next('label').text('bla');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
<input type="checkbox" id="check-1">
<label for="check-1">foo</label>
</li>
try this
$("#check-1 + label").text("bla");

Checkbox - Getting multiple check boxes checked on checking only one

I am trying to implement a check box which checks all the check boxes on the page. But when I changed the code slightly, it stopped working. I want to keep the changed code and still want the functionality to be working. Kindly help!
* Kindly ignore the missing tags if any. It is correct unless I made mistake in editing the question.
<script>
function toggle(source) {
checkboxes = document.getElementsByName('qchecked[]');
for(var i=0, n=checkboxes.length;i<n;i++){
checkboxes[i].checked = source.checked;
}
}
</script>
<html>
/* Code for the check box which when checked, checks all the checkbox. */
<input type='checkbox' class='css-checkbox' id='checkbox' onClick='toggle(this)'/>
<label for='checkbox' class='css-label lite-y-green'></label>
/* Code for the check boxes which should be checked when the check box with id=checkbox is checked.
I changed the code from INITIAL CODE to CHANGED CODE for some other purpose and the toggle stopped working.
Now clicking on that one check box is not marking or un marking all the check boxes. */
<!-- INITIAL CODE -->
<input type='checkbox' id='yes_checkbox[$index]' class='css-checkbox' name='qchecked[]'/>
<label for='yes_checkbox[$index]' class='css-label lite-y-green'></label>
<!-- CHANGED CODE -->
<input type='checkbox' id='yes_checkbox[$index]' class='css-checkbox' name='qchecked[$array6[qID]]'/>
<label for='yes_checkbox[$index]' class='css-label lite-y-green'></label>
</html>
Instead of name, give a class to all elements and you should use by
getElementsByClassName('your_class');
Since you name of inputs are different, you can make use of common class
checkboxes = document.getElementsByClassName('css-checkbox');
Try this..
<ul class="chk-container">
<li><input type="checkbox" id="selecctall"/> Selecct All</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item1"> This is Item 1</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item2"> This is Item 2</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item3"> This is Item 3</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item4"> This is Item 4</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item5"> This is Item 5</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item6"> This is Item 6</li>
<li><input class="checkbox2" type="checkbox" name="check[]" value="item6"> Do not select this</li>
</ul>
$(document).ready(function() {
$('#selecctall').click(function(event) { //on click
if(this.checked) { // check select status
$('.checkbox1').each(function() { //loop through each checkbox
this.checked = true; //select all checkboxes with class "checkbox1"
});
}else{
$('.checkbox1').each(function() { //loop through each checkbox
this.checked = false; //deselect all checkboxes with class "checkbox1"
});
}
});
});
demo:https://jsfiddle.net/go1gL743/

finding value of closest hidden field, located above user click in javascript

I'm trying to grab the value of a hidden field that resides above each group of LI's with javascript, I cannot use jQuery because of an unreasonable client's concerns (believe me, I've tried, they just don't want to "risk" adding a library)... anyway...
The list would look something like this:
<input id="hidden1" type="hidden" value="5" class="includeds">
<h3>header</h3>
<ul class="groups">
<li><input id="li1" type="checkbox" value="1" onclick="value()"></li>
<li><input id="li2" type="checkbox" value="2" onclick="value()"></li>
<li><input id="li3" type="checkbox" value="3" onclick="value()"></li>
</ul>
<input id="hidden2" type="hidden" value="3" class="includeds">
<h3>header2</h3>
<ul class="groups">
<li><input id="li4" type="checkbox" value="4" onclick="value()"></li>
<li><input id="li5" type="checkbox" value="5" onclick="value()"></li>
<li><input id="li6" type="checkbox" value="6" onclick="value()"></li>
</ul>
So if I click on checkbox li1, I want to retrieve the value "5" from the hidden field above it.
If I click li5, I want to get the value of "2" from the first hidden field above it, etc, etc.
in a previous SO question some amazing people helped me do this with jQuery:
if($(this).closest('ul').prevAll('.includeds:first').val() !== '0') {
// logic here
}
but when presented to the client, I ran into the aforementioned complaints. So now I need to do the same thing with javascript vanilla. I appreciate any help or pointers you guys could provide. I apologize for asking the same question twice, between jquery and javascript.
Uhm, the jQuery code I'd use would be:
$(this).parent().prev().prev().val()
With that in mind, all you have to do is rewrite the code to correct plain javascript entities.
The result would be something like:
function getParent(node){
return node.parentNode;
}
function getPrev(node){
do { // loop to find the previous node that is an element
node = node.previousSibling;
}while(node && node.nodeType != 1);
return node;
}
getPrev(getPrev(getParent(this))));
If you can't use jQuery then complex queries like the on you mentioned become much more difficult. In liue of jQuery it's easiest to reference elements by their ID tag or by a class filter (depending on the scenario).
Here i would say the best bet is to hard code the given input ID into the onclick function.
HTML
<input id="hidden2" type="hidden" value="3" class="includeds">
<h3>header2</h3>
<ul class="groups">
<li><input id="li4" type="checkbox" value="4" onclick="value('hidden2')"></li>
<li><input id="li5" type="checkbox" value="5" onclick="value('hidden2')"></li>
<li><input id="li6" type="checkbox" value="6" onclick="value('hidden2')"></li>
</ul>
JavaScript
function value(id) {
var elem = document.getElementByID(id);
...
}

how to get the checked box input value by jquery or javascript?

the input check box code:
<li class="odd"><input type="checkbox" class="forminput" name="VD10" checked="checked" value="http://test1.com">
example 1</li>
<li class="even><input type="checkbox" class="forminput" name="VD11" checked="checked" value="http://test2.com">
example 1</li>
<li class="odd"><input type="checkbox" class="forminput" name="VD12" checked="checked" value="http://test3.com">
example 1</li>........
the button code:
<li>
<input type="checkbox" id="checkall" name="checkall" checked="checked">
<label for="checkall">check all</label>
<input type="button" value="copy the checked link" class="button">
</li>
now, i want to do when click the copy the checked link button. it will copy the checked input value to the clipboard? how do i do?
Try this,
$(".button").click( function () {
var selectedCheckboxValue = "";
$('input.forminput:checked').each(function() {
selectedCheckboxValue += $(this).val() + ", ";
});
alert(selectedCheckboxValue);
});
click here see the working demo. http://jsfiddle.net/t5TKm/
You can't copy to the clipboard without flash, silverlight, or some other rich-client plugin.
But, here is the answer to that question: How do I copy to the clipboard in JavaScript?
And: How to retrieve checkboxes values in jQuery
You can use the document.getElementByTag('VD10').checked to check if the checkbox is checked or not

Showing/hiding divs based on checkbox using jQuery

I have a form with a checkbox (contained within a label #contact). For the change action of this checkbox, I am showing/hiding a div (#options).
To ensure that if the checkbox is checked the #options div always is always shown (and avoid the situation where checking the checkbox actually hides the subjequent options), I am using this code:
$('#contact :checkbox').is(':checked') ? $("#options").show() : $("#options").hide();
This works fine. The problem I have is that instead of a single checkbox with an ID, I want to have multiple checkboxes. I want to show/hide the next instance of my .hidden class based on whether the previous checkbox (within a label with the class .trigger) is checked or not. I have tried this:
$(document).ready(function() {
if( $('.trigger :checkbox').is(':checked') ) {
$(this).parent().nextAll('ul.hidden').show();
} else {
$(this).parent().nextAll('ul.hidden').hide();
}
});
But to no avail. The checkboxes are in an unordered list, like this:
<ul>
<li><label class="trigger"><input type="checkbox" name="02" /> Trigger 1</label>
<ul class="hidden">
<li><label><input type="checkbox" name="02-sub1" /> Normal</label></li>
<li><label><input type="checkbox" name="02-sub2" /> Normal</label></li>
</ul>
</li>
<li><label><input type="checkbox" name="02" /> Normal</label></li>
<li><label><input type="checkbox" name="03" /> Normal</label></li>
<li><label class="trigger"><input type="checkbox" name="04" /> Trigger 2</label>
<ul class="hidden">
<li><label><input type="checkbox" name="04-sub1" /> Normal</label></li>
<li><label><input type="checkbox" name="04-sub2" /> Normal</label></li>
</ul>
</li>
</ul>
I can't see where I'm going wrong here; presumably my selector is incorrect, but I've played around with the syntax for ages and not got anywhere. Thanks in advance (and thank you for reading this far).
You need to run your code inside a change handler, so this refers to the checkbox you want, like this:
$(document).ready(function() {
$('.trigger :checkbox').change(function() {
if( $(this).is(':checked') ) {
$(this).parent().nextAll('ul.hidden').show();
} else {
$(this).parent().nextAll('ul.hidden').hide();
}
});
});
...and that can be made much shorter with .toggle(bool), like this:
$(function() {
$('.trigger :checkbox').change(function() {
$(this).parent().nextAll('ul.hidden').toggle(this.checked);
});
});
If you need it to run when the page loads, so the show/hide states match the checkbox, just call that change handler with .change() (shortcut for .trigger('change')), like this:
$(function() {
$('.trigger :checkbox').change(function() {
$(this).parent().nextAll('ul.hidden').toggle(this.checked);
}).change();
});
You know you can roll your own fields, right? The typical way to do that is with a "rel=" field that has no meaning in HTML but can be picked up and used in jquery.
if ($('#contact :checkbox').is(':checked')) {
$("#" + $('#contact :checkbox').attr('rel')).show();
} else {
$("#" + $('#contact :checkbox').attr('rel')).hide();
}
And then:
<li><label class="trigger"><input type="checkbox" name="04" rel="hidden-04" /> Trigger 2</label>
<ul class="hidden" id="hidden-04">
<li><label><input type="checkbox" name="04-sub1" /> Normal</label></li>
<li><label><input type="checkbox" name="04-sub2" /> Normal</label></li>
</ul>
</li>
So then, when the checkbox named 04 is checked, we look in its rel field for the id of the object to hide() or show(). I think that's a LOT easier than trying to walk the dom to find the target object.

Categories

Resources