Nội dung Text: ASP.NET 1.1 Insider Solutions- P5

188 5
Creating Reusable Content
LISTING 5.26 Continued
dropbox.CssClass = CssClass.ToString()
textbox2.CssClass = CssClass.ToString()
End If
dropbox.Attributes.Add(“onclick”, “selectList(‘“ & sCID _
& “‘, ‘dropbox’, ‘textbox2’)”)
textbox2.Attributes.Add(“onkeyup”, “scrollList(‘“ & sCID _
& “‘, ‘dropbox’, ‘textbox2’)”)
dropbtn.Attributes.Add(“onclick”, “return openList(‘“ _
& sCID & “‘)”)
dropbox.DataSource = DataSource
dropbox.DataTextField = DataTextField
dropbox.DataTextFormatString = DataTextFormatString
dropbox.DataBind()
Else
pchStandard.Visible = True
If CssClass “” Then
listbox.CssClass = CssClass
textbox.CssClass = CssClass
End If
listbox.Attributes.Add(“onclick”, “selectList(‘“ & sCID _
& “‘, ‘listbox’, ‘textbox’)”)
textbox.Attributes.Add(“onkeyup”, “scrollList(‘“ & sCID _
& “‘, ‘listbox’, ‘textbox’)”)
listbox.DataSource = DataSource
listbox.DataTextField = DataTextField
listbox.DataTextFormatString = DataTextFormatString
listbox.DataBind()
End If
SetWidth()
SetRows()
End Sub
Now you can apply any CSS classname that may have been specified for the CssClass property
to both the list and text box. Then you add the attributes to the text box and list that attach the
client-side script functions. You use the complete ID of this instance of the user control (which
you generated earlier) and specify the appropriate text box and list control IDs. If you’re creat-
ing a drop-down combo box, you also have to connect the openList function to the list control.
Next, you set the data binding properties of the list within the user control to the values speci-
fied for the matching properties of the user control and call the DataBind method. In fact, you
could check whether the DataSource property has been set first, before setting the properties and

Using the ComboBox Control 189
calling DataBind. This would probably be marginally more efficient, although the DataBind
method does nothing if the DatSource property is empty.
Finally, you call the SetWidth and SetRows routines again to ensure that any conflicting CSS styles
are removed from the constituent controls. And that’s it; the ComboBox control is complete and
ready to go. You’ll use it in a couple simple sample pages next to demonstrate setting the prop-
erties and using data binding.
Using the ComboBox Control
The first example of using the ComboBox control contains three instances and applies three differ-
ent styles to them so that you can see the possibilities (see Figure 5.10). You can find this page
in the samples that you can download for this book (see www.daveandal.net/books/6744/), or you
can just run it online on our server (also see www.daveandal.net/books/6744/). There is a [view
source] link at the bottom of the page that you can use to see the source code and the source of
the .ascx user control.
FIGURE 5.10
The ComboBox user control demonstration
page in action.
The page contains a Register directive for the ComboBox control:
As shown in Listing 5.27, three instances of the ComboBox control are then declared within the
section of the page. However, because the constituent controls reside within a

190 5
Creating Reusable Content
element or a element (depending on the mode specified), you have to use another
element to place a caption next to them. Listing 5.27 shows the attributes you specify
for each one to apply the CSS style class (defined elsewhere in the page) and the other proper-
ties you set declaratively.
LISTING 5.27 The Declaration of the ComboBox Controls in the Sample Page
Simple Combo List Box:
Styled Drop-down Combo Box:
Wide and More Rows Drop-downCombo Box with Larger Font:
Select Combo Box and specify action to apply:
Display the syntax by calling the ShowMembers method
...
... other controls here to set properties ...
...

