...

View Full Version : Another Show/Hide Problem



owdy-88
06-03-2009, 12:06 PM
Hi Guys,

I had a problem I posted here last night. I was able to get a solution right away, which was great. I've just realized that a section of my assignment requires some form of DOM, as well as JaveScript. I've implemented some DOM into my script but I seem to be having the same problems I was having last night:

The third column shows the information by default. I want to change my script so that it's initially HIDDEN
The 'show/hide' function only functions for the top row. If I press the show/hide button on any other row it only applies to the top code

Here's my script:



<script language="javascript" type="text/javascript">

function showHideDiv()
{
var divstyle = new String();
divstyle = document.getElementById("div1").style.visibility;

if(divstyle.toLowerCase()=="hidden" || divstyle == "")
{
document.getElementById("div1").style.visibility = "visible";
document.getElementById('btn1').value='Hide';
}
else
{
document.getElementById("div1").style.visibility = "hidden";
document.getElementById('btn1').value='Show';
}
}

</script>


and here's my XSL:



<body>
<h2>BUSS315 DHTML Assignment - Beaus CD Collection</h2>
<table border="1">
<tr bgcolor="#99CCCC">
<th>Artist:</th>
<th>Album Title:</th>
<th>More Information:</th>
</tr>
<xsl:for-each select="CATALOG/CD">
<tr>
<td><xsl:value-of select="ARTIST"/></td>
<td><xsl:value-of select="TITLE"/></td>
<div id="div1">
<td>
<ul>
<li>Country: <xsl:value-of select="COUNTRY"/></li>
<li>Record Company: <xsl:value-of select="COMPANY"/></li>
<li>Price: <xsl:value-of select="PRICE"/></li>
<li>Year of Release: <xsl:value-of select="YEAR"/></li>
</ul>
<input type="button" value="show hide div" onclick="showHideDiv()" id='btn1' />
</td>
</div>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>


Any help would, once again, be appreciated greatly. What I want is pretty simple: the 'show/hide' button in that third column, and for the information to appear and disappear accordingly when the button is clicked. Also, as previously stated, I want the information in the third column initially hidden, so all that appears when the page is loaded is the show/hide button.

Cheers.

Old Pedant
06-04-2009, 12:45 AM
Your basic problem is that all your div's have the same ID. That's a no-no.

ID's should be unique (a few exceptions, but unimportant).

On top of that, you have invalid HTML. You can't have a <div> that surrounds a <td>. Bad nesting.

The <div> would need to be inside the <td>.

But, really, you have no need of any <div> at all.

So...and this is off the top of my head:


<xsl:for-each select="CATALOG/CD">
<tr>
<td><xsl:value-of select="ARTIST"/></td>
<td><xsl:value-of select="TITLE"/></td>
<td>
<ul style="display: none;">
<li>Country: <xsl:value-of select="COUNTRY"/></li>
<li>Record Company: <xsl:value-of select="COMPANY"/></li>
<li>Price: <xsl:value-of select="PRICE"/></li>
<li>Year of Release: <xsl:value-of select="YEAR"/></li>
</ul>
<input type="button" value="show" onclick="showHide(this);" />
</td>
</tr>
</xsl:for-each>


and then:


function showHide(where)
{
var node = where;
// look "up" the tree for the surrounding td:
while ( node.tagName != "td" ) node = node.parentNode;
// then find the ul in that td:
var ul = node.getElementsByTagName("ul")[0]; // better be one and just one!
if ( ul.style.diplay == "none" )
{
ul.style.display = "inline"; // ??? maybe should be "block"??
where.value = "hide";
} else {
ul.style.display = "none";
where.value = "show";
}
}


See? No need for id's, because we do it all by relative positioning starting from the button.

You *really* do NOT want to use the ".visibility" property. When you do so, the stuff that is hidden still eats up the same real estate on the screen. Setting display to none collapse the stuff entirely.

100% UNTESTED!!! Only warranted against bugs with 6 legs for the next 30 nanoseconds.

owdy-88
06-04-2009, 01:30 AM
Hi!

Wow thanks heaps for your help and hints. As I said, my knowledge base is very small so I like replies like that where I'm learning something.

I've embedded the code and XSL. We're half-way there. The information is hidden and the 'show' button appears. But when I press it, nothing happens - to any of them.

Ideas?...

Old Pedant
06-04-2009, 01:43 AM
Do you have JavaScript debugging turned on??

You are probably getting a JS error and, if you are a typical user, you have your browser set to just ignore all JS errors.

We can put some debugging code into my JS, but if the fault is a syntax error or lies someplace else, it won't help.

But just in case:


function showHide(where)
{
alert("DEBUG: value of clicked button is " + where.value);
var node = where;
// look "up" the tree for the surrounding td:
while ( node.tagName != "td" ) node = node.parentNode;
alert("DEBUG: contents of td are:\n" + node.innerHTML);
// then find the ul in that td:
var ul = node.getElementsByTagName("ul")[0]; // better be one and just one!
alert("DEBUG: contents of the ul are:\n" + ul.innerHTML);
if ( ul.style.display == "none" )
{
alert("DEBUG: changing ul to visible");
ul.style.display = "inline"; // ??? maybe should be "block"??
where.value = "hide";
} else {
alert("DEBUG: changing ul to hidden");
ul.style.display = "none";
where.value = "show";
}
}

You can remove any/all of those DEBUG alerts as things start to work.

Did you notice I had a typo on my original code??

I had


if ( ul.style.diplay == "none" )

Obviously that should have been display

If you didn't fix that, that could well be the culprit.

Old Pedant
06-04-2009, 01:52 AM
GOT IT!

In addition to my goof on "diplay", I forgot that tagName normally returns an all-upper-case value.

So I should have used:


while ( node.tagName != "TD" ) node = node.parentNode;

To play it safe, we could do this:


while ( node.tagName.toUpperCase() != "TD" ) node = node.parentNode;

Or we could be even safer and do this:

while ( node.tagName.toUpperCase() != "TD" )
{
node = node.parentNode;
if ( node == null ) { alert("No TD found"; return; }
}

owdy-88
06-04-2009, 02:15 AM
BULLS-EYE!

Great work OP, really appreciative for your help. This is why I'd never be a good programmer - one little mistake and if ruins your whole code grr. But thanks again. It's all working swimmingly. You rock!



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum