Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

table row collapse prob

Status
Not open for further replies.

thompom

Technical User
Dec 4, 2006
395
GB
hi - i use the following function to make rows of a table show/hide when an image is clicked and change the image [from down to up arrow].
this worked fine but now i need the same effect on dynamic rows that are created within an asp loop.
i can change the id of each row with asp.

if my asp code helps let me know - the html below is the static rows

hope i make sense

Code:
<script>
//showhide
function showHide(inrow) {
   rowArr = inrow.split(",")
   for (x=0; x<rowArr.length; x++){
      theRow = document.getElementById(rowArr[x])
      theRow.style.display = theRow.style.display == "none" ? "block" : "none"
   }
}
function chgimg(obj) {
    obj.src=(obj.src.indexOf("showbut2.gif")!=-1)? "images/hidebut2.gif":"images/showbut2.gif";
}
</script>

static html
Code:
<input name=showhide type=image onClick=showHide('discrow1,discrow2');chgimg(this);return false; src=images/showbut2.gif width=13 height=9>

<table>
<tr id="discrow1" style="display: none;">
<td>...data</td>
</tr>
<tr id="discrow2" style="display: none;">
<td>...data</td>
</tr>
</table>

dynamic asp/html table
 
You're taking the long way about things by passing in the IDs of each of the rows for the showHide function. Make the following changes and it should work no matter how many rows you have for your table:
Code:
<script [!]type="text/javascript"[/!]>
//showhide
function showHide([!][s]inrow[/s][/!]) {
   rowArr = [!]document.getElementById("theTable").rows[/!];
   for (x=0; x<rowArr.length; x++){
      theRow = rowArr[x];
      theRow.style.display = theRow.style.display == "none" ? "block" : "none"
   }
}
function chgimg(obj) {
    obj.src=(obj.src.indexOf("showbut2.gif")!=-1)? "images/hidebut2.gif":"images/showbut2.gif";
}
</script>

Code:
<input name=showhide type=image onClick=showHide([!][s]'discrow1,discrow2'[/s][/!]);chgimg(this);return false; src=images/showbut2.gif width=13 height=9>

<table [!]id="theTable"[/!]>
<tr id="discrow1" style="display: none;">
<td>...data</td>
</tr>
<tr id="discrow2" style="display: none;">
<td>...data</td>
</tr>
</table>

And from the example that you've provided, wouldn't it just make more sense to set the display:none property on the entire table instead of doing only one row at a time? It would run worlds faster on larger tables.

-kaht

[small](All puppies have now found loving homes, thanks for all who showed interest)[/small]
 
hi kaht - thanks for your reply
was seeing if your example made a difference
but kept getting

'rowArr.length' isnull or not an object

...think i need to give a bit more background
because this may affect solution

This table contains makes of cars in stock with the models available underneath each make each in a row.
The model cells are hidden initially but when the showbutton is clicked the models available ae shown.
The showhide button is actually within a cell by each make. This is different from my example - sorry to change the situation

asp/html
Code:
<script type="text/javascript">
//showhide
function showHide(inrow) {
   rowArr = document.getElementById("theTable").rows;
   for (x=0; x<rowArr.length; x++){
      theRow = rowArr[x];
      theRow.style.display = theRow.style.display == "none" ? "block" : "none"
   }
}
function chgimg(obj) {
    obj.src=(obj.src.indexOf("showbut2.gif")!=-1)? "images/hidebut2.gif":"images/showbut2.gif";
}
</script>

response.Write("<table border=0 cellspacing=0 cellpadding=2><tr> <td colspan=4><span class=quickf>Quick</span><span class=finder>Finder</span><img src=images/quicklogo2.gif alt=quickfinder width=39 height=21></td></tr><tr><td colspan=4><div id=menulinequick></div></td></tr>")
x_makecount=0

Do While (Not rsmakecount.Eof) 
x_makeid = rsmakecount("makeid")
x_makequick = rsmakecount("makequick")
x_makecount = rsmakecount("makecount")

response.Write "<tr><td colspan=2><a href=3coltemp.asp?pagesetupid=2&x_Make=" & Server.URLEncode(x_makeid) & "&z_Make==,','><span class=quickfindlge>" & (x_makequick) & "</span></a></td><td><input name=showhide type=image onClick=showHide();chgimg(this);return false; src=images/showbut2.gif width=13 height=9></td><td><span class=quickfindlge>("& (x_makecount) & ")</span></td></tr>"

reccount=0
Set rsmod = Server.CreateObject("ADODB.Recordset")
rsmod.CursorLocation = 3
rsmod.Open modsql, conn
totrecs = rsmod.RecordCount
startrec = 1
lastrec = totrecs

Do While (Not rsmod.Eof)
reccount=reccount+1
if rsmod("make") = x_makeid then
x_modcount = rsmod("modcount")
x_mod = rsmod("model")

response.Write "<tr id=""theTable"" style=""display: none;""><td><img src=images/spacer.gif width=5></td><td><a href=3coltemp.asp?pagesetupid=2&x_Model=" & Server.URLEncode(x_mod) & "&z_Model==,','&x_Make=" & Server.URLEncode(x_makeid) & "&z_Make==,','><span class=quickfind>" & (x_mod) & "</span></a></td><td></td><td><span class=quickfind>("& (x_modcount) & ")</span></td></tr>"
end if
rsmod.MoveNext
Loop

