views:

762

answers:

1

Good morning. I have an XML file which contains lists of warning and errors from a build output. I have successfully been able to write XSL to iterate over the separate lists of warnings and errors to have them display in my browser. What I'd like to do next would be to add a bit of javascript in order to add a link/button to be able to toggle the display of the warnings. I can't get it to work properly.

here is the relvant code (trimmed down to what I hope are the essentials)

<xsl:template match="/">
    <xsl:variable name="messages" select="/cruisecontrol//buildresults//message" />
    <xsl:variable name="warning.messages" select="$messages[(contains(text), 'warning ')) or @level='Warning']" />
    <xsl:variable name="warning.messages.count" select="count($warning.messages)" />
    <xsl:if test="$warning.messages.count > 0">
        <script type="text/javascript">
            function toggleWarnings() {
                eDiv = document.getElementById("warnings");
                tDiv = document.getElementById("warningsTitle");
                if ( eDiv.style.display == "none" ) {
                    eDiv.style.display = "inline";
                    tDiv.innerText = "Hide Warnings";
                } else {
                    tDiv.innerText = "View Warnings";
                    eDiv.style.display = "none";
                }
            }
        </script>
        <table>
            <tr> <td>
                <a href="javascript:void()" onclick="javascript:toggleWarnings(); return false;">
                   <span id="warningsTitle">View Warnings</span>
                </a>
            </td> </tr>
            <xsl:for-each select="$warning.messages">
                <tr> <td class="warning" id="warnings" style="display: none;">
                    <xsl:value-of select="."/>
                </td> </tr>
            </xsl:for-each>
        </table>

The problemt that I have is that only one warning is ever displayed after hitting the "view warnings" link. My problem is that I know enough HTML, XSL, and javascript to be slightly dangerous and the combination is proving that I don't know enough :-)

Is there an easy way for me to iterate over XSL elements, display then in a table and also be able to hide all of those elements under a link toggle?

Thanks.

+1  A: 

Give this a go - comments are in the code.

<xsl:template match="/">
<xsl:variable name="messages" select="/cruisecontrol//buildresults//message" />
<xsl:variable name="warning.messages" select="$messages[(contains(text), 'warning ')) or @level='Warning']" />
<xsl:variable name="warning.messages.count" select="count($warning.messages)" />
<xsl:if test="$warning.messages.count > 0">
    <script type="text/javascript">
     function toggleWarnings()
     {
      // Get the table
      var table = document.getElementById("warnings");

      // Get all the rows in the table
      var rows = table.getElementsByTagName('tr');

      tDiv = document.getElementById("warningsTitle");

      if (tDiv.innerHTML == 'View Warnings')
      {
       for (var i = rows.length - 1; i >= 0; i--)
       {
        // Skip any rows that aren't warnings
        if (rows[i].className != 'warning')
         continue;

        try
        {
         // Try it the right way
         rows[i].style.display = 'table-row';
        }
        catch (e)
        {
         // Try it the IE way
         rows[i].style.display = 'block';
        }

       tDiv.innerHTML = "Hide Warnings";
      }
      else
      {
       for (var i = rows.length - 1; i >= 0; i--)
       {
        // Skip any rows that aren't warnings
        if (rows[i].className != 'warning')
         continue;

        rows[i].style.display = 'none';
       }

       tDiv.innerHTML = "View Warnings";
      }

      return false;
     }
    </script>
    <!-- Moved the ID to the table - IDs must be unique! -->
    <table id="warnings">
     <tr>
      <td>
       <!-- This is must shorter, and "javascript:" inside onclick is plain wrong -->
       <a href="#" onclick="return toggleWarnings();">
        <span id="warningsTitle">View Warnings</span>
       </a>
      </td>
     </tr>
     <xsl:for-each select="$warning.messages">
      <!-- Moved the class to the tr -->
      <tr class="warning" style="display: none;">
       <td>
        <xsl:value-of select="."/>
       </td>
      </tr>
     </xsl:for-each>
    </table>
Greg
Woot! Thanks. I missed fact that id's need to be unique.
Mark