Tuesday, November 24, 2009

Filling cascading dropdown example using jQuery and AJAX.Net library

Previous post related to filling cascading dropdown asynchronously offers more simple and traditional approach for beginner programmers who're more familiar with readymade asp.net update panel control. That post demonstrated dynamic approach which utilizes update panel to enable partial postbacks from a web page. You can read previous post from here.

As mentioned in previous post, we'll look into more advanced ways of solving same problem space. This time, I used combination of JQuery/AJAX.Net library to achieve responsive and far more superior user experience. I almost fell in love with jQuery. If you don't know jQuery library, I recommend you to read about it.

jQuery is a free open source lightweight javascript library which is compatible with Microsoft ASP.NET Ajax and Visual studio. jQuery provides powerful functions like DOM element manipulation, function Chaining and extensibility. jQuery usually exists as a single JavaScript file. It can be included within a web page using the following markup.

This demo demonstrates technique of calling server side method using jQuery script and Ajax.Net library. This offers more clean and faster way to update DOM elements with results from the server. This is more light weight and no page life cycle being kicked off. This is true power of jQuery.

Pre-Requisites:

Please register the Ajax HTTP handler in the web.config file in <httpHandlers> section to allow ajax call interception

<!--following ajax handler is needed for asynchronous communication with server side code-->
<add path="ajax/*.ashx" verb="POST,GET" type="Ajax.PageHandlerFactory, Ajax"/>

Please add reference to approriate version of Ajax.Net assembly.

Please add reference to approriate version of jQuery script to your web page. I’ve utilized 1.3.2 version of jQuery “jQuery-1.3.2.min.js” for this demo.

<script type="text/javascript" src="JQuery/jquery-1.3.2.min.js"></script>
<script src="JQuery/JQueryScripts.js" type="text/javascript"></script>
.ASPX page(Default.aspx)

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="JQueryAsynchronousCallBackDemo._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<!--following references include jQuery file and a script file which includes custom functions -->
<script type="text/javascript" src="JQuery/jquery-1.3.2.min.js"></script>
<script src="JQuery/JQueryScripts.js" type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Literal ID="Literal1" runat="server">States:&nbsp;</asp:Literal>
<asp:DropDownList ID="ddStatesList" runat="server">
<asp:ListItem Selected ="True" Text = "please select state" Value = "0"></asp:ListItem>
<asp:ListItem Text="USA" Value ="1"></asp:ListItem>
<asp:ListItem Text ="Europe" Value = "2"></asp:ListItem>
<asp:ListItem Text ="Asia" Value = "3"></asp:ListItem>
</asp:DropDownList>
<br />
<hr />
<asp:Literal ID="Literal2" runat="server">Cities:&nbsp;</asp:Literal>
<asp:DropDownList ID="ddCitiesList" runat="server">
</asp:DropDownList>
</div>
</form>
</body>
</html>

Default.aspx.cs:

1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Web;
5: using System.Web.UI;
6: using System.Web.UI.WebControls;
8: 
9: namespace JQueryAsynchronousCallBackDemo
10: {
11:     //THIS SAMPLE DEMONSTRATES USAGE OF AJAX.NET LIBRARY FOR DESIRED CLIENT SIDE PROGRAMMING.
12:     public partial class _Default : System.Web.UI.Page
13:     {
14:         protected void Page_Load(object sender, EventArgs e)
15:         {
16:             Ajax.Utility.RegisterTypeForAjax(typeof(AjaxUtilities)); 
17:             this.ddStatesList.Attributes.Add("OnChange", string.Format("AdjustCitiesDropDown(this, '{0}')", this.ddCitiesList.ClientID));
18:         }
19:     }
20: }
21: 
jQuery script file: : //******************************************************************************************//3: //This is jquery based script. JQuery offers more concise and light weight javascript code. //This script is called on "Onchange" event and asynchronously calls server side method to retrieve cities 5: //corresponding to given state.  6: function AdjustCitiesDropDown(ddlState, ddlCity) { 7: if (ddlState && ddlCity) { 8: var stateId = $(ddlState).val(); 9: var res = AjaxUtilities.GetCities(stateId); 12: if (res.value != null && res.value.length > 0) { 13: var options_cityTypes = ''; 14: $.each(res.value, function(i, d) { 15: options_cityTypes += '<option value="' + d+ '">' + d + '<\/option>'; 16: }); 17: $('#' + ddlCity).html(options_cityTypes); 18: } 19: } 20: } AjaxUtilities Class file

1: using System.Collections.Generic;
2: 
3: namespace JQueryAsynchronousCallBackDemo
4: {
5:     public class AjaxUtilities
6:     {
7:         public AjaxUtilities()
8:         {
9:         }
10:         //The method which is invoked from client side javascript/jquery must be marked with following
11:         //attribute
12:         [Ajax.AjaxMethod()]
13:         public List<string> GetCities(string stateId)
14:         {
15:             if (stateId == "1")
16:             {
17:                 return new List<string>() { "Chicago", "NewYork", "LA" };
18:             }
19:             else if (stateId == "2")
20:             {
21:                 return new List<string>() { "London", "Paris", "Madrid" };
22:             }
23:             else if (stateId == "3")
24:             {
25:                 return new List<string>() { "Mumbai", "Shanghai", "Tokyo" };
26:             }
27:             else
28:             {
29:                 return new List<string>() { "GothamCity" };
30:             }
31:         }
32:     }
33: }

Monday, November 23, 2009

Programmatic way of adding update panel control to asp.net web page

Due to issue with some legacy third party controls on a regular asp.net web page, I was not able to declaratively add UPDATE PANEL controls to the page. My aim was to generate asynchronous behavior or partial postback for the new controls which i was supposed to add to legacy page. Finally, I came up with this following basic idea which involves using placeholder container controls and dynamically adding controls to the place holder controls. There are few other options like using JQuery techniques. Ofcourse, I finally ended up using JQuery technique to achieve the same effect.

But, I thought some people might feel comfortable using the traditional asp.net code-behind model and more aligned towards microsoft ajax controls and techniques.

Following sample code is almost self-explanatory. You can copy it and run it as is. Please feel free to post your questions in comments









html code:
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">
    <title>title> head>
<body>
   <form id="form1" runat="server">
    <div>
    <asp:Literal ID="literal1" runat="server">Countryasp:Literal>
    <asp:PlaceHolder  ID= "placeHolder1" Visible="true" runat="server">
asp:PlaceHolder>      <asp:Literal ID="literal2" runat="server">Citiesasp:Literal>
     <asp:PlaceHolder  ID= "placeHolder2" Visible="true" runat="server">asp: PlaceHolder>
    div>
    form>
<body>
<html>
Code behind code:
using System; using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1 {
    public partial class _Default : System.Web.UI.Page
    {
       private static System.Collections.Generic.List<Int32
        protected void Page_Load(object sender, EventArgs e)
        {
           ScriptManager manager = new ScriptManager();
           CheckBoxList checkboxList = new CheckBoxList();
           checkboxList.ID = "Cities";
           checkboxList.AutoPostBack = true;
           DropDownList dropdwnlist = new DropDownList();
       dropdwnlist.ID = "ddCountry";
           dropdwnlist.SelectedIndexChanged += 
new EventHandler(dropdwnlist_SelectedIndexChanged);            dropdwnlist.AutoPostBack = true;
           dropdwnlist.Items.Add(new ListItem("please select","0"));
           dropdwnlist.Items.Add(new ListItem("India","1"));
dropdwnlist.Items.Add(new ListItem("USA","2"));
           placeHolder1.Controls.Add(dropdwnlist);
           placeHolder2.Controls.Add(checkboxList);
         
UpdatePanel panel = new UpdatePanel();
           panel.ContentTemplateContainer.Controls.Add(placeHolder1);
           panel.ContentTemplateContainer.Controls.Add(placeHolder2);
           Page.Form.Controls.Add(manager);
           Page.Form.Controls.Add(panel);
   
          }
      protected void dropdwnlist_SelectedIndexChanged(object sender,EventArgs e)         {
           var checkboxlist = placeHolder2.FindControl("Cities") as CheckBoxList;
           var dropdwonlist = placeHolder1.FindControl("ddCountry") as DropDownList;
           if (dropdwonlist.SelectedValue == "1")
           {
               checkboxlist.Items.Add(new ListItem("Hyderabad","1"));
               checkboxlist.Items.Add(new ListItem("Mumbai","2"));
               checkboxlist.Items.Add(new ListItem("NewDelhi","3"));
               checkboxlist.Items.Add(new ListItem("Chennai","4"));
           }
           else if (dropdwonlist.SelectedValue == "2")
           {
               checkboxlist.Items.Add(new ListItem("NewYork","1"));
               checkboxlist.Items.Add(new ListItem("Chicago","2"));
               checkboxlist.Items.Add(new ListItem("LosAngeles","3"));
           }
        }
  }
}