The Whole Enchilada

The Whole Enchilada

As of December 2011, this topic has been archived. As a result, it is no longer actively maintained. For more information, see Archived Content. For information, recommendations, and guidance regarding the current version of Internet Explorer, see Internet Explorer Developer Center.

Heidi Housten, Tom Moran, and Kusuma Vellanki
Microsoft Corporation

October 2, 2000

It's filling. This month, the Web Team Talking bites off a mouth-watering menu of questions—everything from unwanted addresses and element access to SELECT and recordsets. They even include a short answer that could become much longer.


Pesky addresses—Removing address bar entries
Getting into your <HEAD>—Retrieving data from within a <HEAD> element
Extending SELECT behavior—Selecting smartly
Getting your orders mixed up?—Avoiding scrambled data

The Web Team in Short

Pesky addresses

Dear Web Team:

How do I delete addresses from my Web browser? I try to highlight and press the DEL key, but all this does is take it off the window; when I use the address scroll, it's still there.

Vaughan Whittaker

The Web Team replies:

We hear you, Vaughan! That would be a really useful feature, especially for URLs that you mistyped but keep accidentally selecting by using the address bar's auto complete feature. There is currently no documented way to delete a single address from the address-bar drop-down list.

For now, let's be brave and resolve this issue by using the registry. First, we have to warn you: Using the registry incorrectly can cause serious problems, so proceed at your own risk. Click the Start button, select Run, and type regedit to start the Registry Editor. Internet Explorer saves these typed URLs in the registry under the following key, and you can delete either some or all of the entries under this key.

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TypedURLs

Getting into your <head>

Dear Web Team:

Hi there.

Is there a way to retrieve the head section of an HTML document, or whatever is between the tags <HEAD>and </HEAD>, by using JavaScript or JScript?

Ahmed Saif

The Web Team replies:

Just lie comfortably on that couch while we take a look at what's going on in your head. Actually, it is not as easy to get into your <HEAD> as some parts of your <BODY>.

From Internet Explorer 4.x and later, you can get individual parts of the <HEAD> element, but you can't get the whole enchilada. For example, take the large code sample below. From Internet Explorer 4.x, you can access the <META> tags, the script and style-sheet blocks, among others, individually.

For example, to access the content attribute of the description <META> tag, use document.all.description.content. The tags and attributes are completely based on the contents of the tag; they are not predefined. This means that you can roll your own attributes. In the <META> tag below, you can access the value of the abc attribute by using Be aware that if you are using JScript®, capitalization in your script must match that of the tag.

The syntax is slightly different for style and script blocks. To access the first rule in the style-sheet block in the code below, use:


To get the contents of the script block, use:


In Internet Explorer 5 and later, you can get the whole enchilada, or take bites of it. You need to use the document.all collection to access this information. We have put together a couple of examples to show how you can access different HTML code sections by using the document.all collection. (Keep in mind that document.all.tags returns a collection even if there is only one element. Use the item collection to iterate through all the elements of the collection, and remember that collections are zero based.)

The first function below will show the script block contents using the syntax available from Internet Explorer version 4.0.

The second function uses properties available from Internet Explorer 5, and shows an alert box that contains the value of the outerHTML property of the <HEAD> section.

The third function, showHeadKids(), illustrates the use of the children collection to access the subsections of the document's <HEAD> element. This function calls showCollection() to iterate through the collection passed in, and display the value of the innerHTML property. Notice that in showCollection(), the collection is addressed as an array, which means that an individual element is returned, not a collection. This means that the attributes can be accessed directly without needing to use the item() subcollection.

The showTree() function calls the showCollection() function, passing the entire document.all collection. We put this in just to show that every single element in the page is accessed through document.all, and that it is a sequential rather than a hierarchical tree.

<TITLE>Getting into your head</TITLE>
<META NAME="description" CONTENT="Heady topics" ABC="123">
body { font-family:verdana; }

