Link to home
Start Free TrialLog in
Avatar of Mitch Swetsky
Mitch SwetskyFlag for United States of America

asked on

Javascript to show or hide rows when a checkbox is selected

I have a section of an asp page with part of a table that needs to be dynamicly displayed.
If the checkbox ( chPrePost) is selected I do not want PP1-4 shown.
The code below does this  but when check box is deselected I want it shown again.
I need some help with a way to toggle the get element depending on checkbox checked or not.
I am a beginner in javascript and would appreciate any comments along with a potential solution.
<Table Name=PPEquip cellpadding="2" cellspacing="0">
<tr>
<td Colspan=3 bgcolor="#FFFFCC"><b>Pre & Post Finishing Equipment Details - Box to Stacker Only? </b><input type="checkbox" name="chPrePost" value="BoxStack" onclick="document.getElementById('PP1').style.display='none'; document.getElementById('PP2').style.display='none'; document.getElementById('PP3').style.display='none'; document.getElementById('PP4').style.display='none' "></td>
</tr>
 
 
<tr id="PP1" style="display: inline">
<td bgcolor="#FFFFCC" align="center">Make</td>
<td bgcolor="#FFFFCC" align="center">Model</td>
<td bgcolor="#FFFFCC" align="center">Description</td>
</tr>
<tr id="PP2" style="display: inline">
<td bgcolor="#FFFFCC" align="center"><input type="text" name="TxtPrePostMake1" size="20">&nbsp;</td>
<td bgcolor="#FFFFCC" align="center"><input type="text" name="TxtPrePostModel1" size="20">&nbsp;</td>
<td bgcolor="#FFFFCC" align="center"><input type="text" name="TxtPrePostDesc3" size="25">&nbsp;</td>
</tr>
<tr id="PP3" style="display: inline">
<td bgcolor="#FFFFCC" align="center"><input type="text" name="TxtPrePostMake2" size="20">&nbsp;</td>
<td bgcolor="#FFFFCC" align="center"><input type="text" name="TxtPrePostModel2" size="20">&nbsp;</td>
<td bgcolor="#FFFFCC" align="center"><input type="text" name="TxtPrePostDesc3" size="25">&nbsp;</td>
</tr>
<tr id="PP4" style="display: inline">
<td bgcolor="#FFFFCC" align="center"><input type="text" name="TxtPrePostMake3" size="20">&nbsp;</td>
<td bgcolor="#FFFFCC" align="center"><input type="text" name="TxtPrePostModel3" size="20">&nbsp;</td>
<td bgcolor="#FFFFCC" align="center"><input type="text" name="TxtPrePostDesc3" size="25">&nbsp;</td>
</tr>
</table>

Open in new window

Avatar of jmanGJHS97
jmanGJHS97

I would use an onBlur event to toggle the rows you want.

Something like this (notice I added an ID to the checkbox as well):
<input type="checkbox" name="chPrePost" id="chPrePost" value="BoxStack" onblur="toggleRows(this.id);" />
 
<script>
function toggleRows(checkboxID)
{
  if (document.getElementById(checkboxID).checked == true)
  {
    document.getElementById('PP1').style.display='block';
    document.getElementById('PP2').style.display='block'; 
    document.getElementById('PP3').style.display='block'; 
    document.getElementById('PP4').style.display='block';
  }
  else
  {
    document.getElementById('PP1').style.display='none';
    document.getElementById('PP2').style.display='none'; 
    document.getElementById('PP3').style.display='none'; 
    document.getElementById('PP4').style.display='none';
  }
}
</script>

Open in new window

sorry this was posted a million times.  the page freaked out when I submitted the comment.  dunno how it happened.
You seem quite attached to that answer jman.  I'm going to have to disagree though and suggest this (cleaned it up a bit):

<html>
<head>
 
<script type="text/javascript">
function toggleRows(checkBox)
{
  if (checkBox.checked == true)
  {
    document.getElementById('PPEquip').style.display='none';
 
  }
  else
  {
    document.getElementById('PPEquip').style.display='block';
 
  }
}
</script>
<style type="text/css">
#PPEquip{
	border-collapse:collapse;
	background-color:#FFFFCC;
	width:500px;
	text-align:center;
}
#PPEquipSelector{
	font-weight:700;
	background-color:#FFFFCC;
	width:500px;
}
</style>
 