if reccount = lastrec then
rsmod.movefirst
end if

rsmakecount.MoveNext
Loop

response.Write("</table>")
 
Sorry man... I don't speak VBScript [sad]

If you post a link to your site, or the generated "view-source" HTML then I'll take a look.

-kaht

[small](All puppies have now found loving homes, thanks for all who showed interest)[/small]
 
One thing I did notice in the HTML lying "between the lines above" is this:

Code:
response.Write("<table border=0 cellspacing=0 cellpadding=2>........

[gray][i]No id put on the table above[/i][/gray]

response.Write "<tr id=""theTable"" style=""display: none;"">........

[gray][i]id of "theTable" applied to a table row[/i][/gray]

Using this code:
Code:
rowArr = document.getElementById("theTable").rows;
Will return an array of row references of a table. Since you have assigned the id to a table row, the javascript above is attempting to pull all rows from a <tr>, and of course a <tr> does not contain a collection of rows, a <table> contains a collection of rows. Hence, the .rows collection will only return results when called from a table object reference - which was what my first example above showed.

-kaht

[small](All puppies have now found loving homes, thanks for all who showed interest)[/small]
 
hi kaht- have included some source from the table in question
the makes are the rows with id "trx" and the models are the rows underneath
have started using this function

Code:
<script language="javascript" type="text/javascript">
   function FuncShowHide(){
      
      if (document.getElementById('hideShow').style.display == document.getElementById('trX').style.display){
         document.getElementById('hideShow').style.display = "none";
      } else {
         document.getElementById('hideShow').style.display = document.getElementById('trX').style.display
      }
   }
</script>

at the moment this only show/hides the models for the first make in the list - Citroen C3
but does not affect the models for any other makes.


Code:
<tr id=trX>
<td colspan=2>Citroen</td>
<td><input name=showhide type=image onClick=FuncShowHide();chgimg(this);return false; src=images/showbut2.gif width=13 height=9></td><td><span class=quickfindlge>(1)</td>
</tr>

<tr id="hideshow" style="display: none;">
<td><img src=images/spacer.gif width=5></td>
<td><span class=quickfind>C3</span>
</td>
<td></td>
<td><span class=quickfind>(5)</span></td>
</tr>
<tr id=trX>
<td colspan=2>Chevrolet</span></td>
<td><input name=showhide type=image onClick=FuncShowHide();chgimg(this);return false; src=images/showbut2.gif width=13 height=9></td>
<td></td>
</tr>
<tr id="hideshow" style="display: none;">
<td></td>
<td>KALOS</td>
<td></td>
<td><span class=quickfind>(5)</span></td>
</tr>
<tr id="hideshow" style="display: none;">
<td><img src=images/spacer.gif width=5></td>
<td>LACETTI</td>
<td></td>
<td><span class=quickfind>(5)</span></td>
</tr>
<tr id="hideshow" style="display: none;">
<td></td>
<td>LANOS</td>
<td></td>
<td><span class=quickfind>(5)</span></td>
</tr>
<tr id="hideshow" style="display: none;">
<td></td>
<td>MATIZ</td>
<td></td>
<td><span class=quickfind>(5)</span></td>
</tr>
<tr id="hideshow" style="display: none;">
<td></td>
<td>NUBIRA</td>
<td></td>
<td><span class=quickfind>(1)</span></td>
</tr>
 
There's a few fundamental things wrong with your code.

Mainly, when assigning an id to an element, it must be unique. This means that you cannot reuse the same id for multiple elements. You have assigned an id of hideshow to multiple rows in the table, and this is invalid html syntax.

Second, when calling the getElementById function, it returns a reference to only one HTML element. The reason for this is because of what I described above. Since ids must be unique, the function assumes that it will return only one element. After all, the function is getElementById, not getElement[!]s[/!]ById. This is why you're seeing the behavior that only the first row is hidden - because getElementById is only returning the first row.

To remedy your situation you could change all the ids to names, multiple HTML elements are allowed to have the same name. Once making that change you can use the getElementsByName (notice the plural Element[!]s[/!]) to return an array reference to all the rows with the name you supply. That should fix your problem.

Now.... I'm not sure what doctype you are using for your page, or if you're even concerned about keeping a standards compliant page - but I'm not sure if name is a valid attribute for a <tr> tag. That said, the page will still function with the above changes I mentioned, and 99.9% of your users will be none the wiser because it won't change any functionality. But don't be surprised if you run it thru the validator at w3c and a few errors pop up.

-kaht

[small](All puppies have now found loving homes, thanks for all who showed interest)[/small]
 
ok changed my func to use names - but doesnt work
ne other thing if i get this going surely it will affect all rows in the table with the name showhide, not just the rows underneath each make?

Code:
 <script language="javascript" type="text/javascript">
   function FuncShowHide(){
      if (document.getElementsByName("hideShow").style.display == document.getElementsName("trX").style.display){
         document.getElementsByName("hideShow").style.display = "none";
      } else {
         document.getElementsByName("hideShow").style.display = document.getElementsName("trX").style.display
      }
   }
</script>

<tr name=hideshow style=""display: none;""></tr>

[/code]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top