Monday, December 3, 2007 12:53 PM Kazi Manzur Rashid

AjaxDataControls GridView Part One

The GridView seems to be the most popular among the other controls of AjaxDataControls. In this post, I will give you a quick walk through on some of the basic features of GridView.

DataBinding

As mention in the past the purpose of these controls is to enrich the Client Centric Development Model of Asp.net Ajax and thus it depends upon the Web Service or Page Method calls of Asp.net Ajax. The following shows the code which is used to show the Supplier Table of Northwind database.

<AjaxData:GridView ID="GridView1" runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <HeaderStyle CssClass="HeaderStyle" />
</AjaxData:GridView>

<script type="text/javascript">

    function pageLoad(sender, e)
    {
        DataService.GetAllSupplier(onLoadSuccess);
    }

    function onLoadSuccess(result)
    {
        var gridView = $find('<%= GridView1.ClientID %>');

        gridView.set_dataSource(result);
        gridView.dataBind();
    }

</script>

And the result is following:

What we are doing is very simple, we are calling a Web Service method to get the supplier list. The web method opens a sql connection and returns a supplier entity collection which we are binding with the GridView in the successCallback handler of the web service call. You can also bind to DataSet/DataTable but in that case you have bind the rows collection instead of the DataTable/DataSet itself in the successCallback. The following shows code which can be used to bind a DataTable with this control:

function onLoadSuccess(result)
{
    var gridView = $find('<%= GridView1.ClientID %>');

    gridView.set_dataSource(result.rows);
    gridView.dataBind();
}

For styling we are also using the HeaderStyle, RowStyle, AlternatingRowStyle like the original GridView. Note that we did not mention any column in the GridView declaration but it is capable to discover the column list from its data source, this same as original GridView AutoGenerateColumns property to true.

Predefined Columns

Certainly we do not want to show all the columns that are in DataSource and we might want to change the header text and order of the columns. In that case, we have declare the columns in the GridView like the following:

<AjaxData:GridView ID="GridView1" runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle"/>
   <HeaderStyle CssClass="HeaderStyle"/>
   <Columns>
    <AjaxData:GridViewBoundColumn HeaderText="Company" DataField="Company" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left"/>
    <AjaxData:GridViewBoundColumn HeaderText="Contact" DataField="ContactName" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left"/>
    <AjaxData:GridViewBoundColumn HeaderText="Title" DataField="ContactTitle" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left"/>
   </Columns>
</AjaxData:GridView>

The same rule applies like the original GridView control that is you have to set the DataField name of the columns.

Different Type of Columns

Currently the GridView has all the built-in columns that are available in original GridView and it has a very extensible API to roll your new column which I will show iin future post. The following shows few of those columns to show the above supplier table:

<AjaxData:GridView ID="GridView1" runat="server" CssClass="DataWebControlStyle" DataKeyName="ID" SelectedIndexChangedEvent="onSelectedIndexChanged" RowCommandEvent="onRowCommand">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle"/>
   <HeaderStyle CssClass="HeaderStyle"/>
   <SelectedRowStyle CssClass="SelectedRowStyle" />
   <Columns>
    <AjaxData:GridViewCommandColumn ShowSelectButton="true"/>
    <AjaxData:GridViewRadioButtonColumn GroupName="Active"/>
    <AjaxData:GridViewCheckBoxColumn DataField="Active"/>
    <AjaxData:GridViewButtonColumn CommandName="ShowInfo" HeaderText="Company" DataTextField="Company" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left"/>
    <AjaxData:GridViewBoundColumn HeaderText="Contact" DataField="ContactName" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left" />
    <AjaxData:GridViewBoundColumn HeaderText="Title" DataField="ContactTitle" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left" />
    <AjaxData:GridViewHyperLinkColumn HeaderText="City" DataTextField="City" DataNavigateUrlFields="City" Target="_blank" DataNavigateUrlFormatString="Related.aspx?City={0}" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left" />
   </Columns>
</AjaxData:GridView>
function pageLoad(sender, e)
{
    DataService.GetAllSupplier(onLoadSuccess);
}

