In this article, I would be demonstrating an example using Ajax with latest and hottest feature of .net: LINQ (Language INtegrated Query framework). I assume you are familiar with basics of Microsoft’s ASP.Net Ajax and LINQ.
First of all I would like to brief about requirements of the demo and then steps to implement the same.
A client wishes to see list of customers choosing a country.
For this requirement, I am gonna list countries in a dropdown and display customers in a DataGrid. Simple isn’t it?
There are many ways to implement this, but I have chosen my own way using Ajax style with LINQ.
In detail, I will be using UpdateProgress and client scripts for user interaction and LINQ for processing data in the codebehind.
Here are the few steps to go ahead.
Step1: Create a Ajax enabled website either using Visual Studio 2005 Codename Orcas or Visual Web Developer 2005 Codename Orcas.
This will create a web form Default.aspx. Lets make screen ready and then go into deep!.
With a blank web form, you would have already had Scriptmanager control (don’t worry about that now) on top of it. Drop a dropdownlist and GridView from tool box onto the screen as shown below:
So when user selects a country from Dropdown, list of Customers are displayed. Dropdown triggers the request and GridView displays the action.
For this purpose, I have created 2 classes for a Country and Customers inline with Default.aspx.cs which will be a data source for me.
public class CustomerList
{
private List _customers;
public CustomerList()
{
_customers = new List();
_countries = new List();
this._countries.Add(new Country("India", "IN"));
this._countries.Add(new Country("United States of America", "US"));
this._countries.Add(new Country("United Kingdom", "UK"));
this._countries.Add(new Country("France", "FR"));
this._countries.Add(new Country("Italy", "IT"));
}
public List Customers()
{
this._customers.Add(new Customer("Puru", this._countries[2]));
this._customers.Add(new Customer("Venu", this._countries[1]));
this._customers.Add(new Customer("Arindam", this._countries[0]));
this._customers.Add(new Customer("John", this._countries[3]));
this._customers.Add(new Customer("Philips", this._countries[4]));
return _customers;
}
private List _countries;
public List Countries()
{
return _countries;
}
}
public class Customer
{
private string name;
public string Name
{
get { return name; }
}
private Country country;
public Country Country
{
get { return country; }
}
public Customer(string name, Country country)
{
this.name = name;
this.country = country;
}
}
public class Country
{
private string name;
public string Name
{
get { return name; }
}
private string code;
public string Code
{
get { return code; }
}
public Country(string name, string code)
{
this.name = name;
this.code = code;
}
}
Next, Create an handler to handle postback for Dropdownlist in the codebehind. Which will be like this..
…
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.DropDownList1.SelectedIndex != -1)
{
}
}
.. .
This is interesting handler to discuss.
In the page load add the below shown code in order to display country list in dropdown.
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
//..
}
}
This is a point of foucs now. Here in this Page load I am gonna query data from CustomerList using LINQ to assin the result to dropdownlist.
. . .
if (!this.IsPostBack)
{
var countryList = from countries in customerList.Countries()
select countries;
this.DropDownList1.DataSource = countryList;
this.DropDownList1.DataTextField = "Name";
this.DropDownList1.DataValueField = "Code";
this.DropDownList1.DataBind();
}
. . .
Intially I do not want to display the GridView, so make its visible false in PageLoad.
. . .
this.GridView1.Visible = false;
. . .
Then move on to Dropwdown’s handler: SelectIndexChanged..
Here I would need to take selected value from country dropdown and query customsers from the list.
I assume that there will be delay in getting customers from data. Hence there will be a sleep of 5 seconds for this thread.
.. .
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.DropDownList1.SelectedIndex != -1)
{
System.Threading.Thread.Sleep(5000);
var customers = from cust in this.customerList.Customers()
select cust;
var customer = from c in customers
where c.Country.Code == this.DropDownList1.SelectedValue.ToString()
select c;
this.GridView1.Visible = true;
this.GridView1.DataSource = customer;
this.GridView1.DataBind();
}
}
. . .
That’s it from the code behind point of view..
And a lot more needs to be done on aspx page. At this moment if you run the project, when you select a country, there will be a postback for each selection.
We need to implement Ajax for this page.
Step 2: Implementation of Ajax
This page needs partial render/refresh for every post back. So Ajax supplies a control called UpdatePanel and will add on to the page.
UpdatePanel allows us to update a page partially without post backing whole page or re rendering the whole page, which is not desirable if page is has tonnes of data. Hence I have dropped GridView into the UpdatePanel which needs partial refresh.
I am gonna take GridView and drop into the UpdatePanel. No if you run the application, you will not see any post backs at all.
Setp 3: Implement User’s interaction for Cancel/Abort
For this purpose I would need to create client side javascript. So in the head element of html script add below shown lines of code.
. . .
<html xmlns=http://www.w3.org/1999/xhtml>
<head runat="server">
<script type="text/javascript">
…
</script>
/
For this purpose I will add UpdateProgress control from Ajax Extensions tab. This control is responsible for displaying Progress activities when you select a country and allows us to interact with those post backing activities.
Ajax exposes Ajax Libraries thro Sys namespace. There are tonnes of classes available in this namespace; among them I will be using PageRequestManager from Sys.WebForms namespace.
I had to find workaround to fix “Sys undefined” javascript error on my by browser, Hence I am initalising intial javascript code on load of the html’s body.
So, I have created following code snippet in script block.
<script type="text/javascript">
var prm;
function pageLoad()
{
if(prm == null)
{
prm = Sys.WebForms.PageRequestManager.getInstance();
}
}
</script>
And called this method in OnLoad of body’s event
. .
<body onload="pageLoad()">
<form id="form1" runat="server">
. .
Here I am creating an instance of PageRequestManager. It has several methods, but will be using which are applicable to my requirements.
.add_initializeRequest(..)
.add_endRequest(..)
.abortPostBack() are the methods which am interested in here.
As name suggests they are delegates and consumes methods to initialise, end request.
So I will be creating 2 more metohds to handle initialise and end request and abort/cancel postback/request.
...
var postBackElement;
function InitializeRequest(sender, args) {
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
}
postBackElement = args.get_postBackElement();
if (postBackElement.id == 'DropDownList1') {
$get('UpdateProgress1').style.display = 'block';
}
}
function EndRequest(sender, args) {
if (postBackElement.id == 'DropDownList1') {
$get('UpdateProgress1').style.display = 'none';
}
. . .
In these methods, I have created postback element which triggers action and setting updatepanel’s propeties using dhtml.
Finally, the overall script looks like this.
<script type="text/javascript">
var prm;
var postBackElement;
function InitializeRequest(sender, args) {
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
}
postBackElement = args.get_postBackElement();
if (postBackElement.id == 'DropDownList1') {
$get('UpdateProgress1').style.display = 'block';
}
}
function EndRequest(sender, args) {
if (postBackElement.id == 'DropDownList1') {
$get('UpdateProgress1').style.display = 'none';
}
}
function AbortRequest()
{
if(prm != null)
{
prm.abortPostBack();
}
}
function pageLoad()
{
if(prm == null)
{
prm = Sys.WebForms.PageRequestManager.getInstance();
}
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
}
</script>
Along with this script, I also would like to add CSS capablities to this page in order to provide elegant look.
<style type="text/css">
#UpdatePanel1 {
width:200px; height:250px;
border: 1px solid gray;
}
#UpdateProgress1 {
width:200px; background-color: #FFC0FF;
bottom: 0%; left: 0px; position: relative;
}
#GridView1
{
width:200px; height:100px;
}
</style>
The next step is, how to trigger action on the page.
We now have, dropdownlist for Country, Gridview for Customer and UpdatePanel for partial rendering upon postback.
I need to add UpdateProgress, a control from Ajax extension which provides status message of activites and abort feature as well.
Please refer UpdateProgress control library for more details from Ajax website.
UpdateProgress provides a property called ProgressTemplate, where in you can add your own html code. Here I am adding a message and an html button and calling javscript’s AbortMethod() upon Abort button click which will cancel a postback which is under progress!
<asp:UpdateProgress ID="UpdateProgress1" runat="server"
AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
Getting customers..
<input id="btnCancel" type="button" value="Cancel" onclick="AbortRequest()" />
</ProgressTemplate>
</asp:UpdateProgress>
One more thing I would like to mention is, you would need to associate Upadate panel which you are partially refreshing. Here in our case UpdatePanel1 is the candidate.
I think we are done with this page I guess. So lets run and try how it works…
Hope you enjoyed the ride and please leave your comments..
Take care,
Here is the overall code.
<Defaault.aspx.cs>
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Linq;
using System.Collections.Generic;
public partial class _Default : System.Web.UI.Page
{
CustomerList customerList = new CustomerList();
protected void Page_Load(object sender, EventArgs e)
{
this.GridView1.Visible = false;
if (!this.IsPostBack)
{
var countryList = from countries in customerList.Countries()
select countries;
this.DropDownList1.DataSource = countryList;
this.DropDownList1.DataTextField = "Name";
this.DropDownList1.DataValueField = "Code";
this.DropDownList1.DataBind();
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.DropDownList1.SelectedIndex != -1)
{
System.Threading.Thread.Sleep(5000);
var customers = from cust in this.customerList.Customers()
select cust;
var customer = from c in customers
where c.Country.Code == this.DropDownList1.SelectedValue.ToString()
select c;
this.GridView1.Visible = true;
this.GridView1.DataSource = customer;
this.GridView1.DataBind();
}
}
}
public class CustomerList
{
private List _customers;
public CustomerList()
{
_customers = new List();
_countries = new List();
this._countries.Add(new Country("India", "IN"));
this._countries.Add(new Country("United States of America", "US"));
this._countries.Add(new Country("United Kingdom", "UK"));
this._countries.Add(new Country("France", "FR"));
this._countries.Add(new Country("Italy", "IT"));
}
public List Customers()
{
this._customers.Add(new Customer("Puru", this._countries[2]));
this._customers.Add(new Customer("Venu", this._countries[1]));
this._customers.Add(new Customer("Arindam", this._countries[0]));
this._customers.Add(new Customer("John", this._countries[3]));
this._customers.Add(new Customer("Philips", this._countries[4]));
return _customers;
}
private List _countries;
public List Countries()
{
return _countries;
}
}
public class Customer
{
private string name;
public string Name
{
get { return name; }
}
private Country country;
public Country Country
{
get { return country; }
}
public Customer(string name, Country country)
{
this.name = name;
this.country = country;
}
}
public class Country
{
private string name;
public string Name
{
get { return name; }
}
private string code;
public string Code
{
get { return code; }
}
public Country(string name, string code)
{
this.name = name;
this.code = code;
}
}
<Default.aspx>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_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>Untitled Page</title>
<style type="text/css">
#UpdatePanel1 {
width:200px; height:250px;
border: 1px solid gray;
}
#UpdateProgress1 {
width:200px; background-color: #FFC0FF;
bottom: 0%; left: 0px; position: relative;
}
#GridView1
{
width:200px; height:100px;
}
</style>
<script type="text/javascript">
var prm;
var postBackElement;
function InitializeRequest(sender, args) {
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
}
postBackElement = args.get_postBackElement();
if (postBackElement.id == 'DropDownList1') {
$get('UpdateProgress1').style.display = 'block';
}
}
function EndRequest(sender, args) {
if (postBackElement.id == 'DropDownList1') {
$get('UpdateProgress1').style.display = 'none';
}
}
function AbortRequest()
{
if(prm != null)
{
prm.abortPostBack();
}
}
function pageLoad()
{
if(prm == null)
{
prm = Sys.WebForms.PageRequestManager.getInstance();
}
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
}
</script>
</head>
<body onload="pageLoad()">
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
</div>
<div>
<asp:DropDownList ID="DropDownList1" runat="server" Width="200px"
AutoPostBack="True"
onselectedindexchanged="DropDownList1_SelectedIndexChanged1">
</asp:DropDownList>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</div>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID ="DropDownList1" />
</Triggers>
</asp:UpdatePanel>
</div>
<div>
</div>
<div>
<asp:UpdateProgress ID="UpdateProgress1" runat="server"
AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
Getting customers..
<input id="btnCancel" type="button" value="Cancel" onclick="AbortRequest()" />
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
</body>
</html>