Dynamically Creating JavaScript in ASP.NET

In this section, I'll show you how to dynamically add JavaScript to server controls. This allows you to easily and powerfully change the behavior of your user interface. Special items can change color when the mouse hovers over them, additional clarification can be provided for specific users, and product information depending on a user's previous buying history can be provided.

The way it's done is with the Attributes collection. All controls derived from WebControl have this collection. It allows you to get and set arbitrary attributes that don't correspond to properties of the control. And in this case, we'll set JavaScript behaviors for events such as onMouseOver and onClick.

It's the Holy Grail: how to make your Web application grab and keep the attention of the user. It used to be easy; just insert an animated GIF image, and you'd easily capture the attention of users. But in this day and age of Flash presentations, an animated GIF image isn't too impressive. The other thing that people quickly learned is that a busy user interface doesn't necessarily make for a good user interface. Color change during a mouse-over is a visual hint that the option can be accessed with a mouse click. When you're performing a lengthy operation, motion on the screen gives the impression that the application is still running.

Another sought-after prize is a rich user interface that provides a lot of information without cluttering up the screen. There are times when you want to add explanatory text for various screen elements, but when you do, applications quickly run out of real estate.

Both of these issues can be effectively addressed with the right JavaScript code. With JavaScript, you can do things such as change text color when the mouse hovers over it, display additional explanatory text when the mouse hovers over special screen elements, and in general, add some eye-catching interactive events.

You may already be asking, "What does this have to do with ASP.NET?" The answer is, "Plenty." For starters, ASP.NET uses JavaScript frequently. For instance, the validation controls that check data users type in work by injecting JavaScript code into the HTML. This injected JavaScript code does the work of validating the user input and notifying users when the data is improper.

In addition, just because you're using ASP.NET server controls doesn't mean you can't use JavaScript. To use JavaScript events such as onMouseOver and onClick with server controls, all you need to do is add the appropriate attributes to the server control. I'll show you more about this in the section entitled "JavaScript Overview."

So far, everything sounds pretty straightforward you can use JavaScript to enhance your user interface. As my 14-year-old daughter would say, "Duh!" But this article talks about how to dynamically create JavaScript for server controls. This can be very useful if you have special items for which you want to add JavaScript events, but only at certain times. It's also effective to add special explanatory text for some screen items and have the text customized for the current user. For instance, if a user is on a preferred list, and a certain item is on sale on a certain day for preferred users, the item can change in response to this situation.

Server Controls Overview

ASP.NET comes with what are called server controls. Server controls aren't ActiveX or COM+ objects, but they are special server objects that can be placed onto an .ASPX page. These controls then render themselves as HTML that's sent to the client machine. Most of the server controls map to an HTML object. For instance, the asp:Button server control renders as an HTML button object.

Most people are already familiar with server controls, so I won't go into detail. I did cover them from a practical aspect in Chapter 2, if you want to refer to that chapter for more information, Server controls are placed into .ASPX code as XML, such as the following:

 <asp:TextBox  runat="server"></asp:TextBox> <asp:Button  runat="server" Text="Register"></asp:Button> 

Notice that each server control has attributes that determine the value of the control's properties. When you are programming code behind modules, auto complete shows the properties (and methods) that are available for server controls, as shown in Figure 17.1.

Figure 17.1. Visual Studio .NET Brings Up the List of Methods and Properties for Server Controls.

graphics/17fig01.jpg

It's also important to note that you can manually add any arbitrary attribute to a server control. Let's say that your application needs a custom attribute named Bozo. You could add this attribute to server controls as follows:

 <asp:TextBox  runat="server" Bozo="Me"></asp:TextBox> <asp:Button  runat="server" Text="Register"   Bozo="You"></asp:Button> 

When the server controls are rendered at the time of the client request, these arbitrary attributes will be part of the rendered HTML object, as follows:

 <input name="Test" type="text"  Bozo="Me" /> <input type="submit" name="Register" value="Register"     Bozo="You" /> 

This is an important point because adding the capability to catch JavaScript events for a server control relies on our ability to add arbitrary attributes. We'll talk about this in more detail in the next section.

JavaScript Overview

JavaScript executes on the client computer. It's code that's embedded within the HTML document, and then the client browser executes it. JavaScript has been used extensively for effects that fall under that category known as Dynamic HTML (DHTML). DHTML allows Web developers to provide rich user interfaces that do much more than pedestrian HTML. The HTML tells the browser how to render the user interface, and DHTML/JavaScript allows the user interface to react to user actions.

