reptile7's JavaScript blog
Tuesday, April 08, 2008
The Script Tips #92-93 Script: Intro
Blog Entry #109

Today we begin work on the final script presented by the HTML Goodies JavaScript Script Tips series: the "Pop-Up Tables" script of Script Tips #92 and #93.

The Script Tips #92-93 Script codes a 'mini-résumé'. The script initially displays a table whose rows contain lists of the programming languages that the script's author, Peter Trenholme, has under his belt, e.g.:

Windows: C++, C++ Builder, Java, JavaScript, Delphi, Visual Basic, SAS/AF

When the user mouseovers the blue text, a table providing relevant details pops up:

Pop-up table for the 'Windows' row

When the user mouseouts from the blue text, the table disappears. If this seems familiar, it should: the Script Tips #92-93 Script's effect is similar to that of the "Drop-Down Menu" tutorial script that we analyzed in Blog Entry #96. Nonetheless, the Script Tips #92-93 Script will break some new ground for us in that its tables - both the initial table and the pop-up tables - are assembled via a 'two-dimensional' array, an array type we heretofore have not encountered.

A two-dimensional array is simply an array whose elements are themselves arrays. The child arrays of an arrayName 2-D array are referenced in the usual manner: arrayName[0], arrayName[1], etc. The individual elements of the child arrays are accessed via an arrayName[i][j] syntax; for example, arrayName[5][2] would refer to the third-in-source-order element of arrayName's sixth-in-source-order child array.

The Script Tips #92-93 Script and the xmp element

Mr. Trenholme has formatted his script with whitespace in order to make it easier to read in various ways - for example, the script's Text 2-D array is formatted so that the Text child arrays resemble the pop-up tables that are coded from them - so to preserve this formatting, Joe has wrapped the script in an xmp element on the "Here's the Code" page of Script Tips #92-93. As you may know, the xmp element* is a not-just-deprecated-but-now-obsolete precursor** to the pre element.
*Note from this link that the W3C was warning authors away from the xmp element as far back as HTML 2.0.
**The xmp element appears in the element set of the first version of HTML whereas the pre element doesn't.

Like, say, the title element, the xmp element has (or 'had' - perhaps I should use the past tense here) a #PCDATA(-type) content model, meaning that it could validly contain text and also character references (e.g., é for é) but no markup, and therefore any markup in an xmp element should be treated by the browser as normal text and not rendered, in the same way that the markup in a

<title>My not-so-<b>bolded</b>-and-<i>italicized</i> title</title>

title is not rendered but printed in the browser window's title bar. So regarding the Script Tips #92-93 Script's display, I suspect that Joe put the script in an xmp element and not a pre element because a pre element, which can legitimately contain most text-level elements including the script element, would have required him to respectively escape the script's < and > characters to &lt; and &gt; (at the least, the < characters would have to be escaped), whereas he could let the < and > characters be with an xmp element.