Using the ComboBox Control 191
The sample page also contains a RadioButtonList control that is used to specify which of the
three ComboBox controls you want to apply the property settings to dynamically and a series of
controls to specify the action to carry out on the selected ComboBox control. They are not all
shown in Listing 5.27 to avoid unnecessary duplication. Notice that the Value properties of the
items in the RadioButtonList control are the IDs of the three ComboBox controls.
Populating the ComboBox Controls from an ArrayList Instance
The Page_Load event handler is shown in Listing 5.28. If the current request is not a postback,
you set the radio button to the first option and then create an ArrayList instance containing the
values to be displayed in the ComboBox control list. By using data binding, you can apply this to
all three of the ComboBox controls, just as you would any other list control—but with one excep-
tion. The user control in this example automatically calls the DataBind method when it loads
(after the current Page_Load event has occurred for the hosting page), so you don’t do it here.
You can also take advantage of the DataTextFormatString property exposed by the ComboBox
control to specify how the values are formatted in the third instance. This gives the effect you
see in Figure 5.10 (for example, Animal ‘buffalo’).
LISTING 5.28 The Page_Load Event Handler in the Sample Page
Sub Page_Load()
If Not Page.IsPostback Then
‘ executed when page is first loaded
‘ select first combobox in radiobutton list
optCbo.SelectedIndex = 0
‘ create ArrayList to populate comboboxes
Dim aVals As New ArrayList()
aVals.Add(“aardvark”)
aVals.Add(“baboon”)
aVals.Add(“buffalo”)
aVals.Add(“cheetah”)
aVals.Add(“frog”)
aVals.Add(“giraffe”)
aVals.Add(“lion”)
aVals.Add(“lynx”)
‘ assign to DataSource of comboboxes
cboTest1.DataSource = aVals
cboTest2.DataSource = aVals
cboTest3.DataSource = aVals
‘ set display format string for third combobox

192 5
Creating Reusable Content
LISTING 5.28 Continued
cboTest3.DataTextFormatString = “Animal ‘{0}’”
End If
End Sub
Displaying the Members of the ComboBox User Control
When the user clicks the Show Members button, the routine named ShowMembers in the hosting
page is executed. In it, you first have to get a reference to the ComboBox control currently selected
in the RadioButtonList control. Then you call the ShowMembers method of this ComboBox control to
get back a string, and you display that in a Label control in the page (see Listing 5.29). To see
the result of this, refer to Figure 5.9.
LISTING 5.29 Calling the ShowMembers Method
Sub ShowMembers(oSender As Object, oArgs As EventArgs)
‘ get a reference to the selected comboxbox control
Dim oCtrl As Object = Page.FindControl(optCbo.SelectedValue)
‘ call ShowMembers method of combobox control
lblResult.Text = oCtrl.ShowMembers()
End Sub
Displaying Details of the Selected Item
The sample page contains a button that displays details of the item currently selected in the
ComboBox control. Figure 5.11 shows the output that this generates in the page, and you can see
the values for the SelectedIndex, SelectedValue, and SelectedItem properties, plus the items in the
list, as obtained by iterating through the Items collection.
FIGURE 5.11 The output of the
ShowMembers method of the
ComboBox control, as
displayed in a Web page.

Using the ComboBox Control 193
Listing 5.30 shows the code that executes when this button in the hosting page is clicked. After
the code gets a reference to the currently selected ComboBox control, a StringBuilder instance is
used to create the string that is displayed in a Label control. Again, the process of extracting the
values from the ComboBox control is exactly the same as you would use with any other Web
Forms list control.
LISTING 5.30 The ShowSelected Routine That Calls the ShowMembers Method
Sub ShowSelected(oSender As Object, oArgs As EventArgs)
‘ get a reference to the selected comboxbox control
Dim oCtrl As Object = Page.FindControl(optCbo.SelectedValue)
‘ use a StringBuilder to hold string for display
Dim sResult As New StringBuilder(“Property Values:”)
‘ collect details of current selection from combobox
sResult.Append(“SelectedIndex: “ & oCtrl.SelectedIndex & “”)
sResult.Append(“SelectedValue: “ & oCtrl.SelectedValue & “”)
sResult.Append(“SelectedItem.Text: “ & oCtrl.SelectedItem.Text & “”)
‘ collect all items in the combobox list
sResult.Append(“ListItems Collection:”)
For Each iItem as ListItem In oCtrl.Items
sResult.Append(iItem.Text & “”)
Next
‘ display results in the page
lblResult.Text = sResult.ToString()
End Sub
Setting the Properties of the ComboBox User Control
The remaining buttons in the sample page set various properties of the selected ComboBox control,
including SelectedIndex, SelectedValue, Width, and Rows. They validate the values first to make sure
they are of the correct data types and within range. Then, after obtaining a reference to the
current ComboBox control, as in the previous examples, they apply the property setting(s) to it. This
chapter doesn’t list all the code for these routines because it is extremely repetitive, but you can
see it by using the [view source] link at the bottom of the page at www.daveandal.net/books/6744/.

194 5
Creating Reusable Content
Populating the ComboBox Control
The sample page described in this section (populating.aspx) demonstrates different ways of
populating the ComboBox user control. As in the previous example, it registers the control with a
Register directive and then declares three instances of it. This time, they are all of the default
style. However, the lists are filled using three different techniques this time, as you can see in
Figure 5.12.
FIGURE 5.12 Filling the ComboBox control
list, using different data
sources and data binding.
The first list is filled using the same ArrayList instance as in the previous example. The second is
filled from the Northwind sample database that is supplied with SQL Server, using the values
from the ProductName column of the Products table. The third ComboBox control is filled by creat-
ing new ListItem instances in code and adding them to the ComboBox control’s Items collection
(the ListItemCollection instance exposed by the Items property). This section of code also
demonstrates how you can access a specific item in the list and read or change its value.
All this is done within the Page_Load event
Editing the Connection String handler for the sample page, with the excep-
You must edit the connection string in the tion of a separate routine that creates a
web.config file to point to your database
DataReader instance for the table in the
server, and you must specify the correct user-
Northwind database. Listing 5.31 shows the
name and password if you run the examples
on your own server. complete code for this sample page.
LISTING 5.31 Code That Demonstrates Techniques for Populating the ComboBox Control
Sub Page_Load()
If Not Page.IsPostback Then
‘ populate combobox controls

196 5
Creating Reusable Content
LISTING 5.31 Continued
‘ be sure to close connection if error occurs
If oConnect.State ConnectionState.Closed Then
oConnect.Close()
End If
‘ display error message in page
lblErr.Text = oErr.Message
End Try
End Function
Summary
This chapter begins by looking at the techniques that are available in ASP.NET for creating
reusable content and for reducing the amount of repetitive work you need to do when building
Web sites and Web applications. While the server-side include approach is still valid, there are
better ways. User controls and custom server controls both offer advantages, and they provide a
natural approach that integrates well with ASP.NET in both style and effectiveness.
Other techniques briefly discussed in this chapter are using master pages and templates and
wrapping existing COM/COM+ components for use in ASP.NET. Chapter 9, “Page Templates”
looks in more depth at the first of these options, but this book does not pursue the COM/COM+
wrapper technique any further.
The second part of this chapter walks through the design and construction of a nontrivial user
control that implements a feature that is missing from the standard range of browser-based
control elements—a dual-mode combo box. You saw how it uses constituent controls, how to
expose properties and methods, and how to use code within the control to manage its behavior
and appearance.
Finally, to complete the chapter, you saw how you can use the new ComboBox control in ASP.NET
pages. However, this chapter does not address a few issues. One is the way that the client-side
script within the control works; we’ll come back to this issue in Chapter 6. Another is the
general compatibility of the control in different browsers. As you’ve seen in this chapter, the
sample ComboBox control works fine in Internet Explorer 5.0, and it also works well in the latest
versions of Opera. However, there are issues in other browsers, especially older ones. In subse-
quent chapters, you’ll see how you must understand the issues, how you can address them, and
how you can build controls that adapt to suit a wider range of browser types.

6 IN THIS CHAPTER
Client-Side Interaction on the Web 198
Useful Client-Side Scripting
Client-Side Techniques 207
Summary 240
Script
Integration
A SP.NET provides plenty of clever server-
side controls that ultimately generate HTML
elements in the browser. However, with the
notable exception of the validation controls
and one or two other features, that’s really
all they do. In fact, when they start to build
Web applications, most developers who are
used to building Windows applications find
that the interface features Web developers
have become accustomed to using are quite
poor.
We can’t do much about the actual client-
side HTML elements and controls that are
available because that’s the whole nature of
the Web. Content is supposed to be univer-
sally supported in all browsers, and browsers
are supposed to follow accepted standards.
Therefore, if your application needs some
fancy new kind of multistate psychedelic
flashing button, you’re going to have to
find a way to build it yourself. And depend-
ing on how you implement it, you might
then have to find a way to persuade all the
people who use your site to download this
great new control and install it on their
machine.

198 6
Client-Side Script Integration
Client-side scripting has been a feature of
Avoiding Meaningless and Annoying Content Web development for almost as long as the
In reality, most people have seen enough in the Web in its current incarnation has been
way of annoying Java applets, malicious ActiveX
around. Scripting provides an increasing
controls, time-wasting Flash animations, and
number of useful features that you can take
pointless Shockwave effects. They expect an
application to do what it says on the box by advantage of to make Web applications
being intuitive and easy to understand and appear more seamless, responsive, and inter-
working seamlessly and as fast as possible, active, while still running well in almost all
given the nature of Internet connections. popular browsers in use today.
This book is about ASP.NET and not client-
side scripting, but, in fact, the two are no longer really divisible. ASP.NET generates client-side
script in varying quantities, depending on the server controls you place on a page. Even simple
effects such as auto-postback depend on some client-side script.
And you saw client-side script being used in the ComboBox control you created in Chapter 5,
“Creating Reusable Content.”
This chapter takes a look at the major client-side script issues that affect you when you create
ASP.NET pages, as well as when you create reusable content such as user controls and server
controls. This is by no means a reference work on client-side scripting, but it reinforces some of
the basic techniques and demonstrates useful ways that even very simple script can solve
common issues you come up against when building ASP.NET Web applications.
Client-Side Interaction on the Web
Client-side interaction is hard to achieve because of the disconnected nature of HTTP and the
way that browsers and Web servers work. Information is passed to and from the client only
during distinct phases of the Web-surfing process. The server builds the page and sends it to the
browser, and the browser submits the page back to the server when it’s ready for another one.
Okay, so there are some well-known ways that you can get around this issue, usually by
installing a component in the browser that can send and receive HTTP requests without having
to reload the current page. The XMLHTTP component within the MSXML parser in Internet
Explorer 5 and above is a good example. You can also use Macromedia Flash and a range of
third-party plug-ins or components for other browsers. However, the point is that if you want a
page to be interactive to the extent that it “does stuff” while loaded into the browser, you need
to find a way to execute code within the confines of the browser.
When you’re building items of reusable content, as demonstrated in Chapter 5, client-side
scripting allows you to push the envelope beyond the simple flow layout of HTML controls to
provide extra features that are often seen in traditional executable applications. The following
sections explore the fundamental aspects of where, when, and how—and then move on to look
at some useful techniques that integrate client-side and server-side programming and provide
examples you can use in your own pages.

