Select all checkboxes JS toggle issue - javascript

Hoping someone can help me overcome my Javascript ignorance.
I've got a form that includes checkboxes and I've got a piece of JS that toggles selecting/deselecting all the boxes. And so far, it all works as expected.
The wrench in the works is that I've got multiple groups of checkboxes in this form and I would like to select/deselect by group, not all the checkboxes in the form. This is a sample of the php and html. As you can see, the form is in a table and there is a checkbox in the header row that performs the action. 'resources_req' is the name of the checkbox element in the form
<form method="post" name="add_reservation">
<?php for($x=0; $x<count($groups); $x++) : // make seperate display for each group ?>
<div class="group_<?php echo $group_label; ?>">
<table class="res">
<tr>
<!-- form: checkbox all -->
<?php if($make_res == 'enter') : // adds checkbox to check all ?>
<th><input type="checkbox" onClick="toggle(this, 'resources_req[]')" /></th>
<?php endif; ?>
<!-- end form: checkbox all -->
</tr>
...
foreach($resources as $resource) { // for each resource/laptop
$form_start = '<td>';
$form_start .= '<input type="checkbox" name="resources_req[]" value="'.$resource['id'].'"';
$form_start .= ' />';
$form_start .= '</td>';
}
...
</table>
</div>
<?php endfor; // loop for each group ?>
<input type="submit" name="add_reservation" value="Make this reservation" />
</form>
Here is the JS being called:
function toggle(source, element) {
checkboxes = document.getElementsByName(element);
for(var i in checkboxes)
checkboxes[i].checked = source.checked;
}
Best I can put together, the 'this' in the script call is referring to the form. I thought if maybe I put each of these groups in to their own div class, I could then somehow refer to just that but now I'm just lost. Any help or suggestions appreciated!
EDIT: I asked for suggestions and it's been suggested I post only the html:
<form method="post" name="add_reservation">
<div class="group_A">
<table>
<tr>
<th><input type="checkbox" onClick="toggle(this, 'resources_req[]')" /></th>
<th>Name</th>
</tr>
<tr>
<td><input type="checkbox" name="resources_req[]" value="1" /></td>
<td>John</td>
</tr>
<tr>
<td><input type="checkbox" name="resources_req[]" value="2" /></td>
<td>Bill</td>
</tr>
<tr>
<td><input type="checkbox" name="resources_req[]" value="3" /></td>
<td>Fred</td>
</tr>
</table>
</div>
<div class="group_b">
<table>
<tr>
<th><input type="checkbox" onClick="toggle(this, 'resources_req[]')" /></th>
<th>Name</th>
</tr>
<tr>
<td><input type="checkbox" name="resources_req[]" value="4" /></td>
<td>George</td>
</tr>
<tr>
<td><input type="checkbox" name="resources_req[]" value="5" /></td>
<td>Tom</td>
</tr>
<tr>
<td><input type="checkbox" name="resources_req[]" value="6" /></td>
<td>Raymons</td>
</tr>
</table>
</div>
<input type="submit" name="add_reservation" value="Make this reservation" />
</form>

