Coming Up for Air

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.

By Jay Allen, Mark Davis, Heidi Housten, and Tosh Meston
Microsoft Corporation

June 3, 2002

We had to lock away the Xboxes to get some work done; they were just too much fun. Without further ado, please welcome the newest Web Team member and Halo hog, Tosh Meston! We put him through the paces this month, and not just on the virtual slopes. We hope you will be as pleased as we are with Tosh's contributions to the team. This month we show how to implement help in a Web page, wax lyrical about states of ASP.NET, and even do a little modalling.

We have a full complement now on the team and we'll be full speed ahead, unless Tosh finds the keys to the Xbox cupboard.

Contents

The Perfect Modal—don't lose your dialog
Get Help—and give it to your users
It's Just a State of Mind—keeping track with ASP.NET
Web Team in Short

The Perfect Modal

Dear Web Team:

I am trying to create a modal input form that pops-up over a form that is already displaying information that needs to be referenced to fill out the pop-up.

I have tried using the onFocus/onBlur events of the fields on the form to come up with a way of bringing the form to the top if the user clicks outside of the form. This methodology seems to only get me into a deadly embrace where the onFocus/onBlur events of the input fields fight with each other.

I have tried using onBlur="self.focus();" on the BODY tag. This results in the input fields never getting focus from the BODY.

I don't want to use DIVs because I want to prevent the user from actioning buttons on the underlying screen (That why I want it Modal). Any suggestions?

Regards,
Mike Kramer

The Web Team replies:

The feature you seem to want, showModalDialog, was introduced way back in Internet Explorer 4.0. The modal dialog box is rarely used. In fact, among the team we may have seen it in use once, not counting our own wonderful samples.

It is a little different from just opening a new window. One nice feature is that you can send parameters to it when it opens and return values to the main window when the modal dialog closes. The parameters can be a value of any type, including objects or arrays. They are accessed using the window.dialogArguments property of the modal dialog.

In the following sample, we illustrate passing an array of parameters containing two strings and an array to the modal dialog box.

main.htm:

<HTML><HEAD>
<STYLE>
BODY { FONT-FAMILY: comic sans MS ; FONT-SIZE: 10pt }
.maroon { COLOR: maroon }
</STYLE>
<SCRIPT LANGUAGE="vbscript">
Sub doit_onclick
   Dim something(2)
   something(1) = "x"
   something(0) = "z"
   something(2) = "y"

   retval = window.showModalDialog (_
   "dialog.htm",_
   Array(iName.value,iColor(iColor.selectedIndex).value,something),_
   "dialogWidth:20; dialogHeight:20")

   If IsArray(retval) Then
      iName.value = retval(1)
   Else
      iName.value = retval
   End If

End Sub
</SCRIPT>
</HEAD>
<BODY BGCOLOR="lightyellow" TEXT="darkgreen">
<CENTER>
<BR><BR><BR><BR>
<SPAN CLASS="maroon"><FONT SIZE="+1">A Modal Window Example!</FONT></SPAN><BR>
<BR><BR><BR><BR>
Please enter your name:<BR>
<INPUT TYPE="text" ID="iName" VALUE="Kalle Anka" SIZE=15><BR>
<BR>
Pick a color:<BR>
<SELECT ID="iColor">
   <OPTION VALUE="dodgerblue">blue</OPTION>
   <OPTION VALUE="red">red</OPTION>
   <OPTION VALUE="gold">gold</OPTION>
</SELECT>
<BR>
<BR>
and click!<BR>
<INPUT TYPE="button" ID="doit" VALUE="show me">
<BR>
</CENTER></BODY></HTML>

The modal dialog box checks the incoming parameters and dynamically creates the select box from the array called 'something' that we passed in as the last parameter. The color selected in the select box in body.htm is used for the background of the modal window.

When the user clicks the button, we make another array containing a string and the value of the text box in the modal dialog, and put that in the returnValue of the window. The retval variable in main.htm will contain the value returned by the modal dialog box. The second element of retval is put back into the text box in main.htm.

dialog.htm:

<HTML><HEAD>
<TITLE>The focus is all mine!</TITLE>
<SCRIPT LANGUAGE=vbscript>
Sub doneit_onclick()
   returnValue = Array("Yahoo!", uname.value)
   window.close