function onLoadSuccess(result)
{
    var gridView = $find('<%= GridView1.ClientID %>');

    gridView.set_dataSource(result);
    gridView.dataBind();
}

function onSelectedIndexChanged(sender, e)
{
    writeMessage(String.format('Selected value {0}<br/>', sender.get_selectedValue()));
}

function onRowCommand(sender, e)
{
    if (e.get_commandName() == 'ShowInfo')
    {
        writeMessage(String.format('Command Arument {0}<br/>', e.get_commandArgument()));
    }
}

function writeMessage(message)
{
    $get('divEvents').innerHTML += message;
}

As you can see you can also use the selectedIndexChange and rowCommandEvent as the original GridView.

Data Sorting

The GridView also has the support to indicate by which column the Grid is Currently Sorted. The GridView does not sort the data in the Client Side like any other JS Widgets, instead it depends upon the server side to sort this data. The following shows the client side code:

<AjaxData:GridView ID="GridView1" runat="server" CssClass="DataWebControlStyle" DataKeyName="ID" SortColumn="Name" SortOrderAscendingImageUrl="~/Images/up.gif" SortOrderDescendingImageUrl="~/Images/dn.gif" SortCommandEvent="onSortCommand">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle"/>
   <HeaderStyle CssClass="HeaderStyle"/>
   <Columns>
        <AjaxData:GridViewBoundColumn HeaderText="Product" DataField="Name" SortField="Name" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left" HeaderStyle-Wrap="false"/>
        <AjaxData:GridViewBoundColumn HeaderText="Category" DataField="CategoryName" SortField="CategoryName" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left" HeaderStyle-Wrap="false"/>
        <AjaxData:GridViewBoundColumn HeaderText="Supplier" DataField="SupplierName" SortField="SupplierName" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left" HeaderStyle-Wrap="false"/>
        <AjaxData:GridViewBoundColumn HeaderText="Quantity/Unit" DataField="QuantityPerUnit" SortField="QuantityPerUnit" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="left"/>
        <AjaxData:GridViewBoundColumn HeaderText="Unit Price" DataField="UnitPrice" SortField="UnitPrice" DataFormatString="c" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Right" HeaderStyle-Wrap="false"/>
        <AjaxData:GridViewBoundColumn HeaderText="Units In Stock" DataField="UnitsInStock" SortField="UnitsInStock" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Right" HeaderStyle-Wrap="false"/>
        <AjaxData:GridViewBoundColumn HeaderText="Units On Order" DataField="UnitsOnOrder" SortField="UnitsOnOrder" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Right" HeaderStyle-Wrap="false"/>
        <AjaxData:GridViewCheckBoxColumn HeaderText="Discontinued" DataField="Discontinued" SortField="Discontinued" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Center" HeaderStyle-Wrap="false"/>
   </Columns>
</AjaxData:GridView>
var _gridView;

function pageLoad(sender, e)
{
    _gridView = $find('<%= GridView1.ClientID %>');
    loadProducts();
}

function loadProducts()
{
    //Need to convert the sortoder so our WS understand
    var sortColumn = _gridView.get_sortColumn();
    var sortOrder = (_gridView.get_sortOrder() == AjaxDataControls.GridViewSortOrder.Descending) ? 'DESC' : 'ASC';

    DataService.GetProductList(0, 1000, sortColumn, sortOrder, onLoadSuccess);
}

function onLoadSuccess(result)
{
    _gridView.set_dataSource(result.Rows);
    _gridView.dataBind();
}

function onSortCommand(sender, e)
{
    _gridView.set_sortColumn(e.get_sortColumn())
    _gridView.set_sortOrder(e.get_sortOrder());
    loadProducts();
}

As you can see now each column has an associated property SortField, you can mention the name of the field in this property which you want the Grid to be sorted and it can differ from the DataField property. If the SortField is set then column header becomes Hyperlinked otherwise it appears in simple text. We are also mentioning the initial sort field and Up/Down images in the GridView. Then in the code we are getting the currently sorted column name and its order and calling the web service with these sort criteria and in the SortCommand event we are simply setting the grid SortColumn and the SortOrder. The Web Service method is slightly different in this case, now it accepts startIndex where we are passing 0, maxRow where we are passing 1000 just to ensure that all the Product of the Northwind table is returned, the name of the sort column and the order.  The result is following:

That is it for the day. In the next post we will see the Drag and Drop of the Columns as well as Data Paging. You can check the live examples of the above in the following links:

You can also download the source of this project and the samples from the Source Code tab of CodePlex.

kick it on DotNetKicks.com

Filed under: ,

Comments

# re: AjaxDataControls GridView Part One

Monday, December 3, 2007 2:05 AM by mehfuzh

Nice post amitjax!

# re: AjaxDataControls GridView Part One

Monday, December 3, 2007 4:47 AM by Developer

It's useful information for me.

Thank you.

# re: AjaxDataControls GridView Part One

Monday, December 3, 2007 7:08 AM by Gabriel

Nice...

# re: AjaxDataControls GridView Part One

Monday, December 3, 2007 7:31 PM by MuteThis

The article is good, but it seems like you're binding data twice on postbacks when sorting.  To avoid this, I usually defer binding to prerender, is there an advantage to using load?

# re: AjaxDataControls GridView Part One

Tuesday, December 4, 2007 1:39 AM by Kazi Manzur Rashid

@MuteThis: All the above code is JavaScript and the Grid does not require any postback.

# re: AjaxDataControls GridView Part One

Wednesday, December 12, 2007 4:57 AM by Mehfuz Hossain

Looking closely, does the GridViewRadioButtonColumn , GridViewCheckBoxColumn  has CommandName property

Also, What bout LinkButtonCommand

<AjaxData:GridViewCommandColumn ShowSelectButton="true"/>

   <AjaxData:GridViewRadioButtonColumn GroupName="Active"/>

   <AjaxData:GridViewCheckBoxColumn DataField="Active"/>

   <AjaxData:GridViewButtonColumn CommandName="ShowInfo" HeaderText="Company" DataTextField="Company" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Lef

and it will be nicer, if  we dont need to do this

var gridView = $find('<%= GridView1.ClientID %>');

rather, the html block registers a GridView class instance , by which we can do the following.

   GridView1.dataSource = result;

   GridView1.dataBind();

Light me up!

# re: AjaxDataControls GridView Part One

Wednesday, December 12, 2007 2:33 PM by Kazi Manzur Rashid

For the initial version our plan was to provide the same set of features that the original GridView provides. No the GridViewRadioButton and GridViewCheckBoxColumn does not have any commandName property as the Asp.net team and so do we did not anticapted that it will be required. The GridViewCommandColumn as the name suggests has the CommandName property and it automatically populates the CommandArgument with the row index, same as original Gridview. If you have any special need you can use the GridViewTemplateColumn that will give the full customization support.

Thanks for the tip, we will defintly introduce firendyName/ClientSide variable name in next version.

# re: AjaxDataControls GridView Part One

Friday, March 21, 2008 9:43 AM by Anand Maarten Shyamnarain

How do I transform this implementation into a usercontrol, to use multiple instances of this control on a single page.

This code works only fine for 1 singe implementation of this gridview on a page.

The javascript is created for each control the problem, so the method names and variables are occure more than 1 times.

Do you have any suggestion how use this implementation as a usercontrol?

thnks for the effort...

greetings,

Anand

# re: AjaxDataControls GridView Part One

Friday, May 9, 2008 3:58 PM by Les Pinter

Where can I download your code?

Thanks

# re: AjaxDataControls GridView Part One

Friday, September 12, 2008 8:25 AM by satish1.v

hi ,

  tatz a great control and i have seen in the right.. but in my project they need all the rows as the editable rows and there are two dropdowns in it...so i have introduced the template columns everywhere and tried to do the things is tat .

# re: AjaxDataControls GridView Part One

Friday, September 12, 2008 8:26 AM by satish1.v

for got to ask u one..where can i handle the row-databound event here

# re: AjaxDataControls GridView Part One

Sunday, December 28, 2008 3:52 PM by Roberto Alessi

I have tried but i don't figure how to implement a button for adding a new row: some hint ?