</head>
<body>
 
<div id="PPEquipSelector">Pre & Post Finishing Equipment Details - Box to Stacker Only? <input type="checkbox" name="chPrePost" 
 
value="BoxStack" onclick="toggleRows(this);" /></div>
 
<Table ID="PPEquip">
<tr id="PP1" style="display: inline">
<th>Make</td>
<th>Model</td>
<th>Description</td>
</tr>
<tr id="PP2">
<td><input type="text" name="TxtPrePostMake1" size="20">&nbsp;</td>
<td><input type="text" name="TxtPrePostModel1" size="20">&nbsp;</td>
<td><input type="text" name="TxtPrePostDesc3" size="25">&nbsp;</td>
</tr>
<tr id="PP3">
<td><input type="text" name="TxtPrePostMake2" size="20">&nbsp;</td>
<td><input type="text" name="TxtPrePostModel2" size="20">&nbsp;</td>
<td><input type="text" name="TxtPrePostDesc3" size="25">&nbsp;</td>
</tr>
<tr id="PP4">
<td><input type="text" name="TxtPrePostMake3" size="20">&nbsp;</td>
<td><input type="text" name="TxtPrePostModel3" size="20">&nbsp;</td>
<td><input type="text" name="TxtPrePostDesc3" size="25">&nbsp;</td>
</tr>
</div>
</table>
 
</body>

Open in new window

Yeah, on occasion, when you submit a comment, the page spins for a while, and you end up with 15 copies of it.

As far as the code goes, wrapping divs and styles around a solution that does what the user asked for doesn't really qualify as a diagreement.  If the goal is to hide the entire table, then, sure, you can do that.  I was trying to address the question as it was written.

Maybe I misunderstood what Mswetsky was asking for, but I don't believe so.
Please reread my code.  I didn't wrap a div around anything preexisting.  I created it separately so the table could work with a single call to clean up the code.  It could easily be done by making it the TH and stepping through the TRs too.  Your example was using an onblur which should have been onclick. Also, you were passing just the id of the checkbox then having to scale through the DOM to find it again rather than just passing it directly.  And finally, your code was doing the opposite of what the asker was wanting.  

So, just a simple disagreement.
Yup, I stand corrected.  I should have done onClick and turned off the rows when the box is checked.
<input type="checkbox" name="chPrePost" id="chPrePost" value="BoxStack" onClick="toggleRows(this);" />
 
<script>
function toggleRows(checkbox)
{
  if (checkbox.checked == true)
  {
    document.getElementById('PP1').style.display='none';
    document.getElementById('PP2').style.display='none'; 
    document.getElementById('PP3').style.display='none'; 
    document.getElementById('PP4').style.display='none';
  }
  else
  {
    document.getElementById('PP1').style.display='block';
    document.getElementById('PP2').style.display='block'; 
    document.getElementById('PP3').style.display='block'; 
    document.getElementById('PP4').style.display='block';
  }
}
</script>

Open in new window

why the heck does it keep doing that?  that is so annoying!
Avatar of Mitch Swetsky

ASKER

Thank you both for the solutions and the reasons behind the different methods. I am trying to learn as I go so it helps to understand.

I only posted a small part of the page, The full page is a ridiculous form which actually has over 80 form fields. I tried to lay out many tables so I could structure the page and understand the data groupings.

I am somewhat confused by the Germ Post.
It looks like the Solution has the head in it, does this assume there is only one check box on the page?

My other question of confusion for Jman is with the following statement ( if (checkBox.checked == true) )
Does this work because of where it is put?  since it doesn't call the checkbox name?
Finally I am unfamiliar with the differences in Block, Inline or None. Is there an easy explanation?
I've used Inline and None but what's Block??
ASKER CERTIFIED SOLUTION
Avatar of GreatGerm
GreatGerm
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
No, it works because the function call passes the checkbox object to it, using:

<input type="checkbox" name="chPrePost" id="chPrePost" value="BoxStack" onClick="toggleRows(this);" />

toggleRows(this) sends "itself" to the JS function.  Then, the code knows that "this" is a checkbox, and you can access the checked attribute of that object.  Germ was dead on that this is easier than passing the name of the checkbox and then having the DOM look it up by name.

Make sense?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Two good guys helped with the solution and understanding, THank you both. Great Germ Included all of the code needed in a fashion easiset to pop in my page where as Jman's code needed to be used in addition to other code and I would need to figure where which parts go. As I mentioned I am unfamiliar with javascript and a beginned HTM code writer.
Thank you both again, Us newbies appreciate your assistance and insight.
GreatGerm
After using the code I realize it hides all the tr's in the table
Is there a way to add one more tr that is not hidden?
After the text boxes for Make Model Desc I need a row for comments where there will be another text area used, and that was why I initilly used tr id=
Sure, just to clarify, you have a footer row that's after all the entries you want to use that's not hidden?
Yes. A footer row would work fine
Wow,
I have been typing HTM intermittently for 8 years and never knew there was a footer row!
We could switch to the thead/tbody/tfoot method, but some browsers don't like it as much so I'm just going to add another tr and tell the script to ignore the last row.

<html>
<head>
 
<script type="text/javascript">
function toggleRows(checkBox){
  var tableArray = checkBox.parentNode.parentNode.parentNode.getElementsByTagName('tr');
  var i;
  if (checkBox.checked == true)
  {
    for(i=1;i<tableArray.length-1;i++){
      tableArray[i].style.display = "none";
    }
  }
  else
  {
    for(i=1;i<tableArray.length-1;i++){
      tableArray[i].style.display = "block";
    }
  }
}
</script>
<style type="text/css">
#PPEquip{
	border-collapse:collapse;
	background-color:#FFFFCC;
	width:500px;
	text-align:center;
	font-weight:700;
}
</style>
 
</head>
<body>
 
<table ID="PPEquip">
  <tr>
    <th colspan="3">Pre & Post Finishing Equipment Details - Box to Stacker Only? <input type="checkbox" name="chPrePost" value="BoxStack" onclick="toggleRows(this);" /></th>
  </tr>
  <tr>
    <td>Make</td>
    <td>Model</td>
    <td>Description</td>
  </tr>
  <tr>
    <td><input type="text" name="TxtPrePostMake1" size="20">&nbsp;</td>
    <td><input type="text" name="TxtPrePostModel1" size="20">&nbsp;</td>
    <td><input type="text" name="TxtPrePostDesc3" size="25">&nbsp;</td>
  </tr>
  <tr>
    <td><input type="text" name="TxtPrePostMake2" size="20">&nbsp;</td>
    <td><input type="text" name="TxtPrePostModel2" size="20">&nbsp;</td>
    <td><input type="text" name="TxtPrePostDesc3" size="25">&nbsp;</td>
  </tr>
  <tr>
    <td><input type="text" name="TxtPrePostMake3" size="20">&nbsp;</td>
    <td><input type="text" name="TxtPrePostModel3" size="20">&nbsp;</td>
    <td><input type="text" name="TxtPrePostDesc3" size="25">&nbsp;</td>
  </tr>
  <tr>
    <td colspan="3">This is the footer</td>
  </tr>
</table>
 
</body>

Open in new window

Actually I am lucky that this is on an intranet site and all users use IE 6+
Amazing! so what lines in the code above are you counting rows?

Can you suggest how I can become better able to use and create these type tasks?
Is a javascript class/book or an htm class/book or will experience be my only teacher (then I am doomed)?
This line finds the rows: for(i=1;i<tableArray.length-1;i++){

With javascript you start counting at 0 so I told the loop to start at 1 (i=1) which would be the second row. Then I told it to go until it reached 1 before the last row (i<tableArray.length-1) since tableArray holds the rows objects in order for me.

While it's not the end all, or even the middle in some cases, w3schools (http://www.w3schools.com) is a great reference and will help you with a multitude of topics.
Yeah, I am.