I changed a few things:
First, instead of passing the value of name, I'm passing the tagName of 'input' instead.
<input type="checkbox" onClick="toggle(this, 'input')" />
Then in the toggle() function, I select the parentNode of the source element, and do a getElementsByTagName() so that I only get the input elements in the local div.
Also, I changed the for-in loop to a standard for loop, which is the proper type of loop to iterate over indexed elements. The for-in can actually give some problems.
function toggle(source, element) {
var checkboxes = source.parentNode.getElementsByTagName(element);
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = source.checked;
}
}
Live Example: http://jsfiddle.net/37mT2/
Alternatives:
Instead of parentNode, select the ancestor <div> element by assigning it an ID, and passing it to your toggle() function.
<input type="checkbox" onClick="toggle(this, 'input', 'someUniqueId_1')" />
<input type="checkbox" onClick="toggle(this, 'input', 'someUniqueId_2')" />
function toggle(source, element, id) {
var checkboxes = document.getElementById( id ).getElementsByTagName('input');
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = source.checked;
}
}
Or you could traverse up the parent nodes until you reach your first <div> element:
<input type="checkbox" onClick="toggle(this, 'input')" />
function toggle(source, element) {
while( source && source = source.parentNode && source.nodeName.toLowerCase() === 'div' ) {
; // do nothing because the logic is all in the expression above
}
var checkboxes = source.getElementsByTagName('input');
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = source.checked;
}
}
Or you could give the <div> elements at that level a common class name and traverse up the parent nodes until you reach that class. In the code below, your <div> elements class is "someClassName":
<input type="checkbox" onClick="toggle(this, 'input')" />
function toggle(source, element) {
while( source && source = source.parentNode && source.className === 'someClassName' ) {
; // do nothing because the logic is all in the expression above
}
var checkboxes = source.getElementsByTagName('input');
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = source.checked;
}
}
EDIT: Fixed a typo. I had getElementsById instead of getElementById.

Best I can put together, the 'this' in the script call is referring to the form. I thought if maybe I put each of these groups in to their own div class, I could then somehow refer to just that but now I'm just lost. Any help or suggestions appreciated!
http://jsfiddle.net/JG4uf/
JavaScript Loops: for...in vs for

Related

How to sum value of checked changed checkbox jquery?