<SCRIPT LANGUAGE="jscript" ID="headScript">
function showScript() {

function showHead() {

function showHeadKids() {
   alert("<head> contains " + kids.length + " children");

function showTree(){
   alert("document.all.length is: " + document.all.length);

function showCollection(coll){
   for (i=0; i < coll.length;i++)
      alert("innerHTML for " +
      coll[i].tagName + ":\n"  + coll[i].innerHTML);

View the sample to see the code in action.

For those of you more used to Visual Basic® Scripting Edition (VBScript) than to JScript, notice that collections are accessed using parentheses, while arrays are accessed using square brackets.

There are extensive references for the browser object model in the DHTML references section of the MSDN Library.

Extending SELECT behavior

Dear Web Team:

I have some drop-down list boxes on an ASP page. I have a bunch of items in them, and would like to go to an individual item by typing in the first few letters of that item. Currently, when I hit a letter, it goes to the first item with that letter. Then when I hit the next letter, it goes to the first item that starts with the second letter. HELP!

J. Nelson

The Web Team replies:

We have not one but two samples that fit your needs. We originally addressed this question in a previous posting. The previous sample used an attached behavior and performed an incremental search through an unsorted list. The search also wrapped around when it reached the end of the list.

Here is another sample, with a slightly different implementation, written by Microsoft JScript Program Manager Peter Torr. When you look at the sample, you can see what the user has typed so far and the corresponding match. The options need to be sorted in order to use this implementation, which employs binary search to search through the sorted input. This option is usually best for large lists, and may be slower for small lists (if you were really counting your nano-seconds). If your list has more than, say, 100 items, it will be noticeably faster to use the binary search than the incremental search.

Getting your orders mixed up?

Dear Web Team:

Hi Guys.

I seem to be having an intermittent problem when using SQL Server 7.0 to process customer orders. Basically, on an infrequent basis, a customer's order will get appended to the last recorded order in the database. The main tables are: Products, Orders, Items in Order, Customer. In both the Orders and Items in Order tables, I am using a primary key with an auto increment of one. Could this be the problem? When I create a new customer and add it to the database, I then create another recordset, issue the movelast command, and recall the customer ID, which is then used as a foreign key in the orders table. The order is then created, and I recall the allocated orderid in the same manner before passing that to the 'items in order' table, where it resides as a foreign key. Am I doing anything wrong? I've heard that Select @@identity may be a possible solution, but I am wondering if this would cause more problems!

Any help or advice would be most appreciated.



The Web Team replies:

Not more identity problems!

Anyone asking for the last record of a recordset is looking for trouble. It is the cause of numerous common database errors. Let's examine the specific problem that you are having, Leo. The main difficulty is that the last record is not necessarily the most recent record. First, the data from recordset selections are not guaranteed to be sorted or ordered unless an ordering clause is used in the query. Without such a clause, the default ordering of records can be:

  • Ordered by the clustered index with respect to server character set settings.
  • Ordered by last insert or update.

Second, a transaction may be open—or, worse, left open—which will prevent the new record from appearing in a select query.

A third factor comes into play if the wrong cursor type has been selected when building the recordset. In some cases, MoveLast moves to the last record that has been visited in the current recordset. If not all records have been visited, MoveLast will stop somewhere in the "middle" of the set, or even at the first record.

Outside the scope of a transaction, and assuming the above factors aren't affecting you, it is risky to assume that the most recently inserted record is the record you just inserted. If an error occurs during the insert, your record may not exist, or someone else may have inserted a record at the same time.

Although a lot of cursor and locking options are available, the MSDN Architectural Samples team uses stored procedures for insertions. There are many advantages with this approach. Stored procedures have a lot of facilities to ease this task—including global variables such as @@IDENTITY, which returns the identity of the last record inserted by that connection—that are not available to a disconnected recordset. You also have much tighter control in the stored procedure than you would have with a disconnected recordset, and your code executes right on the server.

Here is a stored procedure that might be used to insert an order into an Orders table:

  @CustomerId INT
  ,@AllOtherNecessaryColumns NVARCHAR(255)
  ,@OrderId INT = 0 OUTPUT
INSERT INTO Orders (CustomerId, AllOtherNecessaryColumns)
SELECT @CustomerId, @AllOtherNecessaryColumns

This batch code would execute this stored procedure, and the output, the new OrderId, would be reliable.

DECLARE @AllOtherNecessaryColumns NVARCHAR(255)
SELECT @CustomerId = 5
SELECT @AllOtherNecessaryColumns = N'Something'
EXECUTE InsertOrder @CustomerId, @AllOtherNecessaryColumns, @OrderId OUTPUT
SELECT @OrderId AS 'The new OrderId'

A last point: An increment factor of one does not guarantee that the next number automatically generated will be one greater than the last. Should an error condition cause an insert to roll back, the number will have incremented internally and will not roll back automatically.

The Web Team in Short

Q: Kirk wants to send e-mail to a second address using the mailto: tag.

A: Separate them by a semi-colon, like;

Q: Jayashree would like to use cross-tab queries and display tables on a Web page.

A: Start with This is a good tutorial on displaying data queries on the Web.

Q: Li would like to manage the back-button behavior in Internet Explorer.

A: See Going Back and Forth as a start.

Q: Bob wants to know about the mailto: tag's limit for the BODY parameter.

A: In Outlook 9.0, running on Windows 2000, the tag limit is about 540 characters (more than the 256 you found). We believe this is actually a limitation of the operating system, rather than a limitation of the e-mail program. Unless a reader has done some work along these lines and can comment in the space below, we'll address this issue more fully in a future column.

Q: James asks about using forms.

A: Excellent question. Start with the MSDN Library's Forms Overview and go from there.

© 2016 Microsoft