Client-Side Interaction on the Web 199
Client-Side Scripting in the Browser
Client-side scripting has been supported in the mainline Web browsers since Netscape Navigator 2
and Internet Explorer 3. These browsers, and many others, support the simple HTML Document
Object Model (DOM) by exposing specific elements to script that runs within the browser. Such
elements include frames, forms, controls (such as and ), images, links, and
anchors ( elements with name=”...” rather than href=”...”). Script can also access the funda-
mental objects such as the current window and the document within a frame or a window.
This level of accessibility to the page content allows the traditional effects such as reading and
setting the values of controls, submitting a form, or swapping images in an element. It
also supports a small set of useful events, such as detecting when a control gets or loses the
focus or receives a click (via keyboard or mouse). However, this basic level of support for script-
ing does not offer the three main features that you often need when building better controls or
interactive content:
n Access to all the elements on the page, with the ability to read and set the content of each
one, show or hide it, and generally manipulate it.
n Access to a full range of keypress events, so that you can manage how a control behaves,
depending on user interaction via the keyboard.
n The ability to position elements outside the flow model, using fixed (absolute) coordinates
that are relative to a container (such as the page or a parent element). It’s nice to be able
to do this dynamically and even be able to move elements around while the page is
displayed.
CSS2 and Dynamic HTML
While much has been made of the “browser wars” over the past few years, the situation today
regarding the use of client-side scripting is actually a lot more favorable than it was. Microsoft
and Netscape added a feature set they called Dynamic HTML to their version 4 browsers,
although the blatant incompatibility between them (and the resulting outcry from Web devel-
opers and standards bodies alike) was perhaps one of the key factors in the evolution of more
comprehensive client-side standards over the following years.
Today we have Cascading Style Sheets (CSS) at version 2, HTML at version 4, and XHTML at
version 1.0; together, they provide not only a comprehensive display model based on the origi-
nal CSS recommendation but also a standard set of methods for accessing and manipulating
document content from script or code running on the client. While these recommendations are
fundamentally similar to the original Microsoft implementation in Internet Explorer 4, there are
subtle differences. However, the mainline manufacturers all have “version 6” browsers available
that generally do meet the basic CSS2, HTML4, and XHTML recommendations. These include
the following:

200 6
Client-Side Script Integration
n Internet Explorer 5.x and 6.x, although CSS2 support is generally more comprehensive and
less buggy in version 6 than in earlier versions. And there are still some issues with the way
that the box display model works.
n Mozilla 1.x (effectively a version 6 browser) and Netscape 6.x, which use the same render-
ing engine (depending on minor version number) and generally support the latest stan-
dards very well. Minor exceptions are
CSS2 Support in Version 6 Browsers occasional buggy rendering, particular with
absolutely positioned elements.
In reality, some of the more esoteric features
of CSS2 are not fully supported in all version n Opera 6.x and 7.x, which both have
6 browsers or are less than totally compatible comprehensive support for the latest stan-
across the different version 6 browsers. dards, although problems with dynamic
However, the basic techniques that we take
positioning have occurred in version 6.0.
advantage of in our examples do work in all
Opera 4.0 and 5.0 also supported CSS2 to
the current version 6 browsers.
a large extent.
Selecting Your Target
Are most users out there using a version 6 browser? Admittedly, our own Web site is mainly
aimed at developers working with the latest Microsoft technologies, so the results we see are
probably not representative of the population, but around 75% of our visitors are using Internet
Explorer 5 or higher, Netscape/Mozilla 6 or higher, and Opera 6 or higher. Looking at the stats
available on other sites, the percentage of visitors using these newer browsers varies from some-
thing over 55% to almost 90%.
It’s probably reasonable to assume that you
Why Use the Latest Browser? can take advantage of CSS2 and HTML4
You probably wouldn’t want to risk driving on features to add client-side interactivity to your
an icy freeway during rush hour in a 1910 pages, without affecting the majority of users.
Model T Ford. Four-inch-wide tires, vague
Of course, that doesn’t mean you can ignore
steering, and a distinct lack of braking
the rest because there are issues such as
performance when compared to those in
modern vehicles, would make this a risky providing accessibility to users of text-only
undertaking at the best of times. Likewise, browsers, page readers, and other devices
using an old and unsupported browser is an aimed at specialist markets or disabled users.
equally foolhardy adventure these days, with
The language of choice for client-side
the proliferation of malicious scripts, annoying
programming is, of course, JavaScript—because
Java applets, and downright dangerous
ActiveX controls that are out there on the only Internet Explorer can natively support
Web and being delivered daily in junk email VBScript. There are several versions of
messages. Most car drivers appreciate the JavaScript available, but the “vanilla” version
added safety of antilock brakes, airbags, and 1.x satisfies almost all requirements for the
seatbelts, and the sensible browser user does simple client-side interactivity you need when
the same by choosing the latest browser so building most user controls and server con-
that he or she can stay secure with the trols. And because Internet Explorer actually
updates and patches provided for it. has its own JScript/ECMAScript interpreter