Of course, all bets are off as to how a modern browser will render an obsolete element. In practice on my computer:
• MSIE 5.1.6 renders the entire Script Tips #92-93 Script, as the content of its xmp element container, without incident.
• Netscape 7.02 only renders the xmp element content that follows the <body bgcolor="#ffffff"> tag.
But as Joe notes, regardless of what your browser does with the xmp element, you can grab the full script from the source of the "Here's the Code" page; alternatively, you can take it from the div below:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<script language="javascript">
    Titles = ["General Programming",
             "Data Base",
    var nCols = 4;              // Number of columns in the tables
    var bgColor = "Yellow";     // Pop-up table background color
    var fgColor = "Black";      // Pop-up table text color
    Text = new Array(10);       // Array of arrays of pop-up table data
//       Language     Years Last Used   Bold
//       -----------  ----- ---------   ----
    Text[0] = new Array(
         "C",         13, "Current", 1,
         "C++",        5, "Current", 1,
         "FORTRAN",   30, 1986,      1,
         "BASIC",     20, 1987,      1,
         "PROLOG",     1, 1990,      1,
         "ADA",      1/2, 1985,      0,
         "LISP",       2, 1975,      0,
         "PL/1",       1, 1978,      0,
         "APL",        2, 1971,      0,
         "COBOL",    1/4, 1967,      0);
    Text[1] = new Array(
         "QA Partner (4Test)", 6, "Current", 1,
         "DTM",                3, 1986,      0,
         "WinRunner",        1/4, 1997,      0);
    Text[2] = new Array(
         "C++",          5, "Current", 1,
         "C++ Builder",  2, "Current", 1,
         "Java",       1/2, "Current", 0,
         "JavaScript",0.08,"Current",  0,
         "Delphi",     1/4, 1997,      0,
         "Visual Basic", 1, "Current", 0,
         "SAS/AF",       2, 1991,      0);
    Text[3] = new Array(
         "MASM",      1, 1985,    0,
         "GMAP",      1, 1986,    0,
         "BAL",       1, 1971,    0);
    Text[4] = new Array(
         "SQL*Plus", 12, "Current", 1,
         "SAS/SQL",   1, 1991,      0,
         "Access",    1, "Current", 1,
         "SIR",       3, 1979,      0,
         "dBase",     3, 1985,      0,
         "Rbase",     4, 1987,      0);
    Text[5] = new Array(
         "SAS",      8, 1990,    1,
         "SPSS",     2, 1971,    0,
         "Minitab",  3, 1980,    0,
         "SIR",      1, 1979,    0,
         "P-STAT",   2, 1985,    0,
         "GLIM",     1, 1985,    0);
    Text[6] = new Array(
         "Corel",     1/2, 1997,     0,
         "Tel-A-Graph", 1, 1986,     0,
         "SAS/GRAPH",   8, 1990,     0);
    Text[7] = new Array(
         "Word",        10, "Current", 1,
         "WordPerfect", 15, 1988,      1,
         "TPU",          8, 1987,      0,
         "EEL",          5, 1971,      0,
         "SNOBOL",       5, 1971,      1,
         "Postscript",   1, 1995,      0);
    Text[8] = new Array(
         "Excel",       2, "Current", 1,
         "Lotus 1-2-3", 5, 1986,      0);
    Text[9] =  new Array(
         "MS-DOS",   18, "Current", 1,
         "NDOS",     15, "Current", 1,
         "DCL",      10, 1992,      1,
         "JCL",      10, 1971,      0,
         "UNIX",      5, 1980,      0);
function eShow(name)
    document.all(name).style.display = "inline";
function eHide(name)
    document.all(name).style.display = "none";

<body bgcolor="white">
<p><b>Pop-up table sample</b></p>

<div style="position:relative">
<script language="javascript">
    for (var j = 0; j < Titles.length; ++j)
        name = Titles[j];
        "<div style=\"position:absolute;top:5px;width:350px\">\n" +
        "    <table id=\"" + name + "\"" +
        " cellpadding=1 cellspacing=4 border=2" +
        " bgColor=" + bgColor + "\n style=" +
        "\"display:none; position:absolute; left:200px\">");
            "<tr bgColor=" + bgColor + ">");
            "  <th bgColor=" + fgColor + " align=center>" +
            " <font color=" + bgColor + ">Language</font>");
            "  <th bgColor=" + fgColor + " align=center>" +
            " <font color=" + bgColor + ">Years Used</font>");
            ("  <th bgColor=" + fgColor + " align=center>" +
             " <font color=" + bgColor + ">Last Used</font>");
        for (var i = 0; i < Text[j].length; i = i + nCols)
            if (Text[j][i + 3] == 0)
                "  <tr><td>" + Text[j][i] + 
                "\n    <td align=\"center\">" + Text[j][i+1] + 
                "\n    <td>" + Text[j][i+2] + "\n  </tr>");
                "  <tr><td><b>" + Text[j][i] + 
                "</b>\n    <td align=\"center\"><b>" + Text[j][i+1] + 
                "</b>\n    <td><b>" + Text[j][i+2] + "</b>\n  </tr>");
<table border="0" cellspacing="4">
<script language="javascript">
  for (var i = 0; i < Titles.length; ++i)
    document.write("<tr>\n<td><p align=\"right\">");
    document.write(Titles[i] + ":</p>");

    document.write("</td>\n<td><a onmouseover=\"eShow(&quot;" + Titles[i] + "&quot;)\"");
    document.write("onmouseout=\"eHide(&quot;" + Titles[i] + "&quot;)\"</a>");
    document.write("<font color=\"#0000FF\" size=\"3\" face=\"Arial\">");
    for (var j = 0; j < Text[i].length; j = j + nCols)
      if (j > 0)
        document.write(", ");
      if (Text[i][j + 3] == 1)
        document.write("<b>" + Text[i][j] + "</b>");

Per my standard practice, the above div script has been placed in a pre element, for which the script's < and > characters have been duly escaped, as you can verify from the source of this page. To preserve the script's formatting, I find that the script must be rendered in a monospace font and not in a sans-serif font (my usual choice) nor even a serif font. The W3C suggests, When handling preformatted text, visual user agents...[m]ay render text with a fixed-pitch font, but I've given my pre element a font-family: monospace; style just to be on the safe side.

In the name of completeness, I should mention, before moving on, that:

(1) The browsers on my computer do not convert character references in an xmp element to their respective characters, e.g.,

<xmp>7 &times; 7 = 49</xmp>

outputs 7 &times; 7 = 49 and not 7 × 7 = 49.

(2) Joe places his xmp element in a line break-preventing nobr element, unnecessarily so IMO - none of the script's lines/strings is long enough to warrant the nobr container.

Getting the script to work with MSIE

As you would expect, the script uses commands to display and vanish its pop-up tables:

function eShow(name) { document.all(name).style.display = "inline"; }
function eHide(name) { document.all(name).style.display = "none"; }
// name is the id value for the pop-up tables.

In its original form, the script is 'MSIE-only': at the time the script was written, the JavaScript/Netscape 'object model' was not able to access table elements, but MSIE could do so via the all collection. However, at the script's demo page, the script does not work even with MSIE - you'll see the initial display table but the pop-up tables don't pop up. The problem lies with the following line:

document.write("onmouseout=\"eHide(&quot;" + Titles[i] + "&quot;)\"</a>");

The yellow-highlighted anchor element end-tag is 'extra' and shouldn't be there - take it out and the script works fine with MSIE.

Then, to get the script to work with current non-MSIE and MSIE browsers, you'd think that we could merely replace the document.all(name) references in the eShow( )/eHide( ) functions with document.getElementById(name) references. But at least for Netscape 7.02, I find that additional changes are necessary to reproduce the script's effect with MSIE; we'll get to these changes, and a cross-browser demo, in due course.

The lost 'Script Tip #94'

Joe does not finish his deconstruction of the "Pop-Up Tables" script at the HTML Goodies site. In Script Tip #92, he discusses the script element in the document head, and in Script Tip #93, he addresses the document body's code for the initial display table. At the end of Script Tip #93, Joe promises, "Next Week: Those Pop-Up Tables." However, the 'current' Script Tip index and the 'legacy' Script Tip index both end with Script Tip #93. Knowing that some of HTML Goodies' materials appear elsewhere on the Web, I decided to see if a Google search would turn up a lost 'Script Tip #94' or its equivalent.

I am gratified to report that my search bore fruit: here at and here at is a "Post the Tables" article in which Joe concludes his discussion of the "Pop-Up Tables" script. (HTML Goodies,, and are all part of the Jupitermedia 'empire', and the 'family ties' that bind these sites are outlined in HTML Goodies' "The Family of HTML Goodies" article.) The "Post the Tables" article is somewhat marred - specifically, it features a pre element-contained block of code that does not display correctly because the < characters thereof are not escaped (it's clear from the source that this is the problem, as there are three other pre-wrapped code blocks on the page that are OK) - so maybe that's why it's not posted at HTML Goodies as a 94th Script Tip.

(July 2016 Update: The aforecited "Post the Tables" pages are no longer live but you can still get the article at the Internet Archive.)

We'll go over the script's initial display table in detail in the next post.


Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)