From the July 2002 issue of MSDN Magazine

MSDN Magazine
HTML Table Control, WindowClosing Event, Numerous ActiveX Controls, and More
Download the code for this article: WebQA0207.exe (36KB)
Q I use the following code to reference an HTML table control. When I call Alert, document.all.tblProg works fine in Microsoft® Internet Explorer, but not in Netscape 4.0. Why not?
<SCRIPT><!-- //Alert(document.all.tblProg)//--></SCRIPT>
                                ••• <table id="tblProg" name="tblProg">
                                <tr> <td></td> </tr></table> 
A This operation can't be performed in Netscape 4.0 because the browser does not have the same level of DHTML support provided by Internet Explorer 4.0 and higher. Access to elements within a document is limited in Netscape and does not cover tables. Netscape 6.0 allows this level of access to the document contents, but it doesn't include support for the document.all collection as it's not part of the final DOM standard (

Q When a user attempts to close a browser window by clicking the X icon on the title bar, I would like to be able to capture the event. In the past, the "return false" and "event.returnValue = false" statements could not be used to cancel an onbeforeunload so a malicious site could not prevent you from navigating away. Has this changed with the latest versions of JScript®?
event::closeBrowser () { if(!confirm("are you sure you want to close
                                this window?")) { //do not close window return false; } } 
A The MSDN® Library includes a page that explains the use of the onbeforeunload event and does exactly what you want (onbeforeunload Event). If you want to distinguish between browsing to a new page and closing the browser, Internet Explorer 5.5 and higher offer the WindowClosing event, defined on the DWebBrowserEvents2 interface. The bad news is that you can't capture this event with JScript; the only way is with a language like C++ or Visual Basic®.
      You could also set a flag in the onclick event of any anchor and check it in the onbeforeunload handler:
<SCRIPT> var nav=false; function closeIt() { if (nav==false) event.returnValue
                                = "Any string value here will force a dialog box to appear before closing the
                                window."; } </SCRIPT> ••• <a href=""
                                onclick="nav=true;"> Click here to navigate to</a>
This isn't foolproof. For example, if the user right-clicks on the anchor tag and selects Open, this won't work. This method also doesn't handle the case where the user types a URL into the Address bar, selects a link from Favorites or the Links bar with Reuse Browser Window selected in Advanced Options, loads a URL from a Microsoft Outlook® message or Word doc, and so forth.
      Remember that invoking onbeforeunload prevents you from leaving the page without getting a prompt, owing to the security reasons you mentioned.

Q Is there a way to dynamically create an arbitrary number of instances of a particular ActiveX® control and display them on an HTML form? I know how to display a fixed number of visible controls with the HTML OBJECT tag, and I can dynamically create an arbitrary number of ActiveX objects in JScript (with "new ActiveXObject"), but I don't know how to display the latter.

A You can use the createElement method on the document to create an element, and then use insertAdjacentElement to insert it into the page (see Figure 1). This can be done as often as needed.

Q I'm trying to create an HTML table that has four columns in which each row can have subrows. The text in the first column is indented based on its level in the hierarchy, while the text in the remaining three columns should all have the same position regardless of the indent level. The trick is that when a row is clicked, all of its subrows are shown or hidden like a listview. The data in the table is dynamic, so the whole thing must be built in script. I've tried both nested <TABLES> and nested <TBODY> tags.

A You can do this with the code in Figure 2; it contains a JScript function which you call in the onClick event to toggle the table rows to hide or show another table. In onClick you call a table ID that has been given the name tlblib; the variable passed into the function and the last three chars of the table ID are the same:
onClick="javascript: ToggleScopeCat('lib" 
You can see the code in action in Figure 3. For the full code, download the archive at the link at the top of this article.

Figure 3 Nested Tables in Action
Figure 3 Nested Tables in Action

      Nested tables are one of the most time-consuming constructs for a browser. Since all columns except the first remain aligned vertically, you might opt to tag subordinate rows and then go through the list to turn them off. It will make your script logic more complex, but will save rendering time for the browser. With the nested tables option you need every sublevel enclosed in a new table and you have to provide unique IDs or identify children.

Q The new Euro laws state that financial calculations must be done to six-digit precision, but the VBScript® decimal data type doesn't support this level of precision. Legacy apps didn't use decimal calculations until the Euro was introduced. What can I do?

A Numbers lower than one billion can be represented to six or more digits of precision with an ordinary number (a double-precision floating point). The disadvantage of using doubles is that you can accumulate floating-point error, which you must then correct with the careful use of rounding algorithms. Of course, you might also have calculations involving sums over one billion, which would decrease precision.
      There's no getting around this second problem. There are some ways to avoid loss of precision due to floating-point error. For example, you could do all your calculations in integer units—microeuros, for example. One million microeuros make a euro. If you convert from euros to microeuros correctly (which might not be as easy as you think!) then you can do all your calculations in nonrounded integer microeuros and have no error. Then when you convert back to Euros (carefully!) you're all set.
      Well, guess what? That's what the decimal type does internally. The only difference is that the decimal type has a massive 96 bits to work with whereas the double only has 64. Or you can just be clever about the way you round and display to help avoid floating-point error. In any event, getting numeric precision correct is a difficult problem that can't be addressed here.

Q I need to know if there is any way to do an unconditional (or even conditional) jump in VBScript. It seems that the Goto Label syntax from Visual Basic is not allowed. I know that it is bad form to use a Goto, but I need it for debugging purposes on some large scripts.

A There are no labeled jumps of any kind in VBScript. Here is a workaround: use do...loop to create a scope:
Sub foo Do ••• if cond1 then exit loop •••
                                if cond2 then exit loop ••• exit loop loop ' cleanup code •••
                                end sub 
Q I'm migrating a Sybase application that includes a stored procedure that takes an XML structure and persists the data into approximately six different tables. The application gets this information (about 40KB of data) from the mainframe when a user logs into their Web site, so there will be quite a few transactions—up to 50 to 100 per second.
      I have rewritten the procedure to utilize OPENXML and have seen performance improvements. But what peformance problems or thresholds should I look for in OPENXML?

A OPENXML is designed for docs in the 50-100KB range. The following tips should be helpful.
  • Never run the same or similar XPath expression more than once; rather, run a more general XPath query to fill a temp table and use SQL.
  • Don't use flag 3 (attribute- and element-centric default) unless absolutely necessary. The XPath engine is not efficient with such "union" queries.
  • Use the sp_xml_removedocument stored procedure at the proper time. Using it too early causes reparsing and too late can create memory contention.
  • For loading large amounts of data, use the XML bulkload functionality of the SQLXML Web releases.

Got a question? Send questions and comments to
Thanks to the following Microsoft developers for their technical expertise: Jay Allen, Erez Amir, Earl Beaman, Zarko Berberski (Excell Data Corporation), Zack Birkenbuel, Lisa Cassley, Aaron Ching, Andrew Clinick, Ulric Dihle, Steve Dunker, Eric Lippert, Dave Massy, Tosh Meston, Michael Murgolo, Michael Rys, Luis Gómez Sánchez, John Sanford, Alex Stephens, John Thorson (SYSolutions), Vincent Yung.