End Sub
</SCRIPT>
</HEAD>
<BODY>
<B>Please change your details below:</B><BR>
<SCRIPT LANGUAGE="vbscript">
   If IsArray(window.dialogArguments) Then
     inarr = window.dialogArguments
     document.bgcolor = inarr(1)

     document.writeln "<select>"
     For Each param In inarr(2)
           document.writeln "<option value=""" & param &  """> " & param
     Next
     document.writeln "</select>"

     document.writeln "<input name=uname value=""" & inarr(0) & """><br>"
   End If
</SCRIPT>
<INPUT TYPE="button" VALUE="All Done" ONCLICK="doneit_onclick">
<BR><BR>
</BODY>
</HTML>

And there you have it, the modal form in Internet Explorer!

Note   For security reasons, the window cannot be less than 100 pixels wide. The modal dialog can point to other domains, so think about security when planning what parameters to pass.

Get Help

Dear Web Team:

I create Web applications that look and feel just like Windows EXEs, but they reside on the Web and use DHTML, ASP, and Internet Explorer. To fully round out the Web application experience, I'd like to use the context-sensitive help icon located in DHTML pop-up windows, such as those created by showModalDialog and showModelessDialog.

I notice that when creating such windows I can specify whether or not I want that help icon to appear in the titlebar. But how do I actually create the help resources necessary to allow a user to click the help icon, then click an element in the window to bring up the little pop-up window explaining what that element does? Is the context-sensitive help icon just there for looks, or is it actually possible to create a help resource file that works just like in a Windows EXE? Or do I need to write a bunch of code to simulate it with things like ONMOUSEOVERs and ONCLICKs and just ignore the help icon? The latter wouldn't be so bad if I could actually detect that a user has clicked on the help icon in the titlebar.

Thanks!
Aaron

The Web Team replies:

Wow, you got us thinking with this one, Aaron! Thanks for the great research project. This took some work, although we were able to get on the right track right away. There is the onHelp event and the showhelp method that we noticed in the documentation. The problem is the docs say that you can use a regular compiled HTML Help file or HTML files. It seems the compiled help will only work in a situation where you are hosting the Web browser in your own application. For regular Web sites you need to use the regular html files that you include in your compiled help, or any other HTML files for that matter.

Let's use the previous question's code as a base for this answer. Add the following function to the script block in main.htm:

Function helper(helpFile)
   window.showHelp helpFile
   window.event.returnValue = false
End Function

The helper function shows the requested file using window.showHelp and then sets the event.returnValue to false to keep the event from bubbling up through the document hierarchy. This keeps prevents the Internet Explorer help file from opening.

Now change the html for the text box to the following:

<INPUT TYPE="text" ID="iName" VALUE="Kalle Anka" SIZE="15"
               ONHELP="helper('iNamehelp.htm')">

Save the changes to main.htm and then put the following in iNamehelp.htm in the same directory as main.htm.

<HTML>
<HEAD>
<TITLE>Using This Modal Dialog</TITLE>
</HEAD>
<BODY>
Click on the help button in the title bar and then click on one of the 
elements in the modal window for more information on it
</BODY>
</HTML>

Open main.htm in Internet Explorer, put your cursor in the text box, and press F1. You should see an HTML Help window containing iNamehelp.htm. Sweet! Now that wasn't hard was it?!

Now, what about that little "What's this?" question mark icon? Well, there is an HTMLHelp object that seems to be meant to be used for displaying normal help files in a Web application, but we couldn't quite get that working, and in the end actually found that one of the main uses for it, tool tip/"What's this?" type help, required putting the strings into variables and then putting the right string into the control. It seemed to us to be easier to use the pop-up with the script variables instead.

So let's add "What's this?" help to the modal dialog box. Create the file modalhelp.vbs and put the following code in it:

Dim helptxt(10)
helptxt(0) = "help text 0"
helptxt(1) = "help text 1"
helptxt(2) = "help text 2"
helptxt(3) = "help text 3"
helptxt(4) = "help text 4"
helptxt(5) = "help text 5"
helptxt(6) = "help text 6"
helptxt(7) = "help text 7"
helptxt(8) = "help text 8"
helptxt(9) = "help text 9"
helptxt(10) = "help text 10"

This could be put in the script block in the .htm file, but since help is often generated by someone other than the developer, let's keep them separated so all the help messages are in one place. This makes it easier for non-technical staff to update the help information.

Now add the following code to the script block in the dialog.htm file:

Dim helpPop
Dim oPopupBody

Sub init()
   Set helpPop = window.createPopup
   Set oPopupBody = helpPop.document.body
   oPopupBody.style.backgroundColor = "lightyellow"
   oPopupBody.style.border = "solid black 1px"
   oPopupBody.style.fontfamily = "verdana"
   oPopupBody.style.fontsize = "8pt"
End Sub
Sub popper(topicId)
   oPopupBody.innerText = helptxt(topicID)
   helpPop.show window.event.x, 10, 100, 25, window.event.srcElement
End Sub

The init subroutine sets up the properties of the pop-up window while the popper subroutine displays the pop-up window with the requested help text.

Change the body tag of dialog.htm to the following:

<BODY ONLOAD="init">

Now add calls to the popper subroutine to each of the elements of the form in dialog.htm. First the dynamic select box needs to be changed. Change the line of code that writes the opening select statement to the following:

document.writeln "<SELECT ONHELP='popper(1)'>"

Change the text box line to:

document.writeln "<INPUT NAME=""uname"" VALUE=""" & _
      inarr(0) & """ ONHELP=""popper(2)""><BR>"

Finally, add help to the button:

<INPUT TYPE="button" VALUE="All Done" ONCLICK="doneit_onclick" onHelp="popper(3)">

Now save dialog.htm and open main.htm in the browser. Click on the button to open the modal dialog box, and then click on the "What's this?" icon in the top right corner of the dialog box next to the X for closing the window. Now click on one of the three elements on the form to get the "What's this?" help. Now go out there and give help to your customers!

It's Just a State of Mind

Dear Web Team:

I'm starting to develop ASP.NET Web applications and I am confused about the different ways to store state information that can be accessed by each Web form.

George

The Web Team replies:

The ASP.NET programming model offers significant improvements over traditional ASP (Active Server Pages) development. On the server-side, an individual Web form is represented by a class that is derived from System.Web.UI.Page that is instantiated by ASP.NET when the associated .ASPX file is requested by a browser. The Page object acts as a container for the ASP.NET server controls and provides programmatic access to the server control hierarchy, and server-side event handlers. Along with the design and programming support provided by Microsoft Visual Studio® .NET, we think you'll find ASP.NET an intuitive and enjoyable development environment.

Despite the advances that ASP.NET programming provides, developers are still faced with the same issues of communicating across the Internet because the standard protocol is HTTP (HyperText Transfer Protocol), and is stateless. The ASP.NET Page object only exists for a short period of time on the Web server, somewhere between the page being requested and the HTML being returned to the browser, and has no knowledge of other Web form requests. This means that if you have global variables in your Page class, these will be initialized each time the page is requested. Given the short-lived nature of server-side objects, how can developers store state information that can be used to communicate between each page request and between the server and client?

The ASP.NET solution to the stateless nature of Web pages is mostly the same as for ASP, with some additions such as ViewState and XML Web services. The state information can be stored on the server or the client, with the information being transferred between the server and client in the HTTP headers or HTML content. There are numerous reasons for choosing which method to use and you need to consider factors such as privacy, security, size of the data, and data usage, among others. These are important design decisions that are outside the scope of this article.

Web Services

ASP.NET Web services provide a remote procedure call mechanism that can be invoked from a URL. Web services return information in the form of XML that can easily be parsed on the client using an XML parser component. When you use the WebService behavior that is available for Microsoft Internet Explorer, a Web service can be accessed as easy as calling a method on an object, and can return the data in a specific format. Although it's easy to think of Web services providing methods to return data, they can also provide a mechanism for writing and reading. See the MSDN Favorites Service for an example of how a Web service can provide data storage for a roaming user.

  • Pros: simple communication mechanism.
  • Cons: client needs to parse XML in order for it to work.

Application State

ASP.NET provides access to the Application object through the Page.Application property. The Application object provides a server-side mechanism for storing information that is available to all Web requests and sessions for the current Web application. Data is usually written in the Application_Start event handler in your global.asax file and then read during each Web form request.

  • Pros: initialized once during the first Web request; enables data and components to be shared between all Web requests.
  • Cons: only suitable for data that is modified infrequently.

Session State

ASP.NET provides access to the Session state object through the Page.Session property. The Session object provides a server-side mechanism for storing information that is available to all Web requests for the current user session. Each instance of a browser on the client machine will be represented by a different session. You can configure the Session object to use cookies (client) or use a session id (server) by setting the Cookieless field to False or True, respectively, in the sessionState section of the Web.config file.

  • Pros: ideal for storing user-specific information.
  • Cons: the Session object will timeout (default is 20 minutes).

View State

ASP.NET provides a new state management option that is primarily designed to enable server-side controls to save their internal states between requests. The ViewState object is associated with each control and can be used to store request-specific information. It is sent by the server to the client, and then returned to the server with each post-back (Web form request). You can manage which controls use ViewState by setting the EnableViewState field in the server control tag in your .aspx file.

  • Pros: ideal for request-specific information.
  • Cons: the size of the ViewState data can become prohibitive when using a large number of controls.

Permanent Storage

There are times when permanent storage is required, and this can include files and databases. Making use of ADO.NET to provide access to a database, such as Microsoft SQL Server™, can provide an excellent solution to a database-driven Web application. Alternatively, you could access a text or XML file; ideally, caching the information when the application first starts, since file i/o will have a big impact on your Web server performance.

  • Pros: permanent data storage.
  • Cons: could affect scalability of your Web application; need to consider data privacy.

Hidden Input Fields and Forms

The INPUT TYPE=HIDDEN HTML element can also be used to send information from the client to the server. When these controls are placed within an HTML FORM element, the contents are submitted along with other form controls and are available through the Page.Request.Form property. Hidden input fields can be a useful way to pass information between client-side script and your server-side ASP.NET code. The client-side script can save data in the hidden input fields, which is then submitted to the server. The server can also return information in a hidden input field, which is represented on the server by the ASP.NET HtmlInputHidden HTML control.

  • Pros: ideal for request-specific information, especially when client-side script is being used.
  • Cons: client-side script can be difficult to read and browser-specific.

Query String

A simple technique to pass small amounts of information between Web requests is to make use of the query string that can follow a URL. The query string consists of all the characters following the "?" character and is commonly used to provide parameters to Web applications, such as search engines. The query string data is accessed from the server ASP.NET code though the Page.Request.QueryString property.

  • Pros: simple technique.
  • Cons: limited to 1 KB of information; data is visible in the URL.

Cookies

If the client browser supports cookies, then this can provide for a small amount of client-side storage. The client cookies are sent in the header with each request and are available through the Page.Request.Cookies property. Setting the expiration date on a cookie will enable it to be persisted between browser sessions. If no date is set, then the cookie will be removed when the user closes the browser. Because cookies are sent between the server and client, you probably don't want to include sensitive data, or at least set the Secure property to True to specify that the cookie should only be sent to the server if a secure connection is used (HTTPS).

  • Pros: only stored on the client; can persist between browser sessions.
  • Cons: information is unavailable if the user moves to another computer; user may have set the browser to not use cookies; limited to 4 KB of data.

Web Team in Short

Don't Select the Text

Q: Paul wants to catch the double-click event on a cell, but wants to keep the text in the cell from being selected.

A: To stop the selection when you double-click an element on a page, all you need to do is return false in the onselectstart event handler, like this:

<DIV ONDBLCLICK="alert('Hello')" ONSELECTSTART="return(false)">double-click me</DIV>

Prompt Window Closing

Q: Waqas wants to stop the confirmation dialog box that sometimes pops up when closing a window through script.

A: There is no way to prevent this behavior. Invoking the window.close method on a window not opened with script, or on the last running instance of Internet Explorer will trigger a confirmation dialog box. This is good behavior from a user perspective. If someone has opened an Internet Explorer window to do something and a site suddenly closes it, they are going to be frustrated. If you want to close the window at the end, then open a window specifically for your application.

Chock Full of UserData

Q: Yoshiaki Kaneko has filled his UserData store on a page and would like to know how to empty it.

A: One can empty the UserData store through script by setting the expires property on the userData behavior to a time in the past in just the same way one would expire a cookie. In the example below, the function fnExpireInput() will set the expires property to one minute in the past, thereby emptying the data in this store. Try it out!

<HTML>
<HEAD>
<STYLE>
   .storeuserData {behavior:url(#default#userData);}
</STYLE>
<SCRIPT>
function fnSaveInput()
{
   var oPersist = oPersistForm.oPersistInput;
   oPersist.setAttribute("sPersist",oPersist.value);
   oPersist.save("oXMLBranch");
}
function fnLoadInput()
{
   var oPersist = oPersistForm.oPersistInput;
   oPersist.load("oXMLBranch");
   if (oPersist.getAttribute("sPersist") != null)
   {
       oPersist.value = oPersist.getAttribute("sPersist");
   }
}
function fnExpireInput()
{
   var oPersist = oPersistForm.oPersistInput;
   var oTimeNow = new Date();
   oTimeNow.setMinutes(oTimeNow.getMinutes() - 1);
   var sExpirationDate = oTimeNow.toUTCString();
   oPersist.expires = sExpirationDate;
   oPersist.save("oXMLBranch");
   oPersist.value = "";
}
</SCRIPT>
</HEAD>
<BODY>
<FORM ID="oPersistForm">
<INPUT CLASS="storeuserData" TYPE="text" ID="oPersistInput">
<INPUT TYPE="button" VALUE="Load" ONCLICK="fnLoadInput()">
<INPUT TYPE="button" VALUE="Save" ONCLICK="fnSaveInput()">
<INPUT TYPE="button" VALUE="Expire" ONCLICK="fnExpireInput()">
</FORM>
</BODY>
</HTML>

No Clipping, No Scrolling

Q: Ravi would like to load a page into an IFRAME and resize the IFRAME so that there are no scrollbars present and the content is not clipped.

A: In the example below, we initially set the width and height attributes of the IFRAME element to 1. On load, we check the scrollWidth and scrollHeight properties of the body of the document loaded inside the IFRAME to see if it is greater than the offsetWidth and offsetHeight properties of the IFRAME. We then set the width and height properties equal to the scrollWidth and scrollHeight properties plus a small buffer.

Be aware that we will encounter Access is denied errors if the document loaded in the IFRAME is from a different domain than the encompassing document. This is for security reasons.

<HTML>
<HEAD>
<SCRIPT>
function window.onload()
{
 if (frName1.document.body.scrollWidth > document.all.fr1.offsetWidth)
 {
  document.all.fr1.width = frName1.document.body.scrollWidth + 4;
 }
 if (frName1.document.body.scrollHeight > document.all.fr1.offsetHeight)
 {
  document.all.fr1.height = frName1.document.body.scrollHeight + 4;
 }
}
</SCRIPT>
</HEAD>
<BODY>
<IFRAME ID="fr1" NAME="frName1" HEIGHT="1" WIDTH="1" src="about:abc<BR>defghijklmnopqrst<BR>uvwxyz"></IFRAME>
</BODY>
</HTML>

The Web Team

Mark Davis is a software design engineer on the Internet Explorer SDK team. Mark originates from England and is currently training to climb the major summits in the Northwest.

Heidi Housten works as a Consultant with Microsoft Consulting Services in Sweden after spending some time in Developer Support and MSDN. It is only a rumor that she moved there to escape the drizzle of Seattle; she really went for the traditional crayfish parties in August.

Jay Allen, a Support Engineer for the Internet Client team in Microsoft Developer Support, longs for the integration of Notepad and Emacs Lisp. What little time is not consumed by his four children is usually spent reading math books, studying Japanese and programming in Haskell.

Tosh Meston is a Web developer on the Outlook Web Access team. He comes to Microsoft with a background in physics and spends his free time reading and perfecting his three-point shot on the basketball court.


The Web Team's Greatest Hits

List of Web Team Topics


  
Show: