Introduction To Asp .Net Ajax Client Side Development ($get, $addhandler, $removehandler, Sys.Application, Sys.WebForms, Sys.Net)

Asp .Net Ajax has many ways to accomplish simple and complex web application requirement. As a brief Asp.Net Ajax has Server and Client Side development.
Often Server and Client Side mixed to make Ajax development more confinient.

Server side development process UI update by sending a response from server machine whereas Client side process all UI update on client or user machine side.
In development point of view, Server side code is simpler. But the process uses more resources on server machine. Client side code requires more Js scripting, so in the end our client script may be much longer than server side script.
Client side Ajax development is more suitable for web applications that have complex user interaction since its doesn’t consume server resouces to update the UI.
But off course, your app logic still remains on server side.

I use Microsoft Ajax Library to simplify client side development. This Ajax Library is a rich framework and used extensively at client script.

If you are new to Asp.Net Ajax then you should visit my previous posts about Ajax Server Controls. I explained and gave example of Asp .Net Ajax for Server side development. Please visit these Urls:Introduction To Asp .Net Ajax (ScriptManager, UpdatePanel, ContentTemplate, Triggers) and Introduction to Asp .Net Ajax – 2 (UpdateProgress).
At general, we have to include controls like ScriptManager, UpdatePanel with its child tag <ContentTemplate> and <Triggers>, and also UpdateProgress.
ScriptManager is must to enable Ajax request. UpdatePanel contains all control which will have Ajax Process and UpdateProgress acts as progress info to indicate that asynchronous process is still working.

$get, $addHandler, $removehandler

$get provides a shortcut to the getElementById method. A Js code like document.getElementById("Button1") is same as $get("Button1"). $get shortcut returns an html element object.

$addHandler attachs an event to a control. Its signature is $addHandler(element, eventName, handler, autoRemove);. autoRemove is optional. To attach click event to Button1 just code

$addHandler($get("button1"), "click", button1_click);
function button1_click() {
	alert("button1 clicked");
}

$get(“button1”) is an element. “click” is an Event and button1_click() is a handler function.
$removeHandler removes an event from a control. To remove click event from button1 just code $removeHandler($get("button1"), "click", button1_click);

Sys.Application

This class provides a run-time object that exposes client events and manages client components that are registered with the application.
This Sys.Application class has methods like Sys.Application.add_load() to register pageLoad client script function name that runs on page load event and Sys.Application.add_unload() to specify client function name which runs when page unload.
Many methods Sys.Application has. Please visit http://msdn.microsoft.com/en-us/library/bb310856. About add_load, add_unload function check http://msdn.microsoft.com/en-us/library/bb383829.

Here’s a code block example of Asp .Net Ajax Client Side Development

<form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
        </asp:ScriptManager>
        
    <script type="text/javascript">
        Sys.Application.add_load(page_load);
        Sys.Application.add_unload(page_unload);

        var product;
        function page_load(sender, e) {
            product = $get("product");
            $addHandler(product, "change", product_onchange);
        }
        function page_unload(sender, e) {
            $removeHandler(product, "change", product_onchange);
        }

        function product_onchange(sender, e) {
            $get("balanceresult").innerHTML = "";
            $get("loading").style.display = "block";
            var prodval = product.value;
            PageMethods.GetStockBalance(prodval, GetStockBalance_success);
        }

        function GetStockBalance_success(response) {
            $get("loading").style.display = "none";
            $get("balanceresult").innerHTML = response;
        }
     </script>
     <h4>Ajax Client Component Example</h4>
        <select id="product" >
            <option value=""></option>
            <option value="Bike">Bike</option>
            <option value="Bag">Bag</option>
            <option value="Shoes">Shoes</option>
        </select><br />
        Stock Balance: <span id="balanceresult"></span><br />
        <span id="loading" style="display:none">Loading...</span>
    </div>
    </form>

page_load() method registered by Sys.Application.add_load and runs when page is load. page_unload() runs when page is unload.
At page_load there is $addHandler function to attach “change” event on product combobox. I write product combobox element tag without onchange attribute. So I need $addHandler.
$get() is working to set behaviour of specific HTML element.

User selects product category and after that the stock balance returned from Server. I call server side function (GetStockBalance) with PageMethods. PageMethods can call server function via client script.
It has success callback function (GetStockBalance_success) and it executes when server succesfuly returned any value. The response value will be written at span element “balanceresult”.

The code behind file:

Imports System.Web.Services
Imports System.Web.Script.Services
Partial Class _Default
    Inherits System.Web.UI.Page

    <WebMethod()> _
    <ScriptMethod()> _
    Public Shared Function GetStockBalance(ByVal product As String) As Integer
        System.Threading.Thread.Sleep(1000)
        Select Case product
            Case "Bike"
                Return 5
            Case "Bag"
                Return 10
            Case "Shoes"
                Return 2
            Case Else
                Return 0
        End Select
    End Function
End Class

This GetStockBalance function returns an integer and client script get this value.

Sys.WebForms

The Sys.WebForms namespace contains classes related to partial-page rendering in the Microsoft Ajax Library. More Description go to: http://msdn.microsoft.com/en-us/library/bb397566.
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginrequesthandler) method registers a beginrequesthandler. beginrequesthandler is Js function name and runs at Ajax request begins.
Usually I arrange UI behaviour at request begin like disabling controls so that user cannot send request twice accidentally.

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endrequesthandler) method registers an endrequesthandler that runs on Ajax request ends.

add_beginRequest / add_endRequest method requires <UpdatePanel> controls to run beginrequesthandler / endrequesthandler function. So here I mixed Server Control and Client Script.

Here’s a code pieces example:

<form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:UpdatePanel runat="server" ID="updpanel">
        <ContentTemplate>
            <asp:TextBox runat="server" ID="txtest"></asp:TextBox> &nbsp;
            <asp:Button ID="btntest" runat="server" Text="#" style="display:none" />
            <input type="button" id="btntest_client" value="Fibonacci Calc" onclick="btntest_client_onclick()" /> &nbsp;
                <asp:UpdateProgress ID="updprog" runat="server" AssociatedUpdatePanelID="updpanel">
                <ProgressTemplate>
                    Loading....
                </ProgressTemplate>
                </asp:UpdateProgress><br />

            <asp:Label ID="lblresult" runat="server" Text=" "></asp:Label>
        </ContentTemplate>
        
        </asp:UpdatePanel>
        

        <script type="text/javascript">
            Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
            Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
            
            function BeginRequestHandler() {
                $get('btntest_client').disabled = true;
                $get("lblresult").innerHTML = "";
            }

            function EndRequestHandler() {
                $get('btntest_client').disabled = false;
            }

            function btntest_client_onclick() {
                if ($get("txtest").value == "" || isNaN($get("txtest").value)) {
                    alert("Please fill in a number");
                    return false;
                } else {
                    alert("Fibonacci Calculation will begin. Click OK");
                    <%= Page.ClientScript.GetPostBackEventReference(btntest, String.Empty) %>;
                }
            }
        </script>
    </div>
    </form>

I write a Js script after ScriptManager Control line to avoid client run-time error. ScriptManager defines Sys Namespace.

I have client and server button. Server button is hidden by set its display style is none. If client (btntest_client) button is clicked then btntest server button will click/send a submit programmatically.
I use server script Page.ClientScript.GetPostBackEventReference(btntest, String.Empty) to do form submit by btntest programmatically.

I use two buttons here because I want to do simple input validation using Js in btntest_client click event. If user clicks btntest_client then it checks whether textbox is empty or not and fill by a number or not. If textbox is empty or not a number then warning will pop up, otherwise btntest server button sends a submit.

BeginRequestHandler() disables btntest_client and EndRequestHandler() enables it. When Ajax request begin the BeginRequestHandler() executes and when it ends the EndRequestHandler() runs.

Here I mixed server control (UpdatePanel, UpdateProgress) and client development. add_beginRequest() and add_endRequest() will enable only if we have UpdatePanel control. I place UpdateProgress inside UpdatePanel Tag for UI purpose.

Server code calculates using Fibonacci algorithm and sets Label “lblresult” control text with result. Code behind file:

Partial Class UpdatePanelAddHandler
    Inherits System.Web.UI.Page

    Protected Sub btntest_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btntest.Click
        System.Threading.Thread.Sleep(1500)
       
        lblresult.Text = "Fibonacci Calc Result: " & fib(txtest.Text)
    End Sub
    Protected Function fib(ByVal n As Integer) As Integer
        If n < 2 Then Return n Else Return fib(n - 1) + fib(n - 2)
    End Function
End Class

Screen shots:
User inputs a number and click Fibonacci Calc button. Alert box saying calculation will begin appear

After User clicks Ok on alert, he/she sees ‘Loading..’ message and also the button disabled.

Server process fibonacci calculation and when it finish, the server code tells the UI to shows calculation result. Ajax process ends and the button sets to enable again using Js script.

Sys.Net

The Sys.Net namespace contains classes that manage communication between AJAX-enabled ASP.NET client applications and Web services on the server. Please see full description here http://msdn.microsoft.com/en-us/library/bb310860. One of classes is Sys.Net.WebRequest().
I use Sys.Net.WebRequest() class to get web page content at an Url address. This class has set_url(Url), set_httpVerb("GET"/"POST") to decide Get/Post navigation method. add_completed(handler) to register webrequest complete handler function.
invoke() to start a webrequest.

<form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <script type="text/javascript">
            Sys.Application.add_load(page_load);
            function page_load() {
                loadUrl();
            }

            function loadUrl() {
                var request = new Sys.Net.WebRequest();
                request.set_url("getpage.htm");
                request.set_httpVerb("GET");
                request.add_completed(load_completed);
                request.invoke();
            }

            function load_completed(executor, eventargs) {
                if (executor.get_responseAvailable()) {
                    $get("page").innerHTML = executor.get_responseData();
                }
            }
        </script>
        <div id="page"></div>
    </div>
    </form>

Here I fill innerHTML of div element “page” with a content from Url “getpage.htm” using Sys.Net.WebRequest() Class.

load_completed(executor, eventargs) is a loadUrl completed callback. It has executor argument as an instance of WebRequest class.
This executor has get_responseAvailable() and get_responseData() to get content of a page.

page_load() method runs when web page load. It calls loadUrl() to get content of an Url. This page_load() method registered by Sys.Application.add_load(page_load).

getpage.htm:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
 <h2>Hello world.</h2> This page comes from WebRequest
</body>
</html>

Using ScriptReference to include a Js file

Let’s make another WebRequest example. I want to get a content of .aspx page with querystring parameter. The Js script will be placed on a seperate file and included in ScriptManager’s scriptreference tag.

<form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        <Scripts>
            <asp:ScriptReference Path="JsScript/Webrequest.js" />
        </Scripts>
        </asp:ScriptManager>
        <script type="text/javascript">
            Sys.Application.add_load(page_load);
            Sys.Application.add_unload(page_unload);

            function page_load() {
                $addHandler($get("product"), "change", product_change);
            }

            function page_unload() {
                $removeHandler($get("product"), "change", product_change);
            }

            function product_change() {
              
                loadpagepath("product_page.aspx?product=" + $get("product").value, "pageinfo", "updateprogress");
               
            }
        </script>
   
        <select id="product" >
            <option value="">-Select Product-</option>
            <option value="Bike">Bike</option>
            <option value="Bag">Bag</option>
            <option value="Shoes">Shoes</option>
        </select> &nbsp;<span id='updateprogress' style='display:none; position:absolute'>Loading ...</span>
        <hr />
        <div id="pageinfo"></div>
    </div>
    </form>

Javascript File (Webrequest.js):

var result_id;
var throbber_id;
function loadpagepath(url, result_element, throbber) {
    result_id = result_element;
    throbber_id = throbber;

    BeginRequestHandler();
    var request = new Sys.Net.WebRequest();
    
    request.set_url(url);
    request.set_httpVerb("GET");
    request.add_completed(loadpagepath_completed);
   
    request.invoke();
    
}

function loadpagepath_completed(executor, eventargs) {
    if (executor.get_responseAvailable()) {
        $get(result_id).innerHTML = executor.get_responseData();
        EndRequestHandler();
    }
}

function BeginRequestHandler() {
    $get(throbber_id).style.display = "block";
}

function EndRequestHandler() {
    $get(throbber_id).style.display = "none";
}
if (typeof (Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

Everytime product combobox changes its value, the related product page will load and showed inside div element “pageinfo”.
The supported Js script file is located inside scriptreference. It contains loadUrl(url, result_element, throbber) to create WebRequest instance. I also have BeginRequestHandler() and EndRequestHandler to control UI behaviour at ajax request begins and ends.

I use html span “updateprogress” instead of UpdateProgress server control so that I can show and hide it using Js

product_page.aspx:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="product_page.aspx.vb" Inherits="product_page" %>

<%  Dim product As String
	product = Request.QueryString("product")
	System.Threading.Thread.Sleep(1500)
	%>

<h2><% Response.Write(product)%> Product Page</h2>
Please write a description, attach image or whatever

Please note that I deleted a form tag, html and body tag because I already have those tags in parent page. Also keep in mind that you must not have <form runat=”server” > tag in child page if parent has similar form tag because you will have unexpected result.
This aspx script retrieves querystring parameter with Request.Querystring("querystring_ref") and print any string with Response.Write().

User choosing a product and then the content of product_page.aspx showed in div element “pageinfo”.

Cheers,
Agung Gugiaji

Advertisements

3 responses to “Introduction To Asp .Net Ajax Client Side Development ($get, $addhandler, $removehandler, Sys.Application, Sys.WebForms, Sys.Net)

  1. Pingback: Introduction To Asp .Net Ajax 3 (ScriptManagerProxy) | Enlighten Application Developer Journals

  2. Pingback: Introduction To Asp .Net Ajax 4 (Timer) | Enlighten Application Developer Journals

  3. Pingback: Traditional Ajax With Asp .Net And Modern PageMethods Approach | Enlighten Application Developer Journals

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s