I'm going to use only three JavaScript events for the demonstration program in this chapter. You could extend the techniques I present, though, to do much more and use the full range of JavaScript events. The three events that we'll see in the demonstration program are onMouseOver, onMouseOut, and onClick.

To enable a JavaScript event for an HTML object, you simply add the event as an attribute to the HTML object, and set it equal to the action that is to be performed when the event is fired. For instance, if you want an alert box to appear when the mouse hovers over an HTML object, you could add the following attribute to the HTML object:

 onMouseOver="alert('Everyone is happy!');" 

If the above attribute was added to a button object, it might look like the following:

 <input type="submit" name="Test" value="Test"     onMouseOver="alert('Everyone is happy!');" /> 

You can add both an onMouseOver and an onMouseOut event. This would allow you to do things such as change the color when the mouse hovers over an HTML object, and have the HTML object restore itself to the original color when the mouse leaves the area. The following code turns the text "Hi There!" to red when the mouse enters the text area and restores the text to black when the mouse leaves the area.

 <span  onmouseover="style.color='red'"    onmouseout="style.color='black'">Hi there!</span> 

Adding JavaScript to Server Controls Dynamically

Adding onMouseOver and onMouseOut events to a server control by adding the appropriate attributes to the server control declaration doesn't require any further discussion because it's straightforward, and using these JavaScript events is well documented. My favorite Web site is www.WebMonkey.com, and my favorite book is Danny Goodman's Dynamic HTML Reference, from O'Reilly. It's when we dynamically set the onMouseOver and onMouseOut attributes for a server control that some explanation is necessary.

You can get or set any server control attribute with the Attributes collection (which all WebControl-derived controls have). The Attributes collection can't be used for standard server control properties, such as BorderColor and Visible. The standard server control properties should be accessed in the normal way, such as TextBox.BorderColor and Label.Visible. But for arbitrary attributes that aren't part of the normal set of properties, you can use the Attributes collection. In other words, the attributes collection is reserved for all attributes that have not been mapped to class properties.

Say, for example, you need to set the Bozo attribute to "Clown" for a TextField named CircusData. You could use the following code to do this from the code behind:

C#
 CircusData.Attribute["Bozo"] = "Clown"; 
VB
 CircusData.Attribute("Bozo") = "Clown" 

When the CircusData object renders, it will appear in the HTML as follows:

 <input name="CircusData" type="text 

This gives you a way to set arbitrary attributes for server controls from your code. With this technique, you can dynamically alter these attributes. It would be rare for you to want to change these attributes programmatically, but there are such cases when you need to alter custom attributes. It gets really interesting when you decide to add JavaScript to the Attributes collection. I'd like to revisit the example that sets some HTML text to red when the mouse enters the text's screen area, which can be found at the end of the "JavaScript Overview" section. Instead of an HTML <span> tag, we'll do the same thing with an ASP.NET Label object.

Let's say that the following Label object is in an .aspx file:

 <asp:Label  runat="server">Hi There!</asp:Label> 

You could make a decision in the code to add JavaScript to turn the code red when the mouse enters the text area, as follows:

 Test1.Attributes["onMouseOver"] = "style.color='red'"; Test1.Attributes["onMouseOut"] = "style.color='black'"; 

Then, when the Test1 server control was rendered as HTML, you would get the following:

 <span  onMouseOver="style.color='red'"    onMouseOut="style.color='black'">Hi There!</span> 

The Dynamic JavaScript Demonstration Application

I've created a demonstration application that shows how to dynamically add JavaScript to server controls. The application offers three pages that each do different things. One page simulates a product catalog in which one of eight items is on special sale. This item will change colors and display extra text when the mouse hovers over it. This technique could be useful if your Web application needed to attract the attention of users in a more subtle way than with a flashing, animated GIF image. This page can be seen in Figure 17.2.

Figure 17.2. When the Mouse Hovers over a Special Item, the Item Changes Colors and Displays Some Text.

The second page of the demonstration application shows how you can give additional information to users about buttons on the screen. Because the extra information is displayed only when users hover over a button, doing this can really give them a lot more information without cluttering up the screen.

graphics/17fig02.jpg

The third page adds JavaScript code to confirm user action, but only if the selected file is a system file. The third page of the demonstration application displays a list box with file names. Some of these are system files, and others are not. The user is provided with the capability to delete any of the files; and before a system file is deleted, a confirmation alert appears. This page can be seen in Figure 17.3.

Figure 17.3. This Page Asks for Confirmation before Deleting System Files.

