New to Telerik UI for ASP.NET AJAXStart a free 30-day trial

Client-side Binding

RadGrid for ASP.NET AJAX supports client-side binding to web services or page methods as demonstrated in this and this online demo of the product. In order to assign data source for the grid and refresh its state on the client, utilize the set_dataSource(dataSource) and dataBind() methods from its client-side API. Keep in mind that the data source passed as an argument to the set_dataSource method should have JSON signature which can be serialized by a web service or a page method.

All grid commands will raise the OnCommand client grid event which can be intercepted in order to cancel the default operation and perform a custom action client-side.

The RadGrid client-side binding is especially useful when you would like to perform asynchronous refresh of the grid data using web service invocations (combined with ASP.NET AJAX), thus by-passing the standard event lifecycle of the page and avoiding execution of code logic which is not "connected" to the grid data population.

Below are some important points that you need to have in mind when utilizing the RadGrid client-side data-binding:

Generally speaking, RadGrid transfers JSON from client-to-server-to-client in order to bind/page/sort/filter on the client. If you are using declarative data-binding and do not bind RadGrid on the server, it will manage to create its client object properly. However, if you are manually binding it on client and do not bind it on server, you need to attach a handler to its OnCommand client event. In both cases RadGrid will bind itself on the server (if you do not bind it explicitly) with dummy data to create PageSize items. Later, when you bind it on the client side, previously created items will be populated with data. If you bind the control on client with rows more than PageSize, RadGrid will create new tr elements and populate properly the cells for certain columns. If you want to initially hide the empty rows shown on the client, you can set the RadGrid.ClientSettings.DataBinding.ShowEmptyRowsOnLoad property to false. Since RadGrid transfers JSON data when bound on the client, if you have some kind of templates - GridTemplateColumn/ NestedViewTemplate - there is no proper way for populating the controls in these templates as they are templates. However, for the rows that are initially created on the server (these PageSize items), RadGrid will manage to populate a control in GridTemplateColumn if the control in that ItemTemplate has ID set equal to the DataField property of that column.

More information about how to use web services and expose them to page methods/client scripts in ASP.NET AJAX can be gathered from the following MSDN resources: https://www.asp.net/ajax/documentation/live/tutorials/ExposingWebServicesToAJAXTutorial.aspx

https://www.w3schools.com/webservices/default.asp

Declarative client-side binding

This first example demonstrates how to use declarative client-side data-binding.

RadGrid declarative client-side data-binding is very similar to ObjectDataSource data-binding. You need to specify SelectMethod and SelectCountMethod (if needed) along with Location property and the grid will automatically invoke the specified method as PageMethod or WebService method:

ASP.NET
...
<ClientSettings> 
  <DataBinding Location="~/Grid/Examples/Client/DeclarativeDataBinding/WebService.asmx" SelectMethod="GetData" SelectCountMethod="GetCount" /> 
</ClientSettings>
...

Important: These methods should be marked with WebMethod attribute . Example: [WebMethod(EnableSession=true)]public List GetData(int startRowIndex, int maximumRows, List sortExpression, List filterExpression){...}

In the ClientSettings.DataBinding section you can also specify the following properties:

  • StartRowIndexParameterName - default is "startRowIndex"

  • MaximumRowsIndexParameterName - default is "maximumRows"

  • SortParameterName - default is "sortExpression"

  • FilterParameterName - default is "filterExpression"

Important: By default RadGrid will expect SelectMethod with four arguments with the following names and types:

  • int startRowIndex
  • int maximumRows
  • List sortExpression
  • List filterExpression> and SelectCountMethod with no arguments!

To change values on the fly of any of the grid declarative client-side data-binding properties you can use the OnDataBinding client-side event:

ASP.NET
...
<ClientEvents OnDataBinding="RadGrid1_DataBinding" />
...

Please refer to the JavaScript code in the demo for more information.To optimize even more the grid client-side data binding you can get both data and total items count in a single request. Example:

C#
[WebMethod(EnableSession = true)]
public Dictionary<string, object> GetDataAndCount(int startRowIndex, int maximumRows, List<GridSortExpression> sortExpression, List<GridFilterExpression> filterExpression)
{
    Dictionary<string, object> data = new Dictionary<string, object>();
    data.Add("Data", GetData(startRowIndex, maximumRows, sortExpression, filterExpression));
    data.Add("Count", (int)Session["Count"]); return data;
}

The grid will check automatically for "data" and "count" and will not execute a second request.

Client-side caching

This example demonstrates how to enable/disable the grid client-side caching.

RadGrid can cache data on the client based on the current grid state. To enable/disable this feature you can use the ClientSettings.DataBinding.EnableCaching property (its default value is false):

ASP.NET
...
<ClientSettings> 
  <DataBinding Location="~/Grid/Examples/Client/DeclarativeDataBinding/WebService.asmx" SelectMethod="GetDataAndCount" EnableCaching="true" /> 
</ClientSettings>
...

With client-side caching enabled RadGrid will store the start row index, maximum rows, sorting and filtering expressions and will retrieve them from the cache automatically on subsequent client-side refreshes.

Non-declarative client-side binding

The second client-side binding demo illustrates how to:

  • extract information about the current page index/virtual item count or set them on the client.

  • customize the appearance of the grid items based on their column cell values (intercepting the OnRowDataBound client event of the grid).

  • obtain the values of the sort expressions/filter expressions applied to the control.

Further information about the OnCommand/OnRowDataBound events of RadGrid and the client GridTableView object's properties, methods and collections can be gathered from the Client-side API Reference chapter in the documentation.

Below are some code excerpts from the second QSF example:

ASP.NET
  <html xmlns="https://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
   <telerik:RadCodeBlock ID="RadCodeBlock1" runat="server">
       <script type="text/javascript">
       function pageLoad()
       {
          $get("<%= Panel1.ClientID %>").innerHTML = "";
          if(!$get("<%= CheckBox2.ClientID %>").checked)
          {
              var tableView = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
             
              PageMethods.GetData(0, tableView.get_pageSize(),
                   tableView.get_sortExpressions().toString(), tableView.get_filterExpressions().toString(),
                       updateGrid);
           }
       }
      
       function RadGrid1_Command(sender, args)
       {
           $get("<%= Panel1.ClientID %>").innerHTML = String.format("<b>RadGrid1_Command</b><br />CommandName : {0}, CommandArgument : {1} <br /><br />", args.get_commandName(), args.get_commandArgument());
      
           args.set_cancel(true);
          
           var currentPageIndex = sender.get_masterTableView().get_currentPageIndex();
           var pageSize = sender.get_masterTableView().get_pageSize();
           var sortExpressions = sender.get_masterTableView().get_sortExpressions();
           var filterExpressions = sender.get_masterTableView().get_filterExpressions();
          
           if(sortExpressions.length > 0 && filterExpressions.length > 0 && currentPageIndex > 0)
           {
               sender.get_masterTableView().set_currentPageIndex(0);
           }
          
           var sortExpressionsAsSQL = sortExpressions.toString();
           var filterExpressionsAsSQL = filterExpressions.toString();
          
           var maximumRows = <%= (RadGrid1.AllowPaging)? RadGrid1.PageSize : RadGrid1.Items.Count %>;
           PageMethods.GetData(currentPageIndex * pageSize, maximumRows, sortExpressionsAsSQL, filterExpressionsAsSQL, updateGrid);
          
           if(args.get_commandName() == "Filter")
           {
               PageMethods.GetCount(filterExpressionsAsSQL, updateVirtualItemCount);
           }
       }
       function updateGrid(result)
       {
          var tableView = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
          tableView.set_dataSource(result);
          tableView.dataBind();
       }
      
       function updateVirtualItemCount(result)
       {
          var tableView = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
          tableView.set_virtualItemCount(result);
       }
       function toggleAllowMultiColumnSorting(sender, e)
       {
          var tableView = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
          tableView.set_allowMultiColumnSorting(sender.checked);
       }
      
       function RadGrid1_RowDataBound(sender, args)
       {
           // conditional formatting
           args.get_item().get_cell("TitleOfCourtesy").style.fontWeight = (args.get_dataItem()["TitleOfCourtesy"] == "Dr.")? "bold" : "normal";
           var sb = new Sys.StringBuilder();
          
           sb.appendLine("<b>RadGrid1_RowDataBound</b><br />");
          
           for(var item in args.get_dataItem())
           {
               sb.appendLine(String.format("{0} : {1}<br />", item, args.get_dataItem()[item]));
           }
          
           sb.appendLine("<br />");
           sb.appendLine("<br />");
           $get("<%= Panel1.ClientID %>").innerHTML += sb.toString();
       }
       </script>
   </telerik:RadCodeBlock>
</head>
<body>
   <form runat="server" id="mainForm" method="post" style="width: 100%;">
       <telerik:RadScriptManager ID="ScriptManager1" EnablePageMethods="true" runat="server" />
       <telerik:RadStyleSheetManager ID="RadStyleSheetManager1" runat="server" />
       <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
           <AjaxSettings>
               <telerik:AjaxSetting AjaxControlID="CheckBox2">
                   <UpdatedControls>
                       <telerik:AjaxUpdatedControl ControlID="RadGrid1" />
                   </UpdatedControls>
               </telerik:AjaxSetting>
           </AjaxSettings>
       </telerik:RadAjaxManager>
       <!-- content start -->
       <asp:CheckBox ID="CheckBox1" Text="Allow multi column sorting" Checked="true" runat="server"
           onclick="toggleAllowMultiColumnSorting(this, event);" />
       <br />
       <asp:CheckBox ID="CheckBox2" Text="Bind the grid server-side on initial load" Checked="true"
           AutoPostBack="true" runat="server" />
       <br />
       <br />
       <telerik:RadGrid RenderMode="Lightweight" ID="RadGrid1" EnableViewState="false" PageSize="2" Skin="Sunset"
           runat="server" AllowPaging="true" AllowSorting="True" AllowFilteringByColumn="true"
           GridLines="None">
           <MasterTableView AllowMultiColumnSorting="true" />
           <PagerStyle Mode="NextPrevAndNumeric" />
           <ClientSettings>
               <ClientEvents OnCommand="RadGrid1_Command" OnRowDataBound="RadGrid1_RowDataBound" />
           </ClientSettings>
       </telerik:RadGrid>
       <br />
       <br />
       Events:
       <asp:Panel ID="Panel1" Style="height: 200px; overflow: auto; padding: 15px;" CssClass="module"
           runat="server">
       </asp:Panel>
   </form>
</body>
</html>