JavaScript with ASP.NET 2.0 Pages - Part 1

Published: 08 Jan 2007
By: Xun Ding

ASP.NET 2.0 has made quite a few enhancements over ASP.NET 1.x in terms of handling common client-side tasks. It has also created new classes, properties and method of working with JavaScript code. This article explores the enhancements and the various ways of injecting JavaScript programmatically into ASP.NET 2.0 pages.

Introduction

In ASP.NET 1.x days, many client-side tasks, such as tracking mouse events, setting page focus, displaying/hiding a section of page, was not directly supported by asp.net. This is because ASP.NET applications are server-based; all web control events are handled on the server side. The constant round trips to and from server often slows down work processes, and the page-refreshing often ensured a web form would to lose its focus or its scroll position. Therefore programmers still rely on a multitude of JavaScript to keep web pages nimble and responsive. However, in ASP.NET 1.x, injecting JavaScript always involves two steps and quite some code: First, you weave your JavaScript function into a string in your code-behind page; second, you use the Page class of your web form to register the script, using either the Page.RegisterStartupScript or the Page.RegisterClientScriptBlock method.

ASP.NET 2.0 has inherited some of the ASP.NET 1.x approaches of including JavaScript in a web form. Moreover, it has added many methods and properties to smooth and simplify the handling of some of the most common client-side tasks. It has also introduced new ways to include JavaScript on the server side or load JavaScript from resources. In this article will go into detail of the enhancements and the various ways of working with Script code in ASP.NET 2.0.

Client-Side Enhancements

In this section, we will consider three common client-side tasks that ASP.NET 2.0 have made as easy as setting properties of controls.

1. Setting focus to web controls

In ASP.NET 1.x, it is not possible to programmatically set focus to a web server control without a bit help from the JavaScript's function focus(). Here is how it was commonly done in C#:

//ASP 1.x method of setting focus to a specific control. You need
//to first pass the control's id as the parameter, then define the 
//JavaScript function in a string variable then call the Page class
//to register the script. You may use either RegisterStartupScript() 
//or RegisterClientScriptBlock() method.

private void SetFocus(String ctrlID)
{
  // Build the JavaScript String
  System.Text.StringBuilder sb = new System.Text.StringBuilder();
  sb.Append("<script language='javascript'>");
  sb.Append("document.getElementById('");
  sb.Append(ctrlID);
  sb.Append("').focus()");
  sb.Append("</script>")
  
  // Register the script code with the page.
  Page.RegisterStartupScript("FocusScript", sb.ToString());
}

However, in ASP 2.0, there are three ways to dynamically set the focus to a specific control, all in just one line of code. You pass the control ID as the parameter and call the Page.SetFocus(control) method, which enables you to set the focus to a particular control immediately after a page is initiated or loaded.

void Page_Init(object sender, EventArgs e)
{
  SetFocus(ControlToSetFocus);
}

Or you can call the Focus method that is available to all web controls. You can call it in the Page_load event or based on a user's response to set up a skip pattern. For example, if you have a TextBox web control called Textbox1, you may simply call:

TextBox1.Focus();

ASP 2.0 web forms also have a property called DefaultFocus. By setting the DefaultFocus property, you can set the focus to a desired control when page loads.

For example, the code below will automatically set the focus on TextBox2 when the web form is loaded:

<form defaultfocus="textbox2" runat="server">
  <asp:textbox id="textbox1" runat="server"/>
  <asp:textbox id="textbox2" runat="server"/>
</form>

2. Popping up Message Boxes

Confirming with users before they take actions with potentially irreversible consequences like record deleting is a common practice, so is alerting users about important information with a JavaScript alert box. In ASP.NET 1.x, with either a delete column of a DataGrid, or a regular web control, we need to attach the JavaScript alert(msg) or confirm(msg) function to the control's attributes or register the script with the Page class.

For example, we can use the following code to add the alert script to a button control:

<script language="C#" runat="server">
  protected  void Page_Load(object sender, EventArgs e){
    //Set the button's client-side onmouseover event
    btnClick.Attributes.Add("onClick", "alert('Ouch, you clicked me!');");
  }
</script>

<form runat="server">
  <asp:button runat="server" Text="Click Me!" id="btnClick" />
</form>

Or similarly we can attach the confirm(msg) script to a button.

<script language="C#" runat="server">
  protected void Page_Load(object sender, EventArgs e){
    //Set the button's client-side onmouseover event
    btnDelete.Attributes.Add("onClick", 
    "return confirm('You sure you want to delete the record?');");
  }
</script>

<form runat="server">
  <asp:button runat="server" Text="Delete!" id="btnDelete" />
</form>

However, with a ASP.NET 1.x DataGrid, we need to place the code for confirm messagebox in the DataGrid's OnItemDataBound or OnItemCreated event handler. The code below shows how this can be done in the OnItemDataBound event.

<script language="c#" runat="server">
  private void DataGrid1_ItemDataBound(Object sender, DataGridItemEventArgs e)
  {
    // First, make sure we're NOT dealing with a Header or Footer row
    If (e.Item.ItemType == ListItemType.Item || 
        e.Item.ItemType == ListItemType.AlternatingItem )
    {
      //Assume  the first column of DataGrid1 is the Delete ButtonColumn
      LinkButton deleteButton = e.Item.Cells(0).Controls(0);

      //We can now add the onclick event handler
      deleteButton.Attributes.Add("onclick",
      "javascript:return confirm('Are you sure you want to delete 
this record?')"
; } } </script> <form runat="server"> <asp:datagrid id="DataGrid1" runat="server" ... OnItemDataBound="DataGrid1_ItemDataBound"> ... </asp:datagrid> </form>

In ASP.NET 2.0, to add a client-side message box is just a matter of setting the OnClientClick property, as the following:

<asp:Button ID=button1 runat=server 
  OnClientClick="return('Are you sure you want to delete this record')" 
  Text="Delete Record" />

However, with GridView, the approach is similar to that of ASP.NET 1.x in terms of adding a confirmation box before deleting a GridView row. That is, you have to attach the confirm() script to the attributes of the delete column. Only with ASP.NET 2.0, you need to place the confirmation script within the RowDataBound event handler.

<script language="c#" runat="server">
  // ...
  protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
  {
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
      //suppose you have a link button column
      LinkButton l = (LinkButton)e.Row.FindControl("LinkButton1");
      l.Attributes.Add("onclick", 
      "javascript:return confirm('Are you sure you want to delete 
this record?'"
); } } </script>

As an alternative, you can convert the CommandField to a TemplateField and add a Button with the onClientClick property set to confirm().

<form id="form1" runat="server">
  <asp:SqlDataSource runat="server" 
    ID="SqlDataSource2" 
    ConnectionString="..."
    SelectCommand="SELECT [CategoryID], [CategoryName], 
                  [Description] FROM [Categories]"
    DeleteCommand="Delete from categories where categoryID=@categoryID">
    <DeleteParameters>
      <asp:Parameter Name=categoryID Type=int16 />
    </DeleteParameters>
  </asp:SqlDataSource>
  
  <asp:GridView ID="GridView2" runat=server AutoGenerateColumns="False"
  datasourceid="SqlDataSource2" DataKeyNames=CategoryID>
  <Columns>
    <asp:BoundField DataField="CategoryID" 
      HeaderText="ID"
      readonly=true/>
      <asp:BoundField DataField="CategoryName" HeaderText="Name"/> 
      <asp:BoundField DataField="Description" HeaderText="Description" />
      <asp:TemplateField HeaderText="Delete">
        <ItemTemplate>
          <asp:Button ID="deleteButton" runat="server" 
            CommandName="Delete" Text="Delete"
            OnClientClick="return confirm('Are you sure you want 
            to delete this record?');" />
        </ItemTemplate>
      </asp:TemplateField>
  </Columns>
  </asp:GridView>

  ...

3. Maintaining Page Scrolling Position

In ASP 2.0, it is very easy to maintain a web page's scrolling position across postbacks. To achieve this, simply add a page directive at the top of your webpage:

<%@ Page ... MaintainScrollPositionOnPostback="true" %>

However in ASP 1.x, it is not quite so simple, even though ASP.NET 1.x has a Smartnavigation page directive that supposedly enables you to achieve the same goal. But as noted in many online posts and publications, SmartNavigation has many known issues and it works only with Internet Explorer 5.5 or later. Several developers wrote some JavaScript code and wrapped the code inside a custom server control to work around the problem. For example, there is an article by Steve Stchur addressing this issue: Maintaining Scroll Position on Postback

Injecting JavaScript Code

ASP.NET 2.0 not only provides ways to simplify some of the most common client-side tasks, it also allows you to write and include your own JavaScript in a web form. There are three ways to do so:

  1. Injecting script blocks directly into a web page
  2. Including JavaScript on the server side
  3. Embedding JavaScript in Resources

As mentioned above, in ASP.NET 1.x, to include script in a web page, you always have to take two steps:

  1. Define the JavaScript in a string variable
  2. Register with the Page class

In ASP.NET 2.0, there is a similar approach. However, instead of the Page class, it is recommended you register the script using the methods exposed by the ClientScript property of the Page class. ClientScript is an instance of a new ASP.NET 2.0 class called ClientScriptManager. Moreover, ClientScript has many more new methods to work with JavaScript.

Injecting Script blocks on demand

Script blocks on demand are code that execute only if a code-specific event is triggered on the client side. To inject script blocks on demand, use ClientScript.RegisterClientScriptBlock. The following example shows how to pop up a new window when the button btnPopUp is clicked using the RegisterClientScriptBlock method:

<script runat="server">
  protected void btnPopUp_Click(object sender, EventArgs e)
  {
    //Build a Pop Up JavaScript
    //please note the peculiar '/script' in the last line of the script string
    //This is to work around the problem that compiler would mistake the 
    //closing script tag as the outer script closing tag.
    //For details, please see
    //http://support.microsoft.com/default.aspx?scid=kb;EN-US;827420

    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    sb.Append("<script language='javascript'>");
    sb.Append("window.open('javascript.htm', 'CustomPopUp',");
    sb.Append("'width=200, height=200, menubar=yes, resizable=no');<");
    sb.Append("/script>");

    //register with ClientScript
    //The RegisterStartupScript method is also slightly different
    //from ASP.NET 1.x
    Type t = this.GetType();
    if (!ClientScript.IsClientScriptBlockRegistered(t, "PopupScript"))
      ClientScript.RegisterClientScriptBlock(t,"PopupScript", sb.ToString());
  }
</script>

<form id="form2" runat="server">
  <asp:Button ID="btnPopUp" runat="server" 
    Text="PopUp" OnClick="btnPopUp_Click" />
</form>

Startup Script Blocks

Like the Page.RegisterStartupScript method with ASP.NET 1.x, ASP.NET 2.0 has ClientScript.RegisterStartupScript to execute JavaScript when the page first loads. The above example could be converted to:

// ...
Type t = this.GetType();
if (!ClientScript.IsStartUpScriptRegistered(t, "PopupScript"))
  ClientScript.RegisterStartUpScript(t,"PopupScript", popupScript);

Including JavaScript on the server side

You can also include external JavaScript files via codebehind. Let's say you have a JavaScript file called myJavaScript.js, and you would like include it inside the web form by using the RegisterClientScriptInclude method, as shown in the following:

ClientScript.RegisterClientScriptInclude("MyScript","MyJavaScript.js")

This piece of code will inject the following JavaScript include in your html code generated by the server:

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

Embedding JavaScript in Resources

In ASP.NET 2.0, you can also add your JavaScript or image files or CSS stylesheet as embedded resources. However, to do so, you must create a custom control, add necessary scripts or files to the project, then set the files property of Build Action as an embedded resources, as illustrated in the following screenshot:

For this article, I borrowed (however simplified) a custom control called AutoComplete Dropdownlist as an example. Briefly, to be able to access the JavaScript in the embedded resource, you need to take two steps: Declare the resource in the control's class file or in the AssemblyInfo.cs using the syntax:

[assembly: WebResource("{namespace}.{filename}", "{content-type}")]

And in our example, it would be:

[assembly: WebResource("WebControlLibrary1.AutoComplete.js", "text/javascript")]

By doing so, we mark the file as accessible through the WebResource.axd HTTP handler, then we may retrieve the actual file from the resources of the project's assembly by calling the method GetWebResourceUrl(type, webresource).

Now we can inject the JavaScript or other resource file by using the RegisterClientScriptInclude method.

protected override void OnPreRender(EventArgs e)
{
  base.OnPreRender(e);
  this.Page.ClientScript.RegisterClientScriptInclude("AutoComplete",
  this.Page.ClientScript.GetWebResourceUrl(typeof(AutoCompleteDropDownList),
  "WebControlLibrary1.AutoComplete.js"));
}

Summary

JavaScript is essential to keep web pages nimble and responsive. While ASP.NET 1.x has been cumbersome working with script, ASP.NET 2.0 has made great enhancements to remedy the limitations. It has made dealing with some of the most common client-side tasks as easy as setting control properties, and has introduced new classes and methods to allow injecting JavaScript into webforms more flexible.

Download

AutoComplete Dropdownlist

Further Reading

JavaScript with ASP.NET Pages - Part 2

References

Enhancing ASP.NET Pages with JavaScript
Accessing Embedded Resources through a URL using WebResource.axd
Client-Side Enhancements in ASP.NET 2.0
An ASP.NET 2.0 AutoComplete DropDownList...
Default Focus, Buttons and Validation Errors with ASP.NET 2.0
Dino Esposito (2005): Programming Microsoft ASP.NET 2.0 Applications: Advanced Topics. Microsoft Press. ISBN: 978-0-7356-2177-0.

About Xun Ding

Web developer, Data Analyst, GIS Programmer

View complete profile

Top Articles in this category

ASP.NET ComboBox
The ASP.NET ComboBox is an attempt to try and enhance some of the features of the Normal ASP.NET DropDownList.

Upload multiple files using the HtmlInputFile control
In this article, Haissam Abdul Malak will explain how to upload multiple files using several file upload controls. This article will demonstrates how to create a webform with three HtmlInputFile controls which will allow the user to upload three files at a time.

JavaScript with ASP.NET 2.0 Pages - Part 2
ASP.NET provides a number of ways of working with client-side script. This article explores the usage and drawbacks of ASP.NET script callbacks, and briefly presents a bird's view of ASP.NET AJAX.

Using WebParts in ASP.Net 2.0
This article describes various aspects of using webparts in asp.net 2.0.

An Architectural View of the ASP.NET MVC Framework
Dino Esposito introduces the ASP.NET MVC framework.

Top
 
 
 

Discussion


Subject Author Date
placeholder download not working m Fowle 2/27/2007 4:35 PM
RE: download not working Sonu Kapoor 2/27/2007 5:23 PM
placeholder Feedback Francesco Cavallaro 1/24/2008 5:03 AM
it's very use full..Thanks a lot. ramki.ch 6/19/2008 7:41 AM
placeholder Correction Steve Lawrence 5/9/2007 5:48 PM
whoops. Steve Lawrence 5/9/2007 5:50 PM

Please login to rate or to leave a comment.

Product Spotlight