RadComboBox and ASP.NET AJAX 4.0 Preview – using client-side templates and webservice load on demand

Thursday, January 15, 2009 by ASP.NET AJAX Team | Comments 7

Edit: The following content applies to ASP.NET Ajax 4.0 Preview 4. Download the project that uses the latest MS Ajax 4.0 Preview 6 from Here

Many of you have asked us, the ASP.NET support officers, whether RadComboBox supports templates when bound to WebService. Using the latest official .NET Framework (3.5) the answer was ‘no’.

Fortunately, this is possible with the client-side templates introduced in the next version of the .NET Framework – 4.0. Currently it is in a Preview stage and you can find its roadmap here

We have already demonstrated how to use the new client-side templates in RadTreeView and RadGrid.

The demo that you can download below shows how to create a multi-column RadComboBox bound to WebService. Here are the important steps that you need to perform:

1. Register the MicrosoftAjaxTemplates.js file in the ScriptManager:

<asp:ScriptManager ID="ScriptManager1" runat="server">
   <Scripts>   
       <asp:ScriptReference Path="~/MicrosoftAjaxTemplates.js" />
   </Scripts>
</asp:ScriptManager>

2. Configure a RadComboBox instance to consume a web service:

<telerik:RadComboBox runat="server" ID="RadComboBox1"
   EnableLoadOnDemand="true"
   OnClientItemDataBound="onItemDataBound"  
   OnClientSelectedIndexChanged="onSelectedIndexChanged">
   <WebServiceSettings Method="GetEmployees" Path="Employees.asmx" /> </telerik:RadComboBox>

3. Add a LinqToSql class and drop the Employee table from the Northwind database.

4. Write the GetEmployees web service method which is used to populate RadComboBox:

[WebMethod]
public IList<Employee> GetEmployees(RadComboBoxContext context)
{
    NorthwindDataContext db = new NorthwindDataContext();
 
    var employees = from e in db.Employees
                    where (e.FirstName.StartsWith(context.Text.ToLower()))
                    select e;
 
    return employees.ToList();
}

5. Add the client-side template:

<div id="myTemplate" class="sys-template">
<!--* if (Index % 2 == 0) { *-->
<table class="employeeTableAlt"> <tr> <td class="employeeFirstName">
                {{ FirstName }}
            </td> <td class="employeeLastName">
                {{ LastName }}
            </td> <td>
                {{ Address }}
            </td> </tr> </table>
<!--* } else { *-->
<table class="employeeTable"> <tr> <td class="employeeFirstName">
                {{ FirstName }}
            </td> <td class="employeeLastName">
                {{ LastName }}
            </td> <td>
                {{ Address }}
            </td> </tr> </table>
<!--* } *-->
</div>

6. Consume the OnClientItemDataBound event (which is a brand new client-side event occurring when an item is created during web-service load on demand) and instantiate the template inside the item's <LI> HTML element:

<script type="text/javascript">
    function onItemDataBound(sender, eventArgs)
    {
        //the combo item var item = eventArgs.get_item();
        //the data item of type Employee var dataItem = eventArgs.get_dataItem();
        //this will be used when selecting an item - its text attribute will go to the input area
        item.get_attributes().setAttribute("text", dataItem.FirstName +
 
          " " + dataItem.LastName);
        item.set_value(dataItem.EmployeeID);
         
        //this is a custom property used in the template to alternate the css styles
        dataItem.Index = item.get_index();
 
        var template = new Sys.UI.Template($get("myTemplate"));
        template.instantiateIn(item.get_element(), dataItem);
    }
 
    function onSelectedIndexChanged(sender, eventArgs)
    {
        var item = eventArgs.get_item();
        sender.set_text(item.get_attributes().getAttribute("text"));
        sender.set_value(item.get_value());
    }
</script>

That’s it. You have a fast combobox with client-side templates.

 

Download the Project from here

 

 

Edit: Download the project that uses the latest MS Ajax 4.0 Preview 6 from Here

7 Comments

  • lchesnais 15 Jan 2009
    Hello Veselin, To improve performance, I would suggest the following: var template; function onItemDataBound(sender, eventArgs) { //the combo item var item = eventArgs.get_item(); //the data item of type Employee var dataItem = eventArgs.get_dataItem(); //this will be used when selecting an item - its text attribute will go to the input area item.get_attributes().setAttribute("text", dataItem.FirstName + " " + dataItem.LastName); item.set_value(dataItem.EmployeeID); //this is a custom property used in the template to alternate the css styles dataItem.Index = item.get_index(); if (template == null) { template = new Sys.UI.Template($get("myTemplate")); } template.instantiateIn(item.get_element(), dataItem); } The template variable is now global (to the window) and created only once. The first time template.instantiateIn is called, template is compiled (internaly) and won't be recompiled anymore. I tested this with RadGrid and it works great. BR, Laurent
  • Veselin Vasilev 16 Jan 2009
    Hi Laurent, you have made a good point. Thanks
  • Ken 02 Jan 2010
    Could you update this example to work with a more recent version of the AJAX library that's available as a CDN? (http://www.asp.net/ajaxLibrary/cdn.ashx)

    A walkthrough explaining how it works would also be valuable.

    Ken
  • Tilak 26 Jan 2010
    How do we get paging enabled in this scenario, I mean ShowMoreResults=true. Because the service return type is IEnumerable I don't see a way to send the Item count and message attributes.
  • Tilak 26 Jan 2010
    How do we get paging enabled in this scenario, I mean ShowMoreResults=true. Because the service return type is IEnumerable I don't see a way to send the Item count and message attributes.
  • Mathew 24 Nov 2011
    I'm attempting to follow this tutorial - everything seems to be working fine except for the binding on the template.  Whatever properties I try to bind to, it tells me that they are undefined.  Is there anything else that needs to be done on the client side in order to get this to work correctly?
  • Simon 25 Nov 2011
    Hi Mathew,
    The template code is for Preview 4 and there are minor differences between P4 and P6.
    Please change the last code in the ItemDataBound event in this way:
    template.instantiateIn(item.get_element(), {}, dataItem, dataItem.Index); 

    We will update the blog post shortly.
    Regards,
    Simon

Add comment

  1. Formatting options
       
     
     
     
     
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)