Client-Side Interaction on the Web 201
rather than a real JavaScript one, staying with the features in JavaScript 1.0 or 1.1 provides the
best compatibility option.
Version 6 Browser-Compatible Code Techniques
Given the three tasks listed earlier in this chapter that you most commonly need to accomplish
in client-side script—access to all elements, access to keypress information, and dynamic posi-
tioning of elements—the following sections look at how these can be achieved in modern
browsers using script.
Accessing Elements Within a Page
Internet Explorer 4 was the first mainstream browser to provide full access to all the elements in
a page by exposing them from the document object as a collection called all. It also allowed selec-
tion of a set of elements by type, via the use of the getElementsByTagname method. While CSS2
provides the same getElementsByTagname method, it replaces the document.all collection with two
methods named getElementById and getElementByName. Because ASP.NET sets the id and name
attributes of an element that is created by a server control to the same value (with the exception
of the element), the getElementById and getElementByName methods gener-
ally provide the same result.
Therefore, the technique for getting a reference to an element within client-side script depends
on whether you are only going to send the page to a CSS2-compliant client or whether you
want the code to adapt to different client types automatically. The accepted technique for
providing adaptive script in a page is to test for specific features that identify the browser type
or the support it provides for CSS2. These features are summarized in Table 6.1.
TA B L E 6 . 1
Features You Can Use to Detect the Browser Type or Its Feature Support
Feature Description
document.all collection Supported by Internet Explorer 4.0 and above
document.layers collection Supported by Netscape Navigator 4.x only
getElementById method Supported by CSS2-compliant browsers
By using the features described in Table 6.1,
you can write code such as that shown in Using the ASP .NET
Listing 6.1 to execute different sections of BrowserCapabilities Object
script, depending on which browser loads the You can use the ASP.NET
BrowserCapabilities object to sniff the
page. Notice that this causes Internet Explorer
browser type and deliver the appropriate
5.x to execute the CSS2-compliant code. If
page or include the appropriate script or
you find that this does not perform correctly
controls. Chapter 7, “Design Issues for User
with your specific client-side scripts, you can Controls,” and Chapter 8, “Building Adaptive
change the tests so as to place Internet Controls,” demonstrate this approach.
Explorer versions 4.x and 5.x into the
same section by checking the value of the
navigator.appName and navigator.appVersion properties as well.

202 6
Client-Side Script Integration
LISTING 6.1 Detecting the Client’s Feature Support in Script Code
if (document.getElementById) {
... code for CSS2-compliant browsers here ...
}
else if (document.all) {
... code for IE 4.x here ...
}
else if (document.layers) {
... code for Netscape Navigator 4.x here ...
}
else {
... code for older browsers here ...
}
However, as discussed earlier, the number of users still running Navigator 4.x and Internet
Explorer 4.x is extremely low, so you generally need to test only for CSS2 support and provide
fallback for all other browsers. There’s not a lot of point in spending long development times on
supporting browsers that only 1% of users may still be running.
Accessing Keypress Information
Microsoft’s early implementation of Dynamic HTML exposed three keypress events for all the
interactive elements on a page and for the document object itself. These are the keydown, keypress,
and keyup events, and they occur in that order. The keypress event exposes the ANSI code of the
key that was pressed, and the other two events expose a value that identifies the key itself (as
located within the internal keyboard mappings) rather than the actual character.
Listing 6.2 shows the generally accepted technique for detecting a keypress that works in
Internet Explorer version 4.x and higher and in CSS2-enabled browsers. If the event is exposed
by the window object, as in Internet Explorer 4 and above, it is extracted from the keyCode prop-
erty of the event object. In CSS2-compliant browsers, the event is passed to the function by the
control to which the function is attached as a parameter, and it can be extracted from the which
property.
LISTING 6.2 Detecting a Keypress Event and the Code of the Key That Was Pressed
...