I have a table, each checkbox contains a value, and I want to sum value of the checkbox.
Example:
Candy and Water is checked : count = 2 , Candy, food and water is checked : count = 5 , checkbox is unchecked : count = 0 .
I think i must two event , event of each checkbox (.checkbox1) and event of checkbox (.check_all).
Javascript
var count = 0;
$(".checkbox1").change(function() {
var table_abc = document.getElementsByClassName("checkbox1");
for (var i = 0; table_abc[i]; ++i) {
if (table_abc[i].checked) {
count += table_abc[i].value;
}
}
});
alert(count);
HTML
<table id="div_table">
<thead>
<tr>
<th><input type="checkbox" class="check_all" id="chk_all" /></th>
<th>Check All</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" class="checkbox1" id="candy" value="2" /></td>
<td>Candy</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox1" id="food" value="3" /></td>
<td>Food</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox1" id="water" value="0" /></td>
<td>Water</td>
</tr>
</tbody>
</table>
But it seems not working. Can you tell me how to wrong?
here is your script, a little bit improved
i'm using here the jquery .prop() method to get the checked property of each element,
and instead of performing concatenation directly with the value of count
you have to use Number(number) or parseInt(number,base) in order to tell js engine, hey i want it to be an arithmetic operation and not a concatenation
here is your snippet of code improved :
$(document).ready(function(){
var count;
$(".checkbox1").change(function() {
count = 0;
var table_abc = $('.checkbox1');
for (var i = 0; i < table_abc.length ; ++i) {
if ($(table_abc[i]).prop('checked')) {
count += parseInt($(table_abc[i]).val(),10);
}
}
console.log(count);
});
});
we are logging to the screen the value of count each time a checkbox(with class checkbox1) state is changed
First I moved declaration of variable count inside the change function to avoid invalid value in repeating the checked-unchecked
Then you should cast the value of checkbox to a numeric so your summation gives correct values
check this fiddle, it works
Use below snippets of code
var count = 0;
$('input[type="checkbox"]').on("change", function() {
count = 0;
if($(this).hasClass('check_all')){
$('input[type="checkbox"][class="checkbox1"]').prop('checked',true);
$('input[type="checkbox"][class="checkbox1"]').each(function(){
count += parseInt($(this).val());
});
}else{
$('input[type="checkbox"]:checked').each(function(){
count += parseInt($(this).val());
});
}
alert(count);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table id="div_table" >
<thead>
<tr>
<th><input type="checkbox" class="check_all" id="chk_all" /></th>
<th>Check All</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" class="checkbox1" id="candy" value="2" /></td>
<td>Candy</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox1" id="food" value="3" /></td>
<td>Food</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox1" id="water" value="0" /></td>
<td>Water</td>
</tr>
</tbody>
</table>
Your javascript code seems wrong. Try following
$(document).ready(function(){
$(".checkbox1").change(function() {
var count = 0;
var table_abc = document.getElementsByClassName("checkbox1");
for (var i = 0; table_abc[i]; ++i) {
if (table_abc[i].checked) {
count += parseInt(table_abc[i].value);
}
}
alert(count);
});
});
You can easily iterate over all your checkboxes using the jquery .each function like this:
(function($){
$("input[name='opt']").change(function() {
count = 0;
$("input[name='opt']").each(function(index, checkbox){
if(checkbox.checked)
count += parseInt(checkbox.value) // convert to integer
})
alert(count);
});
})(jQuery);
Few things to pay attention to:
$("input[name='opt']").change binds all the input checkboxes with name='opt' to the provided event handler.
The count variable is moved inside the change event handler, because it needs to be reset to 0 and re-calculated everytime a checkbox is changed.
$("input[name='opt']").each(function(index, checkbox) iterates through all the input checkboxes with name='opt'.
To correctly sum the values, you will need to use parseInt to convert your string value to integer.
Instead of using class="checkbox1", I use name='opt' in my codes to group all the checkboxes together.
Check out this fiddle for complete HTML and JS codes.

Javascript "check all" a subset of multiple checkbox groups

My checkbox group are in html table. Each row has checbox group. I am trying to put a select_all button in each row of table (which can select all or unselect all the checkbox of that particular row). I used javascript for the purpose. However, select all button checks all the checkbxes of the table. I couldnt find a way to select_all button applicable to only single row. Any idea?
I think the change in javascript can solve this prob, but I am unfamiliar with javascript orjquery.
function checkAll(bx) {
var cbs = document.getElementsByTagName('input');
for (var i = 0; i < cbs.length; i++) {
if (cbs[i].type == 'checkbox') {
cbs[i].checked = bx.checked;
}
}
}
<form action="backend.php" method="POST" target="iframe_3">
<table border="10" width="900" bordercolor="green">
<tr>
<td colspan="3" style="background-color:#7F77AE">DNA</td>
<td><input type="checkbox" name="check_list[]" value="value 1">seq</td>
<td><input type="checkbox" name="check_list[]" value="value 2">codon</td>
<td><input type="checkbox" onclick="checkAll(this)">Select_all</td>
</tr>
<tr>
<td colspan="3" style="background-color:#7F77AE">RNA</td>
<td><input type="checkbox" name="check_list2[]" value="value 3">seq</td>
<td><input type="checkbox" name="check_list2[]" value="value 4">codon</td>
<td><input type="checkbox" onclick="checkAll(this)">Select_all</td>
</tr>
</table>
Using jQuery, this is a kind of trivial task. You actually just need to query for the <input> nodes within you specific <tr> node.
function checkAll(bx) {
var cbs = $( bx ).closest( 'tr' ).find( 'input:checkbox' );
for(var i=0; i < cbs.length; i++) {
if(cbs[i].type == 'checkbox') {
cbs[i].checked = bx.checked;
}
}
}
Without jQuery, this would look like
function checkAll(bx) {
var cbs = bx.parentNode.parentNode.querySelectorAll( 'input[type="checkbox"]' );
for(var i=0; i < cbs.length; i++) {
if(cbs[i].type == 'checkbox') {
cbs[i].checked = bx.checked;
}
}
}
jQuery way:
$(this).closest('tr').find('input[type=checkbox]').prop('checked', true);
fiddle
check this
<tr>
<td colspan="3" style="background-color:#7F77AE">DNA</td>
<td><input type="checkbox" name="check_list[]" value="value 1">seq</td>
<td><input type="checkbox" name="check_list[]" value="value 2">codon</td>
<td><input type="checkbox" onclick="checkAll(this)" id="check_list" role="selectall">Select_all</td>
</tr>
<tr>
<td colspan="3" style="background-color:#7F77AE">RNA</td>
<td><input type="checkbox" name="check_list2[]" value="value 3">seq</td>
<td><input type="checkbox" name="check_list2[]" value="value 4">codon</td>
<td><input type="checkbox" onclick="checkAll(this)" id="check_list2" role="selectall">Select_all</td>
</tr>
</table>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script type="text/javascript">
(function($){
$(document).ready(function(e) {
$('[role="selectall"]').each(function(){
// + handle click of select all
$(this).bind('click.selall', handleSelectAll);
var group_name = $(this) .attr('id')+'[]';
$('[name='+group_name+']').bind('click.single', handleSingle);
})
});
function handleSingle(){
var grp_name = $(this).attr('name');
var sel_all_id = grp_name.replace('[','').replace(']', '');
if( $('[name='+grp_name+']').length == $('[name='+grp_name+']:checked').length){
$('#'+grp_name).prop('checked', true);
}else{
$('#'+grp_name).prop('checked', false)
}
}
function handleSelectAll(){
var group_name = $(this) .attr('id')+'[]';
if( $(this).is(':checked')){
$('[name='+group_name+']').prop('checked', true);
}else{
$('[name='+group_name+']').prop('checked', false);
}
}
})(jQuery)
</script>
the key is the id of the select all check box is same as the group name without paranthesis

Disable Or Enable Checkbox Array Using Javascript

I have Following codes:
<html>
<head>
</head>
<body>
<table>
<tr>
<td>
<input type="checkbox" name="ck[]" value="sakit">
</td>
<td>
<input type="checkbox" name="ck[]" value="izin">
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="ck[]" value="sakit">
</td>
<td>
<input type="checkbox" name="ck[]" value="izin">
</td>
</tr>
</table>
</body>
</html>
How can i disable checkbox in first tr element without make changes in second tr, otherwise i can disable checkbox in second tr element without make changes in first tr?
You can use document.querySelector to target elements using a css selector.
For targeting the first <tr>
document.querySelector('tr:first-child input').disabled = true;
or for targeting the second <tr>
document.querySelector('tr:last-child input').disabled = true;
You can simply disable a checkbox with: CheckboxObject.disabled = true;
In HTML you all you have to do is:
<input type="checkbox" name="ck[]" value="sakit" disabled>
in JS you would do this:
var fields = document.getElementsByTagName("input");
for (var i = 0; i < fields.length; i++) {
if (fields[i].type == "checkbox")
fields[i].disabled = true;
}
this would disable the first checkbox on page.. if you need something different, let me know.

Grab a certain table row

I have a table with a radio button per row.
<table id="t1">
<tr><td><input type="radio" onclick="grab_row()" value=1></td><td>Data1<td>Data11</td></tr>
<tr><td><input type="radio" onclick="grab_row()" value=2></td><td>Data2<td>Data22</td></tr></table>
I would like to have a function that grabs the values of the row selected via radio.
my function:
function grab_row () {
var radio = $("input[name=t1]:checked").val();
}
The function only grabs the radio id that is currently selected.
for example, if the first radio is clicked, Data1 and Data11 are returned.
Thanks
Here's my interpretation of what you're looking for
html
<table>
<tr>
<td>
<input type="radio" value="1" name="myradio" />
</td>
<td>Data1</td>
<td>Data11</td>
</tr>
<tr>
<td>
<input type="radio" value="2" name="myradio" />
</td>
<td>Data2</td>
<td>Data22</td>
<td>Data222</td>
</tr>
js
$("input:radio[name=myradio]").click(function () {
var myvals = [];
var elem = $(this).parent().next();
while (elem.prop("tagName") == "TD") {
myvals.push(parseInt(elem.html().substring(4)));
elem = elem.next();
}
console.log(myvals);
});
I assumed that you just need the integers after the "Data" string, but you can grab the entire content of the TD element with just the .html() and leaving out the .substring(4)
fiddle
When you use .val() when using a selector that returns multiple elements, it will only return the value of the first element. Instead, you need to iterate through them using .each().
var values = [];
$("input[name=t1]:checked").each(function(idx, val) {
//spin through and collect each val
values.push($(val).val());
})
console.log(values); //view values in console
This should be your jQuery:
$("input[type=radio]").click(function () {
console.log($(this).val());
});
and this should be your HTML:
<table id="t1">
<tr>
<td>
<input type="radio" name="foo" value="1" />
</td>
<td>Data1</td>
<td>Data11</td>
</tr>
<tr>
<td>
<input type="radio" name="foo" value="2" />
</td>
<td>Data2</td>
<td>Data22</td>
</tr>
</table>
jsFiddle example
Note that you can also use $("input[name=foo]") instead of $("input[type=radio]").

Change style display for cells with Javascript

I want to do something like this: user selects one radio button (lock,delete or compare).
I want to show to him only the relevant column from the table. (each option has different column). The table is ajax.
I guess i need to change the display style for every cell but i don't know how.
Here is example:
Here i want to change the display of the cells
function ButtonForTbl(value) {
var x=document.getElementById("audithead").rows[0].cells;
if (value == "lock"){
document.getElementById('lock').checked = true;
//something like for(...)lockCell.style.display=''
//something like for(...)deleteCell.style.display='none'
//something like for(...)compareCell.style.display='none'
}
else if(value == "delete"){
document.getElementById('delete').checked = true;
//something like for(...)lockCell.style.display='none'
//something like for(...)deleteCell.style.display=''
//something like for(...)compareCell.style.display='none'
}
else{
document.getElementById('compare').checked = true;
}
}
I guess i need something like that:
for (i = 0; i < deleteCell.length; i++)
deleteCell[i].style.display='' = true ;
The table:
oCell = oRow.insertCell(-1);
oCell.setAttribute('id','comCell' );
oCell.setAttribute('align', 'center');
oCell.innerHTML = "<input type='checkbox' id='com' value='"+ ind + "'name='com[]'>";
oCell = oRow.insertCell(-1);
oCell.setAttribute('id','lockCell' );
oCell.setAttribute('align', 'center');
oCell.innerHTML = "<input type='checkbox' id='lock' value='"+ ind + "'name='lock[]'>";
Radio buttons:
<input type="radio" value="compare" id="compare" name="choose" onclick="ButtonForTbl(this.value)"/> Compare
<input type="radio" value="delete" id="delete" name="choose" onclick="ButtonForTbl(this.value)"/> Delete
<input type="radio" value="lock" id="lock" name="choose" onclick="ButtonForTbl(this.value)"/> Lock<br/>
The table html:
<table class="auditable">
<thead id="audithead">
<tr><td></td></tr>
</thead>
<tbody id="auditTblBody">
</tbody>
</table>
EDIT:
Full row is like that:
<tr>
<td align="center" id="lockCell" style="display: none;">
<input type="checkbox" onclick="" name="lock[]" value="1500" id="lock"></td>
<td align="center" id="delCell" style="display: none;">
<input type="checkbox" name="del[]" value="1500"></td>
<td align="center" id="comCell">
<input type="checkbox" onclick="setChecks(this)" name="com[]" value="1500" id="com"></td>
<td width="65px">100% 1/1</td><td width="105px">2011-01-10 17:47:37</td>
</tr>
Thank you so much!
You can do the same thing with a div or any other element. The javascript would look like:
<script language='javascript'>
<!-- //
function setProperties(obj)
{
if(obj.value == "yes")
{
document.mydiv.style.display = "block";
} else {
document.mydiv.style.display = "none";
}
}
// -->
</script>
And in the body:
<input type=radio name="update" value="yes" checked onclick="setProperties(this)">Yes<br />
<input type=radio name="update" value="no" onclick="setProperties(this)">No<br />
<div id='mydiv'>some text here</div>

Categories

Resources