WebVoyage 7 (Tomcat) Toggle Display Fields

Revised July 22, 2009

I had a librarian tell me that while giving a presentation on Tomcat WebVoyage to students, one of the record displays had an extremely long Contents field through which she had to scroll, all the while embarrassed by students' laughter. I know, I know, I didn't quite get the joke either.

Anyway, to combat the fear and shame felt by our librarians, I wrote a bit of code that will toggle the contents of a field in a record display. If you'd like to see this amazing technology in action, try clicking the word Contents: at this record on TCC's site.

Step 1
Add the following to a cascading stylesheet sheet that is loaded with holdingsInfo. (ui/{skin}/css/displayCommon.css, for example)

.fieldLabelSpan {
   cursor:pointer;
}

Step 2
Add the following to a JavaScript file that is loaded with holdingsInfo, like ui/{skin}/jscripts/highLight.js. Again, I have a separate JavaScript file for all the scripts I write (spellchecker, timeout warning, etc.) that is loaded with each page:

function tcc_toggle(elementName) {
   if(document.getElementById && document.getElementById(elementName)) {
      if(document.getElementById(elementName).style.display == 'none') {
         document.getElementById(elementName).style.display = 'block';
      } else {
         document.getElementById(elementName).style.display = 'none';
      }
   }
}
var savedText = [];
function tcc_toggle(elementName) {
   if(document.getElementById && document.getElementById(elementName)) {
      if(savedText[elementName] == undefined || savedText[elementName] == null || savedText[elementName] == '') {
         savedText[elementName] = document.getElementById(elementName).innerHTML;
         
         var firstLine = savedText[elementName].indexOf('<BR>') ? savedText[elementName].substring(0,savedText[elementName].indexOf('<BR>')) : '';
         firstLine = (firstLine=='' && savedText[elementName].indexOf('<br>')) ? savedText[elementName].substring(0,savedText[elementName].indexOf('<br>')) : firstLine;
         
         var toggleURL = "<br/>(more...)";
         firstLine += toggleURL;
         
         document.getElementById(elementName).innerHTML = firstLine;
      } else {
         document.getElementById(elementName).innerHTML = savedText[elementName];
         savedText[elementName]=null;
      }
   }
}

Step 3
The last, crucial step is to call this script somehow.

  1. Backup /m1/voyager/{xxxdb}/tomcat/vwebv/context/vwebv/ui/{skin}/xsl/contentLayout/display/display.xsl in case something goes horribly wrong.
  2. Open /m1/voyager/{xxxdb}/tomcat/vwebv/context/vwebv/ui/{skin}/xsl/contentLayout/display/display.xsl and find
    <xsl:when test="string-length($displayData)"> (There should only be one)
  3. Add the following (additions are boldface)

    <xsl:when test="string-length($displayData)">
      <div class="fieldLabel">
       <span class="fieldLabelSpan">
         <xsl:choose>
          <xsl:when test="string-length(@label)">
            <a>
             <xsl:attribute name="onclick">tcc_toggle('<xsl:value-of select="@label"/>');</xsl:attribute>
             <xsl:attribute name='title'>Hide or Show <xsl:value-of select="@label"/></xsl:attribute>
             <xsl:value-of select="@label"/>
            </a>
          </xsl:when>
          <xsl:otherwise>
            &#160;
          </xsl:otherwise>
         </xsl:choose>
       </span>
      </div>
      <div class="fieldData" >
       <xsl:attribute name="id">
         <xsl:value-of select="@label"/>
       </xsl:attribute>
       <xsl:copy-of select="$displayData"/>
      </div>
    </xsl:when>

  4. If you'd like to make Contents hidden by default, add the following code to one of your stylesheets. Adding this may confuse your users because the Contents: label must be clicked twice to get the field data to initially display. After that, it toggles correctly.

      div#Contents\: {
        display:none;
      }
    /* (No, that's not a typo... it's div-hash-Contents-backslash-colon) */