Client-Side Interaction on the Web 203
LISTING 6.2 Continued
window.status = iKeyCode.toString();
//-->
Dynamic and Absolute Element Positioning
The final feature set that you often need a browser to support when creating user controls and
server controls is a way of positioning elements within and outside the usual flow of the page,
changing that setting dynamically, and specifying the size of elements. Again, the original
Microsoft Dynamic HTML approach has survived almost intact in CSS2, so these features are
available in Internet Explorer 4.x and above, as well as in CSS2-compliant browsers. In more strict
terms, the features that you are most likely to take advantage of are summarized in Table 6.2.
TA B L E 6 . 2
Dynamic and Absolute Element Positioning Features
Feature Description
Showing and hiding elements Set the display selector of the style attribute to block, inline,
or hidden. Other values can be used, but these three are most
useful. The value block forces this element to start on a new line
and following content to wrap to a new line. The value inline
means that preceding and following content will be on the same
line, unless that content forces a new line. The value hidden
removes the element and all child elements from the page.
Absolute positioning Set the position selector of the style attribute to absolute to
fix an element using the top and left coordinates provided as the
top and left style selectors. This removes the element from the
flow layout of the page. The alternative is position:relative,
which forces the element to follow the flow layout of the page but
also allows it to act as a container within which child elements
can be absolutely positioned. If no parent element contains
position:absolute or position:relative, the current element
is positioned with respect to the top left of the browser window.
Specifying the actual size of elements Set the width and height selectors of the style attribute to
fixed values. These values can be specified with units px (pixels),
pt (points), in (inches), cm (centimeters), mm (millimeters), or pc
(picas) or the typographical units em, en, and ex. The default is px.
Positioning and moving elements dynamically The values for the display, position, top, left, width, and
height selectors can be changed while the page is loaded, and
the page will immediately reflect these changes by showing, hiding,
or moving the element.
The Client-Side Code in the ComboBox User Control
To demonstrate the feature sets described so far in this chapter, let’s briefly review some of the
code from Chapter 5, “Creating Reusable Content.” That chapter shows how easy it is to build a
ComboBox user control for use in browsers that support CSS2 (see Figure 6.1).

Client-Side Interaction on the Web 205
LISTING 6.3 Continued
list.style.display = ‘block’;
btnimg.src = document.getElementById(sCtrlID + ‘imageup’).src;
}
else {
list.style.display = ‘none’;
btnimg.src = document.getElementById(sCtrlID + ‘imagedown’).src;
}
return false;
}
Alternative Client Support Options
The code in Listing 6.3 doesn’t provide support for non-CSS2 browsers. This is because the only
ones that support another feature needed for this control (absolute positioning) are Internet
Explorer 4.x and Netscape 4.x. Because the
number of hits likely to be encountered from Accessing the document.all Collection
these two browsers is negligible, it doesn’t and the getElementID Method in
seem worth supporting them. JavaScript
Remember that document.all is a collection
However, extending support to Internet (array) of elements, so in JavaScript, you must
Explorer 4 isn’t hard; you would just need to use square brackets ([]) to access the
add the test for the document.all collection, as members. On the other hand, getElementId
shown in Listing 6.4, and then access the uses ordinary parentheses (()) because it’s a
elements by using this collection. The remain- method, and you are providing the element ID
ing code will work fine as it is. as a parameter.
LISTING 6.4 Adapting the selectList Function to Work in Internet Explorer 4.x
function selectList(sCtrlID, sListID, sTextID) {
var list;
var text;
if (document.all) {
list = document.all[sCtrlID + sListID];
text = document.all[sCtrlID + sTextID];
}
else {
list = document.getElementById(sCtrlID + sListID);
text = document.getElementById(sCtrlID + sTextID);
}
text.value = list.options[list.selectedIndex].text;
if (sListID == ‘dropbox’) openList(sCtrlID);
}

