Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New to the CF scene
    Join Date
    Jun 2009
    Posts
    5
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Post Another Show/Hide Problem

    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:

    Code:
    <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:

    Code:
    <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.

  • #2
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,536
    Thanks
    80
    Thanked 4,490 Times in 4,454 Posts
    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:
    Code:
        <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:
    Code:
    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.

  • Users who have thanked Old Pedant for this post:

    owdy-88 (06-04-2009)

  • #3
    New to the CF scene
    Join Date
    Jun 2009
    Posts
    5
    Thanks
    1
    Thanked 0 Times in 0 Posts
    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?...

  • #4
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,536
    Thanks
    80
    Thanked 4,490 Times in 4,454 Posts
    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:
    Code:
    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
    Code:
        if ( ul.style.diplay == "none" )
    Obviously that should have been display

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

  • #5
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,536
    Thanks
    80
    Thanked 4,490 Times in 4,454 Posts
    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:
    Code:
    while ( node.tagName != "TD" ) node = node.parentNode;
    To play it safe, we could do this:
    Code:
    while ( node.tagName.toUpperCase() != "TD" ) node = node.parentNode;
    Or we could be even safer and do this:
    Code:
        while ( node.tagName.toUpperCase() != "TD" ) 
        {
            node = node.parentNode;
            if ( node == null ) { alert("No TD found"; return; }
        }

  • #6
    New to the CF scene
    Join Date
    Jun 2009
    Posts
    5
    Thanks
    1
    Thanked 0 Times in 0 Posts
    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!


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •