Manipulating ASP.NET Pages and Server Controls with JavaScript

Excerpt from Professional ASP.NET 3.5: in C# and VB

by Bill Evjen

Developers generally like to include some of their own custom JavaScript functions in their ASP.NET pages. You have a couple of ways to do this. The first is to apply JavaScript directly to the controls on your ASP.NET pages. For example, look at a simple Label server control, shown in Listing 1, which displays the current date and time.

Listing 1: Showing the current date and time

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
   TextBox1.Text = DateTime.Now.ToString()
End Sub

C#

protected void Page_Load(object sender, EventArgs e) {
   TextBox1.Text = DateTime.Now.ToString();
}

This little bit of code displays the current date and time on the page of the end user. The problem is that the date and time displayed are correct for the Web server that generated the page. If someone sits in the Pacific time zone (PST), and the Web server is in the Eastern time zone (EST), the page won’t be correct for that viewer. If you want the time to be correct for anyone visiting the site, regardless of where they reside in the world, you can employ JavaScript to work with the TextBox control, as illustrated in Listing 2.

Listing 2: Using JavaScript to show the current time for the end user

<%@ Page Language="VB" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Using JavaScript</title>
</head>
<body onload="javascript:document.forms[0]['TextBox1'].value=Date();">
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="TextBox1" Runat="server" Width="300"></asp:TextBox>
    </div>
    </form>
</body>
</html>

In this example, even though you are using a standard TextBox server control from the Web server control family, you can get at this control using JavaScript that is planted in the

onload

attribute of the

&lt;body&gt;

element. The value of the

onload

attribute actually points to the specific server control via an anonymous function by using the value of the

ID

attribute from the server control:

TextBox1

. You can get at other server controls on your page by employing the same methods. This bit of code produces the result illustrated in Figure 1.

Figure 1
Figure 1

ASP.NET uses the

Page.ClientScript

property to register and place JavaScript functions on your ASP.NET pages. Three of these methods are reviewed here. More methods and properties than just these two are available through the

ClientScript

object (which references an instance of

System.Web.UI.ClientScriptManager

), but these are the more useful ones. You can find the rest in the SDK documentation.

The

Page.RegisterStartupScript

and the

Page.RegisterClientScriptBlock

methods from the .NET Framework 1.0/1.1 are now considered obsolete. Both of these possibilities for registering scripts required a key/script set of parameters. Because two separate methods were involved, there was an extreme possibility that some key name collisions would occur. The

Page.ClientScript

property is meant to bring all the script registrations under one umbrella, making your code less error prone.

Using Page.ClientScript.RegisterClientScriptBlock

The

RegisterClientScriptBlock

method allows you to place a JavaScript function at the top of the page. This means that the script is in place for the startup of the page in the browser. Its use is illustrated in Listing 3.

Listing 3: Using the RegisterClientScriptBlock method

VB

<%@ Page Language="VB" %>

<script runat="server">
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
      Dim myScript As String = "function AlertHello() { alert('Hello ASP.NET'); }"
      Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "MyScript", _
         myScript, True)
    End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Adding JavaScript</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="Button1" Runat="server" Text="Button"
         OnClientClick="AlertHello()" />
    </div>
    </form>
</body>
</html>

C#

<%@ Page Language="C#" %>

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
      string myScript = @"function AlertHello() { alert('Hello ASP.NET'); }";
      Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
         "MyScript", myScript, true);
    }
</script>

From this example, you can see that you create the JavaScript function

AlertHello()

as a string called

myScript

. Then using the

Page.ClientScript.RegisterClientScriptBlock

method, you program the script to be placed on the page. The two possible constructions of the

RegisterClientScriptBlock

method are the following:

  • RegisterClientScriptBlock

    (type, key, script)

  • RegisterClientScriptBlock

    (type, key, script, script tag specification)

In the example from Listing 2-9, you are specifying the type as

Me.GetType()

, the key, the script to include, and then a

Boolean

value setting of

True

so that .NET places the script on the ASP.NET page with

&lt;script&gt;

tags automatically. When running the page, you can view the source code for the page to see the results:

<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
    Adding JavaScript
</title></head>
<body>
    <form method="post" action="JavaScriptPage.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE"
 value="/wEPDwUKMTY3NzE5MjIyMGRkiyYSRMg+bcXi9DiawYlbxndiTDo=" />
</div>

<script type="text/javascript">
<!--
function AlertHello() { alert('Hello ASP.NET'); }// -->
</script>

    <div>
        <input type="submit" name="Button1" value="Button" onclick="AlertHello();"
         id="Button1" />
    </div>
    </form>
</body>
</html>