206 6
Client-Side Script Integration
Keypress Events in the ComboBox Control
The scrollList function shown in Listing 6.3 continually selects the first matching value in the
list while the user is typing in the text box section of the ComboBox. To work, it must be called
every time a key is pressed so that it can search the list for the appropriate value (if one exists).
To achieve this, you handle the onkeyup event, which runs when the user releases a key.
You attach the scrollList function to the input element that implements the text box by using
server-side code (as shown in Chapter 5). When the page gets to the client, the HTML declara-
tion of the text box (with the nonrelevant style information omitted) looks like this:
You can see that a keyup event will pass the three required parameters to the scrollList func-
tion. However, you aren’t actually interested in detecting which key was pressed because the
function just compares the values within the text box and the list to figure out which entry to
select. This means that you don’t have to pass the event object (required to detect which key
was pressed in Netscape and Mozilla browsers) as a parameter. In later examples, you’ll see occa-
sions where you do need to detect the actual key value.
Element Positioning in the ComboBox Control
The version of the ComboBox control that provides a drop-down list uses absolute positioning to
fix the width of the enclosing element, the width of the text box within it, and the posi-
tion and size of the list that implements the drop-down list part of the control. You can
see in Listing 6.5 that the top of the list is positioned 25 pixels below the top of the text box
and 20 pixels to the left of the text box. The widths of the text box and list are adjusted accord-
ingly, depending on the width of the enclosing element. All these values are calculated on
the server and are used to create the style selectors shown in Listing 6.5.
LISTING 6.5 The Style Selectors for Positioning the Text Box and List in the ComboBox User Control
aardvark
...
lynx

Useful Client-Side Scripting Techniques 207
Notice that the list has the selector display:none so that it’s not visible in the page when it loads.
Likewise, the two elements that hold the up and down button images are not visible
either. They are simply there to preload the images so that they can be instantly switched when
the user opens and closes the list.
Showing and Hiding the List Control
The code in the openList function shown in Listing 6.3 has the job of showing and hiding the
drop-down list when the user clicks the up/down button or makes a selection from the list. It’s
simply a matter of switching the display selector for the list between none and block, depending
on whether the list is already open or closed. At the same time, you switch the button image.
The relevant code section is shown in Listing 6.6.
LISTING 6.6 Showing and Hiding the Drop-Down List Part of the ComboBox Control
if(list.style.display == ‘none’) {
list.style.display = ‘block’;
btnimg.src = document.getElementById(sCtrlID + ‘imageup’).src;
}
else {
list.style.display = ‘none’;
btnimg.src = document.getElementById(sCtrlID + ‘imagedown’).src;
}
Useful Client-Side Scripting Techniques
The following sections demonstrate some useful client-side scripting techniques. These tech-
niques are some of the several that regularly crop up as questions on ASP.NET mailing lists and
discussion forums:
n Trapping an event that occurs on the client and popping up a confirmation dialog before
carrying out the action on the server (for example, getting the user to confirm that he or
she wants to delete a row in a DataGrid control).
n Trapping a Return keypress to prevent a form from being submitted or trapping any other
keypress that might not be suitable for a control or an application you are building.
n Handling individual keypress events (for example, implementing a MaskedEdit control).
n Creating a button that the user can click only once—effectively creating a form that can
only be submitted once. This prevents the user from causing a second postback, which
might interrupt server-side processing, when nothing seems to be happening at the client.
The following sections start by examining the ways you can inject client-side confirmation
dialogs into ASP.NET code and then look at how to trap keypresses and prevent a form from
being submitted.