graphics/17fig03.jpg

The SaleItems Code

Behind the SaleItems.aspx page is some fairly simple code, all found in the Page_Load() method. It first calls a method named GetSpecial Sale Index(), which returns an integer value from 0 to 7. Because there are eight Labels on the page, this integer value corresponds to the Label that contains the item that is on special sale.

There is a switch (for C#) or a Select (for VB) in which a small piece of code is executed so that the proper sale item becomes JavaScript-enabled. This is done by adding onMouseOver and onMouseOut events via the Attributes collection. The onMouseOver handler sets the text color for the Label object to blue, and then calls a JavaScript method named SetSpecial(). The SetSpecial() method populates a Label in which the special sale item will appear. The onMouseOut handler restores the text color to black and calls a JavaScript method named ClearSpecial(). The ClearSpecial() method simply clears the Label in which the special sale item appeared. The C# version can be seen in Listing 17.1 and is labeled SaleItems.aspx.cs; the VB version can be seen in Listing 17.2 and is labeled SaleItems.aspx.vb.

Listing 17.1 The SaleItems.aspx.cs Source Code
 int nSpecialSaleIndex = GetSpecialSaleIndex(); switch( nSpecialSaleIndex ) {   case 0:     Umbrella.Attributes["onMouseOver"] =       "style.color='blue'; " +       "SetSpecial('Umbrella');";     Umbrella.Attributes["onMouseOut"] =       "style.color='black'; " +       "ClearSpecial(); ";     break;   case 1:     Raincoat.Attributes["onMouseOver"] =       "style.color='blue'; " +       "SetSpecial('Raincoat');";     Raincoat.Attributes["onMouseOut"] =       "style.color='black'; " +       "ClearSpecial();";     break; ...   case 6:     CuffLinks.Attributes["onMouseOver"] =       "style.color='blue'; " +       "SetSpecial('Cuff Links');";     CuffLinks.Attributes["onMouseOut"] =       "style.color='black'; " +       "ClearSpecial();";     break;   case 7:     TieClip.Attributes["onMouseOver"] =       "style.color='blue'; " +       "SetSpecial('Tie Clip');";     TieClip.Attributes["onMouseOut"] =       "style.color='black'; " +       "ClearSpecial();";     break; } 
Listing 17.2 The SaleItems.aspx.vb Source Code
 Dim nSpecialSaleIndex As Integer = GetSpecialSaleIndex() Select Case nSpecialSaleIndex   Case 0     Umbrella.Attributes("onMouseOver") = _       "style.color='blue'; " + _       "SetSpecial('Umbrella');"     Umbrella.Attributes("onMouseOut") = _       "style.color='black'; " + _       "ClearSpecial(); "   Case 1     Raincoat.Attributes("onMouseOver") = _       "style.color='blue'; " + _       "SetSpecial('Raincoat');"     Raincoat.Attributes("onMouseOut") = _       "style.color='black'; " + _       "ClearSpecial();" ...   Case 6     CuffLinks.Attributes("onMouseOver") = _       "style.color='blue'; " + _       "SetSpecial('Cuff Links');"     CuffLinks.Attributes("onMouseOut") = _       "style.color='black'; " + _       "ClearSpecial();"   Case 7     TieClip.Attributes("onMouseOver") = _       "style.color='blue'; " + _       "SetSpecial('Tie Clip');"     TieClip.Attributes("onMouseOut") = _       "style.color='black'; " + _       "ClearSpecial();" End Select 

The CustomerService Code

To provide a better simulation, the user needs to type in his name and click the Register button. This way, the program can do a better job simulating feedback to a real, live user. A session variable named Name contains the name the user types in. When the user clicks the Register button, the Register_Click() method is called. This method sets the contents of the session variable, and then calls the SetJavaScriptForName() method (more about this shortly).

The CustomerService page provides three feedback elements for the three main buttons on the screen. When the user hovers over the first button, extra text naming the product that the user last purchased appears to the right of the button.

If you take a look at the Page_Load() method, you'll see that it checks for the existence of a session variable named Name. If this session variable is found, a method named SetJavaScriptForName() is called. This method sets up the dynamic JavaScript in response to the name that has been entered by the user.

The SetJavaScriptForName() method is where most of the work happens for the CustomerService page. At the top is an array of strings from which the extra information for the first button is retrieved. A random number from 0 to 3 determines which of these strings is used in the dynamic JavaScript. For most applications, you'd probably go to a database to get the product that was last purchased.

For the middle button, a text string based on the user's name is created. It might say, for example, "RMA number for Rick." The following code creates the string:

C#
 string strReturn = "RMA number for " + Session["Name"].ToString(); 
VB
 Dim strReturn As String = "RMA number for " + Session("Name").ToString() 

With the strReturn string, the RequestReturnAuth Button can then be set so that it contains the JavaScript with which it can display the extra text mentioned above.

The last thing that is done in this method is to create an account number based on the clock ticks. The following line creates the string:

C#
 string strOrder = "Account number: " +     Convert.ToString( DateTime.Now.Ticks ); 
VB
 Dim strOrder As String = "Account number: " + _     Convert.ToString(DateTime.Now.Ticks) 

Listing 17.3 shows the C# code for the CustomerService page's code. while Listing 17.4 shows the VB version.

Listing 17.3 CustomerService.aspx.cs
 private void Page_Load(object sender, System.EventArgs e) {   if( Session["Name"] != null )   {     SetJavaScriptForName();   } } private void SetJavaScriptForName() {   // One of these four strings will be selected   //   randomly for the first button's extra information.   string[] ServiceIssues =   {     "Regarding your widget",     "About the credenza you ordered",     "For your new lawnmower",     "In reference to your computer"   };   // Create a Random object from which we'll get   //   a random number.   Random rnd = new Random();   // Assign a string value to strService from the array   //   of strings based on a random number from 0 to 3.   string strService = ServiceIssues[rnd.Next(0,3)];   // Set the onMouseOver event so that the text for the   //   ServiceIssue Label changes as users hover over the button.   ReportServiceIssue.Attributes["onMouseOver"] =     "ServiceIssue.innerHTML='" + strService + "'";   // Set the onMouseOut event so that the text for the   //   ServiceIssue Label clears as users leave the button area.   ReportServiceIssue.Attributes["onMouseOut"] =     "ServiceIssue.innerHTML=''";   // Create the text based on the user's name.   string strReturn = "RMA number for " + Session["Name"].ToString();   // Set the onMouseOver event so that the text for the   //   ReturnAuth Label changes as users hover over the button.   RequestReturnAuth.Attributes["onMouseOver"] =     "ReturnAuth.innerHTML='" + strReturn + "'";   // Set the onMouseOut event so that the text for the   //   ReturnAuth Label clears as users leave the button area.   RequestReturnAuth.Attributes["onMouseOut"] =     "ReturnAuth.innerHTML=''";   // Create an account number based on the clock tick.   string strOrder = "Account number: " +     Convert.ToString( DateTime.Now.Ticks );   // Set the onMouseOver event so that the text for the   //   OrderMore Label changes as users hover over the button.   OrderMoreProduct.Attributes["onMouseOver"] =     "OrderMore.innerHTML='" + strOrder + "'";   // Set the onMouseOut event so that the text for the   //   OrderMore Label clears as users leave the button area.   OrderMoreProduct.Attributes["onMouseOut"] =     "OrderMore.innerHTML=''"; } private void Register_Click(object sender, System.EventArgs e) {   Session["Name"] = Name.Text;   RegisteredName.Text = "Registered as " + Name.Text;   Name.Text = "";   SetJavaScriptForName(); } private void ReportServiceIssue_Click(object sender, System.EventArgs e) {   MessageLabel.Text =     "Thanks, our efficent staff will attend to the issue."; } private void RequestReturnAuth_Click(object sender, System.EventArgs e) {   MessageLabel.Text = "The RMA number is 12345ABCDE."; } private void OrderMoreProduct_Click(object sender, System.EventArgs e) {   MessageLabel.Text = "Your product has been ordered."; } 
Listing 17.4 CustomerService.aspx.vb
 Private Sub Page_Load(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles MyBase.Load     If Session("Name") <> Nothing Then         SetJavaScriptForName()     End If End Sub Private Sub SetJavaScriptForName()     ' One of these four strings will be selected     '   randomly for the first button's extra information.     Dim ServiceIssues As String() = _     { _      "Regarding your widget", _      "About the credenza you ordered", _      "For your new lawnmower", _      "In reference to your computer" _     }     ' Create a Random object from which we'll get     '   a random number.     Dim rnd As New Random()     ' Assign a string value to strService from the array     '   of strings based on a random number from 0 to 3.     Dim strService As String = ServiceIssues(rnd.Next(0, 3))     ' Set the onMouseOver event so that the text for the     '   ServiceIssue Label changes as users hover over the button.     ReportServiceIssue.Attributes("onMouseOver") = _        "ServiceIssue.innerHTML='" + strService + "'"     ' Set the onMouseOut event so that the text for the     '   ServiceIssue Label clears as users leave the button area.     ReportServiceIssue.Attributes("onMouseOut") = _         "ServiceIssue.innerHTML=''"     ' Create the text based on the user's name.     Dim strReturn As String = "RMA number for " + _       Session("Name").ToString()     ' Set the onMouseOver event so that the text for the     '   ReturnAuth Label changes as users hover over the button.     RequestReturnAuth.Attributes("onMouseOver") = _      "ReturnAuth.innerHTML='" + strReturn + "'"     ' Set the onMouseOut event so that the text for the     '   ReturnAuth Label clears as users leave the button area.     RequestReturnAuth.Attributes("onMouseOut") = _      "ReturnAuth.innerHTML=''"     ' Create an account number based on the clock tick.     Dim strOrder as String = "Account number: " + _       Convert.ToString( DateTime.Now.Ticks )     ' Set the onMouseOver event so that the text for the     '   OrderMore Label changes as users hover over the button.     OrderMoreProduct.Attributes("onMouseOver") = _       "OrderMore.innerHTML='" + strOrder + "'"     ' Set the onMouseOut event so that the text for the     '   OrderMore Label clears as users leave the button area.     OrderMoreProduct.Attributes("onMouseOut") = _       "OrderMore.innerHTML=''" End Sub Private Sub Register_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles Register.Click     Session("Name") = Name.Text     RegisteredName.Text = "Registered as " + Name.Text     Name.Text = ""     SetJavaScriptForName() End Sub Private Sub ReportServiceIssue_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles ReportServiceIssue.Click     MessageLabel.Text = _       "Thanks, our efficent staff will attend to the issue." End Sub Private Sub RequestReturnAuth_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles RequestReturnAuth.Click     MessageLabel.Text = "The RMA number is 12345ABCDE." End Sub Private Sub OrderMoreProduct_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles OrderMoreProduct.Click     MessageLabel.Text = "Your product has been ordered." End Sub Private Sub Main_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles Main.Click     Response.Redirect("Default.aspx") End Sub 

The ConfirmActions Code

The ConfirmActions page responds to the Delete button and the FileList list-box-selection change. When users select a file in the list, JavaScript is dynamically added to the Delete button if the file that was selected is a system file. This way, when the user clicks the Delete button for a system file, a confirmation alert will appear with which the user can confirm or reject the action.Listing 17.5 shows the C# code for the ConfirmActions page, while Listing 17.6 shows the VB version.

Listing 17.5 The ConfirmActions.aspx.cs Source Code
 private void Delete_Click(object sender, System.EventArgs e) {   MessageLabel.Text = "Done!";   try   {     FileList.Items.RemoveAt( FileList.SelectedIndex );   }   catch   {   } } private void FileList_SelectedIndexChanged(object sender,  System.EventArgs e) {   MessageLabel.Text = "";   string strSelected = FileList.SelectedItem.Value;   // The items that must be confirmed contain   //   a '*' character.   if( strSelected.IndexOf( "*" ) >= 0 )   {     Delete.Attributes["onClick"] = "return ConfirmDelete();";   }   else   {     Delete.Attributes["onClick"] = ";";   } } private void Main_Click(object sender, System.EventArgs e) {   Response.Redirect( "Default.aspx" ); } 
Listing 17.6 The ConfirmActions.aspx.vb Source Code
 Private Sub FileList_SelectedIndexChanged(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles FileList.SelectedIndexChanged     MessageLabel.Text = ""     Dim strSelected As String = FileList.SelectedItem.Value     If strSelected.IndexOf("*") >= 0 Then         Delete.Attributes("onClick") = "return ConfirmDelete();"     Else         Delete.Attributes("onClick") = ";"     End If End Sub Private Sub Delete_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles Delete.Click     MessageLabel.Text = "Done!"     FileList.Items.RemoveAt(FileList.SelectedIndex) End Sub Private Sub Main_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs) Handles Main.Click     Response.Redirect("Default.aspx") End Sub 

Dynamically adding JavaScript to server controls is a very useful and powerful technique for enhancing the appearance, usability, and clarity of an ASP.NET Web application. It's easy to do with the Attributes collection that all server controls have.



ASP. NET Solutions - 24 Case Studies. Best Practices for Developers
ASP. NET Solutions - 24 Case Studies. Best Practices for Developers
ISBN: 321159659
EAN: N/A
Year: 2003
Pages: 175

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net