From this, you can see that the script specified was indeed included on the ASP.NET page before the page code. Not only were the

&lt;script&gt;

tags included, but the proper comment tags were added around the script (so older browsers will not break).

Using Page.ClientScript.RegisterStartupScript

The

RegisterStartupScript

method is not too much different from the

RegisterClientScriptBlock

method. The big difference is that the

RegisterStartupScript

places the script at the bottom of the ASP.NET page instead of at the top. In fact, the

RegisterStartupScript

method even takes the same constructors as the

RegisterClientScriptBlock

method:

  • RegisterStartupScript

    (type, key, script)

  • RegisterStartupScript

    (type, key, script, script tag specification)

So what difference does it make where the script is registered on the page? A lot, actually!

If you have a bit of JavaScript that is working with one of the controls on your page, in most cases you want to use the

RegisterStartupScript

method instead of

RegisterClientScriptBlock

. For example, you’d use the following code to create a page that includes a simple

&lt;asp:TextBox&gt;

control that contains a default value of

Hello ASP.NET

.

<asp:TextBox ID="TextBox1" Runat="server">Hello ASP.NET</asp:TextBox>

Then use the

RegisterClientScriptBlock

method to place a script on the page that utilizes the value in the

TextBox1

control, as illustrated in Listing 4.

Listing 4: Improperly using the RegisterClientScriptBlock method

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
   Dim myScript As String = "alert(document.forms[0]['TextBox1'].value);"
   Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "myKey", myScript, _
      True)
End Sub

C#

protected void Page_Load(object sender, EventArgs e)
{
   string myScript = @"alert(document.forms[0]['TextBox1'].value);";
   Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
      "MyScript", myScript, true);
}

Running this page (depending on the version of IE your are using) gives you a JavaScript error, as shown in Figure 2.

Figure 2
Figure 2

The reason for the error is that the JavaScript function fired before the text box was even placed on the screen. Therefore, the JavaScript function did not find

TextBox1

, and that caused an error to be thrown by the page. Now try the

RegisterStartupScript

method shown in Listing 5.

Listing 5: Using the RegisterStartupScript method

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
   Dim myScript As String = "alert(document.forms[0]['TextBox1'].value);"
   Page.ClientScript.RegisterStartupScript(Me.GetType(), "myKey", myScript, _
      True)
End Sub

C#

protected void Page_Load(object sender, EventArgs e)
{
   string myScript = @"alert(document.forms[0]['TextBox1'].value);";
   Page.ClientScript.RegisterStartupScript(this.GetType(),
      "MyScript", myScript, true);
}

This approach puts the JavaScript function at the bottom of the ASP.NET page, so when the JavaScript actually starts, it finds the

TextBox1

element and works as planned. The result is shown in Figure 3.

Figure 3
Figure 3

Using Page.ClientScript.RegisterClientScriptInclude

The final method is

RegisterClientScriptInclude

. Many developers place their JavaScript inside a

.js

file, which is considered a best practice because it makes it very easy to make global JavaScript changes to the application. You can register the script files on your ASP.NET pages using the

RegisterClientScriptInclude

method illustrated in Listing 6.

Listing 6: Using the RegisterClientScriptInclude method

VB

Dim myScript As String = "myJavaScriptCode.js"
Page.ClientScript.RegisterClientScriptInclude("myKey", myScript) 

C#

string myScript = "myJavaScriptCode.js";
Page.ClientScript.RegisterClientScriptInclude("myKey", myScript); 

This creates the following construction on the ASP.NET page:

<script src="myJavaScriptCode.js" type="text/javascript"></script>

This excerpt is from Chapter 2, "ASP.NET Server Controls and Client-Side Scripts," of the upcoming Professional ASP.NET 3.5: in C# and VB (Wrox, Feb-2008, ISBN: 978-0-470-18757-9). Bill Evjen (St. Louis, MO) is one of the most active proponents of the .NET technologies. He has been involved with .NET since 2000 and has since become the founder of the International .NET Association representing more than 500,000 members worldwide. In addition to working in the .NET world, Bill is a Technical Director serving in the office of the Chief Scientist for the international news and financial services company Reuters. Bill is the lead co-author of the upcoming (Feb-2008) Professional ASP.NET 3.5: in C# and VB and the best-selling ASP.NET 2.0 book Professional ASP.NET 2.0. Other related articles of interest by Bill and his co-authors Scott Hanselman and Devin Rader include Connecting to Oracle or Access from ASP.NET 2.0, Using the ASP.NET 2.0 SQL Server Cache Dependency, and ASP.NET 2.0 FileUpload Server Control.

Tags:

Comments

Leave a Reply

What is 13 + 3 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)