Total votes: 45
Views: 203,842
Comments: 73
Category: AJAX
Print: Print Article
Please login to rate or to leave a comment.
By:
Learn how to create a custom Ajax Grid and Pager with the Microsoft ASP.NET AJAX platform.
Introduction
This article will show you how to create an AJAX Grid and a generic pager, which mimics the built-in GridView control on the client side.Features
The Control(s) Provides:- Able to bind to any web service call that returns an array.
- A GridView like API on the client side.
- Able to AutoGenerate Columns based upon the dataSource.
- Support for Sorting and Paging where developer can spawn his/her own logic.
- Full VS Design Time Support.
- Supports Column Drag and Drop.
- Compatible with all major browsers including IE, Firefox, Opera and Safari.
Prerequiste
This is not a beginner’s guide. If you are new to ASP.NET AJAX or not familiar with Client-Centric or Server-Centric Development model, I strongly recommend you visit http://ajax.asp.net/. To run the solution you must have:- Visual Studio 2005 or Visual Web Developer.
- Latest Version (v1.0) of ASP.NET AJAX.
- SQL Server 2005 (At least Express Edition) for running the sample.
- Northwind Database (You can download the sql script from here).
Background
ASP.NET AJAX is a great platform to develop rich user experience web applications. The most amazing part is that it replaces the traditional page postback refresh model. We can easily add anUpdatePanel
(A Part of Server Centric Development model) in the updatable part of a page to remove the regular page postback. But the problem with an UpdatePanel
is that it not only returns the updated data but also returns the HTML tags of that updated part. This is not an issue if you are developing small or mid size applications where performance and network bandwidth is not a concern. However if you are developing a large system where performance and network bandwidth matters, then definitely you want to send only the updated data without the unnecessary HTML tags.When developing a database application it is a common requirement to show data in a tabular format with sorting and paging. ASP.NET has two first class controls for this purpose, the
DataGrid
and the GridView
. But the problem with these controls there is no object model in the client side, which we can utilize with JavaScript
. There is no way we can call a Web Service or Server side method and bind the result with it in the client side. Developers often have to write reparative DHTML code to render the tabular data.The AJAX Grid
The providedAJAX Grid
solves the above problem. Developer can easily bind the result of a Web Service or Server Side method calls in the client side. It also exposes a similar API like DataGrid/GridView
in client side that most of the ASP.NET developers are already familiar with.Data Binding
When binding data we set theDataSource
of the target control and call the DataBind()
method. The same steps are required for the AJAX Grid
. The following lines show the Suppliers
table records from the Northwind database.Code Listing 1: JavaScript
01.
<script type=
"text/javascript"
>
02.
function
pageLoad()
03.
{
04.
var
grid = $find(
'grid'
);
// Get the reference of the Client Side Component
05.
DataService.GetAllSupplier
06.
(
07.
function
(suppliers)
08.
{
09.
grid.set_dataSource(suppliers);
10.
grid.dataBind();
11.
}
12.
);
13.
}
Code Listing 2: AJAX
1.
<
asp:ScriptManager
ID
=
"TheScriptManager"
runat
=
"server"
>
2.
<
Services
>
3.
<
asp:ServiceReference
Path
=
"~/DataService.asmx"
/>
4.
</
Services
>
5.
</
asp:ScriptManager
>
6.
<
ajax:Grid
ID
=
"grid1"
runat
=
"server"
></
ajax:Grid
>
Figure 1: Output
This is a simple page, which uses a
ScriptManager
with a WebService reference and an AJAX Grid
. In the pageLoad()
(A special event which is fired by the ASP.NET AJAX Library every time the page is loaded) event we are getting the reference of the AJAX Grid
by using the $find
method (A shortcut method to find the Client Side Component, please do not confuse Client Side Component with regular DOM
element, to get a DOM
element reference use $get
) statements and then we are setting the dataSource
that the web service call returns and finally calls the dataBind()
method. As you can see, the output is the same as we would set up a DataGrid/GridView
with the default setting.Styling
The above example shows the data in a plain vanilla style, certainly we do not want show the data in this way rather we would like to add some styling property. AJAX Grid similarly exposesCssClass
, HeaderCssClass
, RowCssClass
, AlternatingRowCssClass
and SelectedRowCssClass
to do the same styling as the DataGid/GridView
controls. Once we apply these styles the above example output looks like the following.Figure 2: Output with Styles
The Supplier.aspx of the attached sample has full source code of the above two examples.
The Column Collection
When showing the tabular data we certainly like to add more control such as hiding a column, showing a different header text, alignment, allow sorting, setting column width etc. InAJAX Grid
we can easily define the column collection in declarative model like the following:Code Listing 3: AJAX Grid with Columns
01.
<
ajax:Grid
ID
=
"grid"
runat
=
"server"
CssClass
=
"grid"
HeaderCssClass
=
"gridHeader"
02.
RowCssClass
=
"gridRow"
AlternatingRowCssClass
=
"gridAltRow"
SortColumn
=
"CompanyName"
03.
SortOrderAscendingImage
=
"Images/up.gif"
SortOrderDescendingImage
=
"Images/dn.gif"
>
04.
<
Columns
>
05.
<
ajax:GridColumn
DataField
=
"CompanyName"
HeaderText
=
"Company"
Sortable
=
"True"
06.
Nowrap
=
"True"
/>
07.
<
ajax:GridColumn
DataField
=
"ContactTitle"
HeaderText
=
"Title"
Sortable
=
"True"
/>
08.
<
ajax:GridColumn
DataField
=
"ContactName"
HeaderText
=
"Contact"
Sortable
=
"True"
/>
09.
<
ajax:GridColumn
DataField
=
"Address"
HeaderText
=
"Address"
Sortable
=
"True"
/>
10.
<
ajax:GridColumn
DataField
=
"City"
HeaderText
=
"City"
Sortable
=
"True"
/>
11.
<
ajax:GridColumn
DataField
=
"PostalCode"
HeaderText
=
"Postal Code"
Sortable
=
"True"
12.
Nowrap
=
"True"
/>
13.
<
ajax:GridColumn
DataField
=
"Country"
HeaderText
=
"Country"
Sortable
=
"True"
/>
14.
<
ajax:GridColumn
DataField
=
"Phone"
HeaderText
=
"Phone"
Sortable
=
"True"
/>
15.
</
Columns
>
16.
</
ajax:Grid
>
AJAX Gird Column
contains the following important properties:HeaderText
: Same as in theDataGrid/GridView
.DataField
: Same as in theDataGrid/GridView
.Sortable
: Iftrue,
the header text will be displayed as a hyperlink instead of text.SortField
: Must be specified ifSortField
is different fromDataField
.FormatString
: Same as in theDataGrid/GridView
.
Sorting
TheAJAX Grid
also supports sorting in the same way as the DataGrid/GridView
control. When a column
header is clicked it raises the Sort
event, which we have to subscribe. To show the current sort order we have to set the SortOrderAscendingImage
and SortOrderDescendingImage
property of AJAX Grid
. In order to get the current sort column and order we can check the SortColumn
and SortOrder
property. The following shows how to add sorting support in the AJAX Grid
which shows the Customers
table of Northwind database.Code Listing 4: AJAX Grid with Columns
01.
function
pageLoad()
02.
{
03.
// Getting the reference of the Client Components and
04.
// attaching the event handlers
05.
_grid = $find(
'grid'
);
06.
_grid.add_sort(sorted);
07.
}
08.
09.
function
sorted(sender, e)
10.
{
11.
// Set the SortColum and SortOrder of the Grid so
12.
// that it can properly render current sort column and
13.
// and the associated image
14.
15.
_grid.set_sortColumn(e.get_sortColumn());
16.
_grid.set_sortOrder(e.get_sortOrder());
17.
18.
// Here we can call the WebService with the new SortColumn and SortOrder
19.
}
Figure 3: AJAX Grid Sorted
The Customer.aspx of the attached sample has the full source code of the sorting example.
Selecting/Deleting Rows
To show theSelect
and Delete
link like in the DataGrid/GridView
we have set the ShowSelectLink
and ShowDeleteLink
property to true
. Once a row is selected it will raise the SelectedIndexChange
event. The same thing happens when the delete link is clicked; it raises the RowDelete
event. Both of these events pass the CommandName
and CommandArgument
but for this the DataKeyName
must to be set. For example if we set the DataKeyName
to the primary key of a table in these events it will have the primary key value as CommandArgument
. You can also select a row by using the SelectedIndex
property or the Select()
method. To deselect a row use the ResetSelection()
method.The RowDataBound Event
In theRowDataBound
event we can do some special processing before the data is bound. For example when showing the Products
table of Northwind database we can change the background color to red
that Unit in Stock is less than 10. Another example could be that our Web Service returns the Product
's CategoryID
but we want to show the category name instead of that CategoryID
. These kinds of changes can be done in this event. This event passes the binding row and the current data item that it is binding. The following shows how to bind this event and do the special processing.Code Listing 5: RowDataBound
01.
function
pageLoad()
02.
{
03.
// Getting the reference of the Client Components
04.
// and attaching the event handlers
05.
_grid = $find(
'grid'
);
06.
_grid.add_rowDataBound(rowDataBound);
07.
}
08.
09.
function
rowDataBound(sender, e)
10.
{
11.
var
product = e.get_dataItem();
12.
13.
var
tdCategory = e.get_tableRow().cells[2];
14.
var
categoryName = getCategoryName(product.CategoryID);
15.
tdCategory.innerHTML = categoryName;
16.
17.
var
tdUnitsInStock = e.get_tableRow().cells[5];
18.
if
(product.UnitsInStock < 10)
19.
{
20.
tdUnitsInStock.style.backgroundColor =
'#ff0000'
;
21.
}
22.
}
Figure 4: RowDataBound
The Product.aspx of the attached sample has the full source code of the
RowDataBound
event example.Paging
When working with large tables we often required to use paging. Although theDataGrid/GridView
has built-in support for paging they are pretty much useless. Most developers often refuse to use the built-in functionality and use their own custom logic which usually takes a start index, page size and other additional parameters and in turn returns only the paged records with the total number of records. The sample DataService.asmx
contains some of the methods (GetCustomerList
, GetProductList
) which contain the custom paging logic. Usually a Pager
shows the page numbers, next/previous, first/last page links. The following shows how to implement a pager control.Code Listing 6: AJAX Grid Pager JavaScript
01.
function
pageLoad()
02.
{
03.
// Getting the reference of the Client Components
04.
// and attaching the event handlers
05.
06.
_grid = $find(
'grid'
);
07.
_grid.add_sort(sorted);
08.
09.
_pager = $find(
'pager'
);
10.
_pager.add_pageChange(pageChanged);
11.
12.
//Getting the reference of the DOM elements
13.
_message = $get(
'message'
);
14.
15.
loadCustomers();
16.
}
17.
18.
function
sorted(sender, e)
19.
{
20.
// Set the SortColum and SortOrder of the Grid so that
21.
// it can properly render current sort column
22.
// and the associated image
23.
24.
_grid.set_sortColumn(e.get_sortColumn());
25.
_grid.set_sortOrder(e.get_sortOrder());
26.
27.
// need to reset the current page as sorting has been changed
28.
_pager.set_currentPage(1);
29.
30.
loadCustomers();
31.
}
32.
33.
function
pageChanged(sender, e)
34.
{
35.
// Set the new page as current page
36.
_pager.set_currentPage(e.get_newPage());
37.
loadCustomers();
38.
}
39.
40.
function
loadCustomers()
41.
{
42.
// Calculating the startindex
43.
var
startIndex = ((_pager.get_currentPage()-1) * _pager.get_rowPerPage());
44.
45.
// Need to convert the sortoder which our WS can understand
46.
// This needs to be on one line. Its been wrapped to display better in this article.
47.
var
sortOrder = (_grid.get_sortOrder() == Ajax.Controls.GridSortOrder.Descending)
48.
?
'DESC'
:
'ASC'
;
49.
50.
_message.innerHTML =
"<div>"
;
51.
_message.innerHTML +=
"<img alt='' src='Images/indicator.gif' />"
;
52.
_message.innerHTML +=
"Loading Customers...</div>"
;
53.
_message.style.display =
""
;
54.
55.
DataService.GetCustomerList
56.
(
57.
startIndex,
58.
_pager.get_rowPerPage(),
59.
_grid.get_sortColumn(),
60.
sortOrder,
61.
function
(pagedResult)
62.
{
63.
var
total = 0;
64.
var
customers =
null
;
65.
66.
if
(pagedResult !=
null
)
67.
{
68.
total = pagedResult.Total;
69.
customers = pagedResult.Rows;
70.
}
71.
72.
_grid.set_dataSource(customers);
73.
_grid.dataBind();
74.
75.
_pager.set_rowCount(total);
76.
77.
_message.innerHTML =
''
;
78.
_message.style.display =
'none'
;
79.
},
80.
function
(exception)
81.
{
82.
_message.innerHTML =
''
+ exception.get_message() +
''
;
83.
}
84.
);
85.
}
Code Listing 7: AJAX Grid Pager ASPX
01.
<
form
id
=
"form1"
runat
=
"server"
>
02.
<
asp:ScriptManager
ID
=
"TheScriptManager"
runat
=
"server"
>
03.
<
Services
>
04.
<
asp:ServiceReference
Path
=
"~/DataService.asmx"
/>
05.
</
Services
>
06.
</
asp:ScriptManager
>
07.
<
table
border
=
"0"
cellpadding
=
"1"
cellspacing
=
"0"
style
=
"width:100%"
>
08.
<
tbody
>
09.
<
tr
>
10.
<
td
style
=
"text-align:left"
>
11.
<
ajax:Grid
ID
=
"grid"
runat
=
"server"
12.
Border
=
"0"
CellPadding
=
"5"
CellSpacing
=
"0"
CssClass
=
"grid"
13.
HeaderCssClass
=
"gridHeader"
RowCssClass
=
"gridRow"
AlternatingRowCssClass
=
"gridAltRow"
14.
SelectedRowCssClass
=
"gridSelectedRow"
SortColumn
=
"CompanyName"
15.
SortOrderAscendingImage
=
"Images/up.gif"
SortOrderDescendingImage
=
"Images/dn.gif"
>
16.
<
Columns
>
17.
<
ajax:GridColumn
18.
DataField
=
"CompanyName"
19.
HeaderText
=
"Company"
20.
Sortable
=
"True"
Nowrap
=
"True"
/>
21.
<
ajax:GridColumn
22.
DataField
=
"ContactTitle"
23.
HeaderText
=
"Title"
Sortable
=
"True"
/>
24.
<
ajax:GridColumn
25.
DataField
=
"ContactName"
26.
HeaderText
=
"Contact"
27.
Sortable
=
"True"
/>
28.
<
ajax:GridColumn
29.
DataField
=
"Phone"
30.
HeaderText
=
"Phone"
31.
Sortable
=
"True"
/>
32.
</
Columns
>
33.
</
ajax:Grid
>
34.
</
td
>
35.
</
tr
>
36.
<
tr
>
37.
<
td
style
=
"text-align:right"
>
38.
<
ajax:Pager
ID
=
"pager"
runat
=
"server"
CssClass
=
"pager"
39.
CurrentPageCssClass
=
"pagerCurrentPage"
OtherPageCssClass
=
"pagerOtherPage"
40.
ShowInfo
=
"True"
InfoCssClass
=
"pagerInfo"
></
ajax:Pager
>
41.
</
td
>
42.
</
tr
>
43.
<
tr
>
44.
<
td
style
=
"text-align:left"
><
div
id
=
"message"
style
=
"display:none"
></
div
></
td
>
45.
</
tr
>
46.
</
tbody
>
47.
</
table
>
48.
</
form
>
Figure 5: AJAX Grid Pager
The followings are some of the important properties of the
AJAX Pager
:ShowInfo
: Whentrue
, shows the info such as Page 1 of 10. The default value isfalse
.ShowFirstAndLast
: Whentrue
, shows the first and last Link. The default value istrue
.FirstText
: The text which will be displayed as link for the first page. The Default value is <<LastText
: The text which will be displayed as link for the last page. The Default value is >>ShowPreviousAndNext
: Whentrue
, shows the Previous and Next Link. The default value isfalse
.ShowNumbers
: Whentrue
, shows the page numbers as link. The default value istrue
.RowPerPage
: The Number of row that each page contains. The default value is 10.CurrentPage
: The currentpage that the pager is showing.HideOnSinglePage
: The control will not be rendered if it founds there is only one page.ShowTip
: Whentrue
, a tooltip will appears on hovering on any of the links.InfoCssClass
: Styling property for the info part.CurrentPageCssClass
: Styling property for the current page.OtherPageCssClass
: Styling property for other pages.
AJAX Pager
contains only one event PageChange
that the developers have to subscribe to load the new page data. I have excluded the Pager
from the Grid
so that it can be utilize in with other controls that show tabular data.Both the Customer.aspx and Product.aspx of the attached sample has full source code of the Paging example.
Drag and Drop
Drag and Drop is an essential part of any Rich Web Application and thus it has become a common feature for Web 2.0 applications. Certianly Pageflakes is one of the best candidates for utlizing drag and drop. TheAjax Grid
has built-in support for column drag and drap. Just set the AllowDragAndDrop
property for any Column
to true
and it will be drag and dropable. The following screenshot shows the implemented version of a drag and drop in the Customers
table of the Northwind database:Figure 5: AJAX Grid Drag and Drop
The
Ajax Grid
raises the ColumnDragStarted
when the column drag started and ColumnDropped
upon dropping the column. The following code shows how to track the column and drag and drop in these events.Code Listing 8: AJAX Grid Drag and Drop
01.
function
pageLoad()
02.
{
03.
_grid = $find(
'grid'
);
04.
_grid.add_columnDragStart(columnDragStart);
05.
_grid.add_columnDropped(columnDropped);
06.
}
07.
08.
function
columnDragStart(sender, e)
09.
{
10.
alert(e.get_column().headerText);
// the event passes the column reference
11.
}
12.
13.
function
columnDropped(sender, e)
14.
{
15.
// this event also passes the column reference with old and new index
16.
alert(e.get_column().headerText);
17.
alert(e.get_oldIndex());
18.
alert(e.get_newIndex());
19.
}
ProfileService
to persist the columns position, so that in the next visit the columns positioning is same as the user left it in the last visit.
No comments:
Post a Comment