WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

The Three Faces of ASP.NET AJAX
Pages: 1, 2, 3, 4, 5, 6

Example 2 shows how the <select> element is created.

Example 2. UserNameLookup.aspx.vb

Imports System.Data
Imports System.Data.SqlClient

Partial Class UserNameLookup
    Inherits System.Web.UI.Page

   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
      Handles Me.Load
      If (Request.QueryString.Count > 0) Then
         Dim queryUserName As String = Request.QueryString.Get(0).ToString()
         Dim dt As DataTable = UserNamesForPartialName(queryUserName)

         If (dt Is Nothing Or dt.Rows.Count = 0) Then
            UserNames.Text = _
              "Sorry no user names found with that letter combination."
         Else
            Dim returnString As String = String.Empty
            returnString = returnString + _
              "<select id='slctName' size=5 onchange=""SelectName();"">"
            Dim row As DataRow
            For Each row In dt.Rows
               returnString = returnString + "<option value='" + _
                  row("UserName").ToString() + "' >" + _
                  row("UserName").ToString() + _
                  "</option>"
            Next
            returnString = returnString + "</select>"
            UserNames.Text = returnString

         End If

      Else
         UserNames.Text = String.Empty
      End If
   End Sub

   Public Function UserNamesForPartialName(ByVal strPartialName As String) _
           As DataTable
      Dim connectionString As String = _
        ConfigurationManager.AppSettings("AdventureWorks")
      Dim connection As SqlConnection = New SqlConnection(connectionString)

      Dim queryString As String = _
        "select distinct LastName as UserName from Person.Contact where " + _
        "LastName like '" + _
        strPartialName + "%' order by LastName"
      Dim ds As DataSet = New DataSet()

      Try
         Dim dataAdapter As SqlDataAdapter = _
            New SqlDataAdapter(queryString, connection)
         dataAdapter.Fill(ds, "Names")
      Catch ex As Exception
         '' Handle exception
         UserNames.Text = ex.Message
      Finally
         connection.Close()
      End Try

      Return ds.Tables("Names")

   End Function

End Class
The username is stored in the Login column of the HumanResources.Employee table, in the form adventure-works\username. Rather than parse that out of the field, I cheated and just queried for the LastName column in the Person.Contact table. However, the query uses an alias, UserName, for the column returned. This is so that if you are so inclined, you can modify the query to retrieve the actual username from the database.

Open Default.aspx in Source view. You'll add all the JavaScript inside the <head> element at the top of the page. You'll also add an attribute to the TextBox txtName so that it will point to one of the JavaScript functions to handle the keyup event. Finally, you'll add a <div> element where the JavaScript function can insert the HTML you created in UserNameLookup's code behind.

Default.aspx is unchanged except for the script, so let's walk through the script one piece at a time.

<script language="javascript" type="text/javascript">
      var xmlHttp
      function showHint(str)
      {
         if (str.length==0)
         { 
            document.getElementById("TextBoxHint").innerHTML=""
            return
         }

         xmlHttp = new XMLHttpRequest()

         var url="UserNameLookup.aspx"
         url=url+"?q="+str
         xmlHttp.onreadystatechange=stateChanged 
         xmlHttp.open("GET",url,true)
         xmlHttp.send(null)
      }

The first method, showHint, takes a string (which it will get from the contents of the text box). If the string is empty, it sets the <div> (which we named TextBoxHint) to empty and returns. The innerHTML property of the

sets the text between the opening and closing tag of the <div>.

If the text is not empty, then the function creates XMLHttpRequest to handle asynchronous communication.

This is a bit of a simplification, but will do for now. In the actual downloadable code, we show a few ways to get what we need.

We set the url variable to the name of the aspx page that is going to look up the cities (UserNameLookup.aspx) and append to that name the characters "?q" indicating that we're going to pass in values to the query string object, and then we append whatever value we obtained from the text box (that is, the portion of the city name typed by the user).

var url="UserNameLookup.aspx"
url=url+"?q="+str

We are now ready to open UserNameLookup.aspx and wait for its processing to be completed, asynchronously. We need a call back so that we are notified when the xmlHttp object's onreadystatechange method fires (which it will when the called page finishes its work), and we assign the name of the method state changed:

xmlHttp.onreadystatechange=stateChanged

Having done, so we open the page and then send null to force the method call and to put us into a wait state.

Each time the onreadystatechange event fires, our stateChanged method is called and we examine it to see if the page is complete (ready state is complete or value 4) and the status is OK. If so, we take the responseText from the xmlHttp object and we assign it to the innerHTML of the Div, thus putting the listbox where we earlier had nothing!

 function stateChanged() 
 { 
    var OK = 200
    if (( xmlHttp.readyState == 4 || xmlHttp.readyState == "complete" ) 
      && xmlHttp.status == OK )
    { 
       document.getElementById("TextBoxHint").innerHTML = xmlHttp.responseText 
    } 
 }

You will need to add a connection string to web.config so that UserNameLookup can connect to the database. Add the following code snippet to web.config just before the <system.web> element:

<appSettings>
   <add key="AdventureWorks" value="Data Source=ServerName;
      Initial Catalog=AdventureWorks;Integrated Security=True;" />
</appSettings>

Run the app and type a character in the text box. The select list will appear below the text box and, as with the previous example, the button will become enabled and its text will change. Type a second character, and the list in the select box will narrow.

False Triggers
Figure 13. HardCoreAjax in action (Click to enlarge.)

Next Steps

We believe strongly that you can go for a long time using AJAX with the controls provided by Microsoft, and we strongly recommend compiling and exploring the samples provided with the Control Toolkit.

For more on extenders, the best bet is to start off with our sample and then to vary it, probably with a good book on JavaScript by your side (we recommend JavaScript The Definitive Guide by David Flanagan).

If you decide to dive into DHTML and to write raw AJAX code, our strongest recommendation is Dynamic HTML, the Definitive Reference by Danny Goodman, which was specifically updated for AJAX. Goodman is a wonderful writer.

All of the material in this article is expanded on for the new ASP.NET programmer in our forthcoming book Learning ASP.NET by Jesse Liberty and Dan Hurwitz. For a somewhat different perspective on the same material, it is also covered in Programming .NET 3 by Jesse Liberty and Alex Horovitz.

The code for this article is available on Jesse's website: http://www.GotDotNet3.com along with links to a support forum, errata, and other items of interest.

Jesse Liberty is a senior program manager for Microsoft Silverlight where he is responsible for the creation of tutorials, videos and other content to facilitate the learning and use of Silverlight. Jesse is well known in the industry in part because of his many bestselling books, including O'Reilly Media's Programming .NET 3.5, Programming C# 3.0, Learning ASP.NET with AJAX and the soon to be published Programming Silverlight.

Dan Hurwitz is the president of Sterling Solutions, Inc., where for nearly two decades he has been providing contract programming and database development to a wide variety of clients.


Return to the Windows DevCenter.