I'm having issues with some JS code that hides columns based off the state of a checkbox, and I'm hoping to get some help.
The check boxes are in a table. The table has multiple rows. eg:
1, 2
3, 4
Those check boxes correspond to columns in another maintable. That maintable is a single row across. eg: 1, 2, 3, 4
When I uncheck boxes 1 & 2 from the the table, it hides row 1 & 2 from the main table. But if I uncheck boxes 3 & 4, it also hides row 1 & 2.
If the check boxes from the table are on a single line, then they hide all the columns as intended. But because they are broken up via table-row, there is an issue.
$(function() {
$("#checkboxes input[type=checkbox]").on("change", function(e) {
var id = $(this).parent().index()+1,
col = $("#table tr th:nth-child("+id+"), #table tr td:nth-child("+id+")");
$(this).is(":checked") ? col.show() : col.hide();
}).prop("checked", true).change();
});
Here is a fiddle. Any help will be greatly appreciated.
https://jsfiddle.net/o6e3pc3a/7/
Thanks
You have a problem with the table rows when you call to $(this).parent().index()+1 beacause you have the <td> tag in two rows which means that it is going to return the position inside <tr> and in every new <tr> the count start in 1 again.
You have two solutions for that:
1- You can put all the checkboxes inside one row:
<tr>
<td><input type="checkbox" name="option1" value="eventid" />Name</td>
<td><input type="checkbox" name="option2" value="groupid" />ID</td>
<td><input type="checkbox" name="option3" value="pathfile" />Type</td>
<td><input type="checkbox" name="option4" value="filesize" />Number</td>
</tr>
Here's an example JS Fiddle Example 1
2- Or you can just add an attribute data-id with the value of the column's position:
<tr>
<td><input type="checkbox" data-id="1" name="option1" value="eventid" />Name</td>
<td><input type="checkbox" data-id="2" name="option2" value="groupid" />ID</td>
</tr>
<tr>
<td><input type="checkbox" data-id="3" name="option3" value="pathfile" />Type</td>
<td><input type="checkbox" data-id="4" name="option4" value="filesize" />Number</td>
</tr>
And then catch it in js:
$(function() {
$("#checkboxes input[type=checkbox]").on("change", function(e) {
var id = $(this).attr('data-id'),
col = $("#table tr th:nth-child("+id+"), #table tr td:nth-child("+id+")");
$(this).is(":checked") ? col.show() : col.hide();
}).prop("checked", true).change();
});
Here's an example JS Fiddle Example 2
If you don't mind the style of the page I recommend de first one. If not, the second one is more dynamic
Agree with #joac omf .
Because the <chekcbox> are the childen of <td> tags. They are not sibling, so the index is incorrect.
The index is 'incorrect' because you have the checkboxes split into two table rows.
Put the checkboxes in one row <tr> and they work correctly.
<tr>
<td><input type="checkbox" name="option1" value="eventid" />Name</td>
<td><input type="checkbox" name="option2" value="groupid" />ID</td>
<td><input type="checkbox" name="option3" value="pathfile" />Type</td>
<td><input type="checkbox" name="option4" value="filesize" />Number</td>
</tr>
https://jsfiddle.net/o6e3pc3a/8/
Related
i'm just learned the javascript. i'm trying to make a simple front-end for practice. so, i've been struggling to select all checkbox inside 'td'.
<table>
<tr class="top1000">
<td><input type="checkbox" onclick="ropangTopping()"><label>milo</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>chocolate</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>chocochip</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>koko krunch</label></td>
</tr>
<tr class="top3000">
<td><input type="checkbox" onclick="ropangTopping()"><label>mozarella</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>cheddar</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>green tea</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>boba</label></td>
</tr>
</table>
when i initialized with this var topping1000 = document.querySelector(".top1000 td input[type=checkbox]");, it just select the first checkbox. but when i use querySelectorAll it didn't select anything. i know this is a silly question. any answer would be appriciated it. thanks in advance.
You're almost there. You do need to use
querySelectorAll()
to grab all the nodes.
But then you need to loop through those nodes and check each one in turn.
One way to do this (there are several) might be to use a forEach loop:
toppings1000.forEach((topping1000) => {topping1000.checked = true;});
N.B. Note the names of the variables I'm using immediately above. I'm distinguishing between the collection of multiple nodes (toppings1000):
toppings1000 // with an 's' to indicate that it's a plural set
and the individual node in each iteration of the forEach loop (topping1000):
topping1000 // no 's' this time - it's just a single node
Working Example:
var toppings1000 = document.querySelectorAll(".top1000 td input[type=checkbox]");
toppings1000.forEach((topping1000) => {
topping1000.checked = true;
});
<table>
<tr class="top1000">
<td><input type="checkbox" onclick="ropangTopping()"><label>milo</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>chocolate</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>chocochip</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>koko krunch</label></td>
</tr>
<tr class="top3000">
<td><input type="checkbox" onclick="ropangTopping()"><label>mozarella</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>cheddar</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>green tea</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>boba</label></td>
</tr>
</table>
I have a html template with one ng-repeat nested inside a parent ng-repeat. The parent ng-repeat contains radio button where the user can select 'Satisfied' or Unsatisfied' which correspond to values 1 and 0 respectively. If a user selects Unsatisfied, a detailed list of options is displayed so they can select more radios for further info. Here's the html;
<div class="group" ng-repeat="group in Groups">
<table>
<tr>
<td>{{group.Description}}</td>
<td><input type="radio" value="1" name="{{group.Id}}" ng-model="group.SatisfactionLevel" /></td>
<td><input type="radio" value="0" name="{{group.Id}}" ng-model="group.SatisfactionLevel" /></td>
</tr>
</table>
<div class="group-detail" ng-class="{'hidden': group.SatisfactionLevel != 1}">
<table>
<tr ng-repeat="item in group.Details">
<td>{{item.Description}}</td>
<td><input type="radio" value="1" name="{{item.Id}}" ng-model="item.SatisfactionLevel" /></td>
<td><input type="radio" value="0" name="{{item.Id}}" ng-model="item.SatisfactionLevel" /></td>
</tr>
</table>
</div>
The json returned from the server looks like this;
"Groups": [
{
"Id":"AA",
"Description":"Service",
"SatisfactionLevel":1,
"Details":[{"Id":"AA1","Description":"Cleanliness","SatisfactionLevel":1},
{"Id":"AA2","Description":"Timeliness","SatisfactionLevel":1}
]
},
{
"Id":"AB",
"Description":"Food",
"SatisfactionLevel":1,
"Details":[{"Id":"AB1","Description":"Price","SatisfactionLevel":1},
{"Id":"AB2","Description":"Portion","SatisfactionLevel":1}
]
}
]
Everything works except that the radio buttons in the nested ng-repeat are not checked. I can see in fiddler that the Satisfactionlevel property contains values. Anybody see where I'm going wrong? Thanks
UPDATE
There was really nothing wrong with the code. It turns out different items in Groups can contain the same Details items. Since I'm using name="{{item.Id}}" for the name attribute, other radios in other group details with the same name but different values were causing previous radios with the same name to get unchecked.
This was my fix;
<td><input type="radio" value="1" name="{{group.Id}}-{{item.Id}}" ng-model="item.SatisfactionLevel" /></td>
since group ids are unique.
First, you have the same value in both inputs - I'm guessing this is a typo?
Second, if you use value="1", it is interpreted as a string "1", but your model is an integer 1.
Instead, use ng-value:
<input type="radio" ng-value="0" name="{{item.Id}}" ng-model="item.SatisfactionLevel">
<input type="radio" ng-value="1" name="{{item.Id}}" ng-model="item.SatisfactionLevel">
I have a list of checkboxes that require one or two certain boxes to be checked in order to return true, however I am unsure how to go about finding if only the required boxes are checked and no other boxes are.
The HTML for the checkboxes are as follows:
<table style="width:135px; height:200px; margin: 0 auto; margin-top: -200px;">
<tr>
<td><input type="checkbox" class="f1s1c"></td>
<td><input type="checkbox" class="f1s2"></td>
<td><input type="checkbox" class="f1s3"></td>
<td><input type="checkbox" class="f1s4"></td>
</tr>
<tr>
<td><input type="checkbox" class="f2s1"></td>
<td><input type="checkbox" class="f2s2"></td>
<td><input type="checkbox" class="f2s3"></td>
<td><input type="checkbox" class="f2s4"></td>
</tr>
<tr>
<td><input type="checkbox" class="f3s1"></td>
<td><input type="checkbox" class="f3s2"></td>
<td><input type="checkbox" class="f3s3"></td>
<td><input type="checkbox" id="cCorrect1"></td>
</tr>
<tr>
<td><input type="checkbox" class="f4s1"></td>
<td><input type="checkbox" class="f4s2"></td>
<td><input type="checkbox" class="f4s3"></td>
<td><input type="checkbox" class="f4s4"></td>
</tr>
</table>
As you can see there are many possible chekboxes however in this case only cCorrect1 must be checked in order for the javascript to return true. All the other checkboxes are as classes as I have multiple tables that follow the same structure.
Currently my Javascript returns true if cCorrect1 is checked but obviously also returns true if any other box is also checked along with it.
My Javascript:
//Quiz Functions
$("#checkC").click(function(){
if(cCorrect1.checked){
cCorrect = true;
}else if(cCorrect1.checked == false){
cCorrect = false;
}
});
Would using an array that checks through the checkboxes and finds out when cCorrect1 is checked would work? I think that may be on the right track but I do not know how to go about that.
Any input and help is much appreciated.
Assuming you have a way to find the right set of checkboxes (a shared class on all of them, etc.) you can count the number of checked boxes in the list. If it's 1, and your target box is checked, you're good.
In this example, I added an id to the table containing the checkboxes to make them easier to find. Removed the style so the table is visible.
$("#checkC").click(function(){
// the one we want
var cCorrect1 = $('#cCorrect1');
// all checked checkboxes in the table
var checks = $('#boxes input[type=checkbox]:checked');
var cCorrect = cCorrect1.prop('checked') && (checks.length == 1);
alert(cCorrect ? "correct" : "incorrect");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="boxes" >
<tr>
<td><input type="checkbox" class="f1s1c"></td>
<td><input type="checkbox" class="f1s2"></td>
<td><input type="checkbox" class="f1s3"></td>
<td><input type="checkbox" class="f1s4"></td>
</tr>
<tr>
<td><input type="checkbox" class="f2s1"></td>
<td><input type="checkbox" class="f2s2"></td>
<td><input type="checkbox" class="f2s3"></td>
<td><input type="checkbox" class="f2s4"></td>
</tr>
<tr>
<td><input type="checkbox" class="f3s1"></td>
<td><input type="checkbox" class="f3s2"></td>
<td><input type="checkbox" class="f3s3"></td>
<td><input type="checkbox" id="cCorrect1"></td>
</tr>
<tr>
<td><input type="checkbox" class="f4s1"></td>
<td><input type="checkbox" class="f4s2"></td>
<td><input type="checkbox" class="f4s3"></td>
<td><input type="checkbox" class="f4s4"></td>
</tr>
</table>
<button id="checkC">check</button>
What you could do is create an array of right answers, discover the selected answers per row, and decide if it's "correct" or "incorrect".
You can use this code to return of array of checkboxes state (0 for unchecked, 1 for checked), and decide what to do from there:
var $table = this.$('tbody');
$(".resultBtn").click(function(){
var outStr = '';
for(var i= 0,len=$table.children().length;i<len;i++){
var $tr = $table.children().eq(i);
outStr += 'row' + (i+1) + ' checked boxes:[';
for(var j= 0;j<$tr.children().length;j++){
var $td = $tr.children().eq(j);
if($td.find(':checked').length > 0 ){
$td.addClass('selected');
outStr += '1,';
} else{
outStr += '0,';
}
if(j==$tr.children().length-1) outStr = outStr.substring(0, outStr.length - 1);
}
outStr += ']';
}
alert(outStr);
});
example:
http://jsfiddle.net/y3yp4ag1/2/
How can i find the next td element using jquery.
I am trying to append a text or a div to the td element inside a particular tr.
my tr is a server side control with tag runat=server
here is my query it is not working
var cssdisable= function testcss(rowid) {
if ($('#testcss').width() != 3) {
var id = $(rowid).find('td');
id.append('The following is not valid');
}
}
this is how i am calling the function with in a click event
cssdisable('<%=tr_myrow.ClientID %>');
It doesn't does anything, neither gives any error. i am trying to add a text after the td elemnent next to the row id passed.
Any ideas
here is the HTML
there is a row named tr_myrow
<table id="tblstudysub_animal" class="bond_qbs_table" width="100%">
<tr>
<td valign="top">
<h3>
Select the study subject.<span class="red">*</span></h3>
<fieldset>
<legend class="hide">Select the study subject.</legend>
<table id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj" border="0">
<tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_0" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_studysubj" value="Humans" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_0">Humans</label></td>
</tr><tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_1" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_studysubj" value="Non-Human primates" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_1">Non-Human primates</label></td>
</tr><tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_2" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_studysubj" value="Rodents" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_2">Rodents</label></td>
</tr><tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_3" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_studysubj" value="Others" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_3">Others</label></td>
</tr>
</table>
</fieldset>
</td>
</tr>
<tr id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_tr_myrow">
<td valign="top">
<div id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_studysub_popul">
<h3>
Select your study subject.<span class="red">*</span></h3>
<fieldset>
<legend class="hide">Select your study subject.</legend>
<table id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul" border="0">
<tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul_0" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_study_popul" value="Individuals" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul_0">Individuals</label></td>
</tr><tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul_1" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_study_popul" value="Population" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul_1">Population</label></td>
</tr>
</table>
<div id="testcss">
</div>
I ma trying to add that text to the td in that row...
i hope this makes more clear...
One issue is that you are trying to query for the td by its id but are not using the # at the start of the selector..
try cssdisable('#<%=tr_myrow.ClientID %>');
Also in order to stick to just the td child of the tr use .children() instead of .find('td') (which will find all descendant td elements)
so
var cssdisable = function testcss(rowid) {
if ($('#testcss').width() != 3) {
var id = $(rowid).children().first();
id.append('The following is not valid');
}
}
Demo at http://jsfiddle.net/D4z9b/ (using your example HTML)
Give your <td>..</td> elements meaningful ids during the table build phase (if you don't build it, just assign them before starting any processing using a separate call) and then generate the id. Something like tableName + '_' + row + '_' will probably should do you fine.
The reason not to use radio buttons here is because I want the option to have all checkboxes unchecked, and there are other behaviors linked to checking and unchecking.
When the 1st box is checked, all radio buttons in the row are selected.
(see here How to use javascript to select a row of radio buttons when a checkbox is selected)
When the 1st button is unchecked, all the radios in that row are deselected.
Whenever a checkbox is checked, the other checkbox should automatically be deselected.
I'm thinking maybe I could do this by css class. So, whenever one checkbox in the class is checked, the others are automatically unchecked.
I'm imagining code like this:
function uncheckOther(row_id) {
var row = document.getElementById(row_id)
var theClassName = row.className;
var classGroup = document.getElementsByClassName(theClassname);
for(var i=0; i<classGroup.length; i++) {
if(classGroup[i].id != row_id) {
classGroup[i].radio = unchecked;
}
}
}
How would I do this? Here's the example HTML with id's and classes in the tr elements, and checkboxes in the 1st child td elements:
<form name="form3" action="testfile4.php" method="get">
<table border="1"><thead>
<tr><th>Select entire row</th><th>item_code</th><th>page</th><th>usd_dn</th></tr>
</thead>
<tbody>
<tr id="534" class="15838">
<td ><input type="checkbox" onclick="select_row(534);"></td> <td>15838 <input type="radio" name="15838|item_code" value="534" /></td>
<td>284<input type="radio" name="15838|page" value="534" /></td>
<td>$73.00<input type="radio" name="15838|usd_dn" value="534" /></td>
</tr>
<tr id="535" class="15838">
<td ><input type="checkbox" onclick="select_row(535);"></td> <td>15838 <input type="radio" name="15838|item_code" value="535" /></td>
<td>299
<input type="radio" name="15838|page" value="535" /></td>
<td>$73.00<input type="radio" name="15838|usd_dn" value="535" /></td>
</tr>
<tr id="565">
<td ><input type="checkbox" onclick="select_row(565);"></td> <td>1611 <input type="radio" name="1611|item_code" value="565" /></td>
<td>66<input type="radio" name="1611|page" value="565" /></td>
<td>$3,350.00
<input type="radio" name="1611|usd_dn" value="565" /></td>
</tr>
<tr id="566">
<td ><input type="checkbox" onclick="select_row(566);"></td> <td>1611 <input type="radio" name="1611|item_code" value="566" /></td>
<td>66<input type="radio" name="1611|page" value="566" /></td>
<td>$3,225.00
<input type="radio" name="1611|usd_dn" value="566" /></td>
</tr>
</tbody>
</table>
</form>
I'm ok with jquery answers but prefer pure javascript at the moment.
There are plenty of reasons to use checkboxes instead of radio buttons...
if ($('#myDivID').attr('checked'))
This will tell you if it's checked. To loop through all, and keep only the current checked one checked, you could do something like this in the $(document).ready() function:
$('input[type="checkbox"]').click(function () {
$('input[type="checkbox"]').attr('checked', false);
$(this).attr('checked', true);
});
Any checkbox checked will STAY checked. The rest will be unchecked.
The native way would be to use the checked property that's on the checkbox dom object:
document.getElementById("checkboxId").checked = false;
Or, to toggle:
var cb = document.getElementById("checkboxId");
cb.checked = !cb.checked;
Here's the documentation for the checkbox dom object, if you're trying to not use jQuery.