Telerik blogs

The Q1 2012 beta release is out the door and we have some exciting new improvements to brag about. Among everything else is a feature long waited for - client-side databinding for RadListView. In a series of blog posts, I will try to introduce you to the specifics of the client-side databinding with RadListView and give you some insight into the new client capabilities that you can leverage to build performant data bound UI on the client. We will start with a brief introduction to HTML templates, binding expressions and databinding API, we'll go down to databinding to web services and various data sources and will finish off with some advanced topics like client-side paging, sorting, filtering and item selection support.

If you want to skip sections ahead, here is a brief table of contents that you can follow:

  1. Introduction
  2. HTML Templates
  3. Binding Expressions
  4. Binding Context

Introduction

To start off, let's clarify what does client-side databinding mean for a control that is entirely template-driven and does not have UI of its own. If you have ever worked with the ASP.NET ListView control, or its older sibling - the Repeater, you already know what a template-driven control means. These are, essentially, databound lists. The developer uses a series of template definitions to give the list a layout of its own. During databinding, templates are instantiated sequentially for every item from the data source and you get the final UI rendered into the browser. This all happens on the server-side. Telerik RadListView for ASP.NET AJAX already extends this server-side databinding model, providing additional templates, paging, sorting, filtering and grouping off-the-box.

HTML Templates

Starting with Q1 2012, we have extended this databinding model to the client. You can now use HTML templates to define a layout that is databound entirely on the client-side. RadListView provides quite an extensive set of templates available for client binding:

  • LayoutTemplate
  • ItemTemplate
  • AlternatingItemTemplate
  • SelectedItemTemplate
  • ItemSeparatorTemplate
  • EmptyDataTemplate

People already using RadListView with server-side databinding will immediately recognize these template names. They work the same with client-side databinding too. The major difference is, while server templates are defined as first-level children of the RadListView control in the markup, all client templates are exposed as properties under RadListView.ClientSettings.DataBinding. Also, the server templates allow server controls, naturally. The client templates are nothing more than string properties, so they allow HTML only.

Let's get to the interesting part and define a rather simple client-bound RadListView. Just like with server-side databinding, you need at least 3 definitions to make a list view show up on your page:

  1. A layout template
  2. An item template
  3. An item place holder

Let's define the skeleton of a simple RadListView that will be used to render an unordered list in the browser:

listview_clientbinding_1.png

We define our LayoutTemplate to contain a <ul> element. We further give this element and id attribute. By setting the RadListView.ClientSettings.DataBinding.ItemPlaceHolderID property the value of this ID, we instruct RadListView to take the unordered list as the parent container for all items that will be rendered by RadListView. Without specifying the HTML element that will contain all databound items, there is no way for RadListView to tell where it should place the rendered items during databinding.

Once we setup our layout and item place holder, we can define an ItemTemplate that will be rendered for every bound item during databinding. In our case, we specify a <li> element that will represent an item in the resulting unordered list.

NOTE: Client-side templates in RadListView are plain string properties. Even though you can define them in the markup view in Visual Studio, no IntelliSense support is provided. Code completion for HTML tags is the best Visual Studio can offer when editing string templates.

Binding Expressions

We have defined our basic UI in the above RadListView. Let's see how we can make the list view show some data inside the HTML elements we have put in there. We can use a set of binding expression in the client-side HTML templates in RadListView.

 

Format Name Description
#= ... # Data Evaluates the expression and outputs the result in the template.
# ... # Code Evaluates the code expression inside. Does not output value.
#: ... # HTML-encoded string Same as the data expression, but HTML-encodes the result.

In a server-bound template, you can use the <%# ... %> binding expression along with Eval() to render the value of a field from the data item. Equivalently, with a client-bound template, you can use the #= [field name] # expression to render the value of a data field.

Turning back to our RadListView definition, let's define a binding expression that will show the value of a field id in our list items:

listview_clientbinding_2.png

We have defined a binding expression in the ItemTemplate, telling RadListView to render the value of the id field in the data items as content of the list item element.

Time to see the result of our effort so far. For the purpose of this example, we will use a rather simple data source for RadListView - a javascript array of objects:

listview_clientbinding_3.png

The actual databinding is done through the client-side RadListView API. We need to find the RadListView client component once the page and the client-side AJAX framework have finished loading. The auto-registered pageLoad() function is a good candidate. We then set the list view data source and databind:

listview_clientbinding_4.png

We run the page to see what we've created and get our first client-bound RadListView:

listview_clientbinding_5.png

That wasn't so difficult, was it? We made our list view render a couple of HTML elements right in the browser after page load. Let's go on and test some other binding expressions. You have probably noted the above sample data items have a name field that contains HTML. If we keep using the #= ... # expression with this field, we will get the values in this field rendered and interpreted as HTML in the browser:

listview_clientbinding_6.png

If we need to ensure HTML in field values is encoded, we can use the #: ... # binding expression:

listview_clientbinding_7.png

Binding Context

What happens in RadListView during client-side databinding? The control takes the template definitions strings and runs them through a client-side templating engine. If you are a javascript & HTML developer, chances are you have at least heard of client templates. Here are a couple of the more popular template engines out on the web:

Jeremy Askenas has started a nice little test bench on jsperf.com that tests the performance of these template engines. Later revisions add even more templating implementations.

Long story short, a javascript templating engine takes the HTML template string and builds a dynamic javascript function that can render this template. The dynamically created javascript function can then be cached for faster rendering of successive identical templates. This function can additionally be provided with a so called binding context object. This is a javascript object acting as the context of any binding expressions inside the HTML template. In our RadListView, the ItemTemplate contained a couple of binding expressions. These expressions were evaluated in the context of an object - the binding context. The id and name fields that we used in our binding expressions are part of the fields in this binding context.

NOTE: The binding context of an HTML template is not the same as the execution context of a function. In your binding expressions, this.id is not equivalent to id. Do not use this in your binding expressions.

In RadListView, all fields from the data item bound to a particular template are copied over to the binding context. In our example, the id, name and value fields are copied to the context of the binding expressions inside the ItemTemplate. Additionally, here is a list of all fields and functions available in the context of the binding expressions:

 

Field or Function Description
owner The current RadListView instance. Can be used for calling methods of the component.
format(value, format) A formatting function that can format Date and Number values. This function is based on the MS AJAX String.localeFormat(format, value) function.
The following context fields are available only in the ItemTemplate, AlternatingItemTemplate and SelectedItemTemplate
item The original JSON data object that the template is binding to.
index The index of the currently databinding item in the current data source.
dataIndex The index of the item in the set of all RadListView data. This field has a meaning only when paging is enabled. It indicates the page-invariant index of the item.
isSelected Indicates if the current item is selected

The above lists is expected to grow, so don't take it as the definitive API reference. The only definitive reference for any control is the online help documentation.

Using the above context fields, you have access to the RadListView client component, item indices and selected state at your disposal during template databinding. The format() function is worth a better explanation. It can be used to format numeric and date values from your data items during databinding.

Turning back to our RadListView example, we can see the value field in the data items is a numeric field, possibly representing a currency value. Using format() in our binding expressions, we can render the values from this field formatted as currency:

listview_clientbinding_8.png

The result of the format() function is a string representing a currency value in the format we specified:

listview_clientbinding_9.png

The new HTML templates in RadListView allow you to easily define a client-bound layout in your application. You can use binding expressions, context fields and functions to render, format and shape data values according to your needs. Client-side data binding is a javascript-intensive job. RadListView does the heavy lifting for you and provide you with a flexible model for binding HTML to data right in the browser. What is more - it steps on building blocks already familiar to ASP.NET developers. ASP.NET itself is template-driven. We all know how to define, use and bind templates. RadListView takes this approach to the next level, providing the same coding paradigm for client-side databinding. It saves tons of javascript usually written to enable that.

In this blog post, we wrote 13 lines of markup and 8 lines of javascript (along with closing braces on new lines) to make RadListView databind on the client. Half of the javascript written was just to define some sample data. In the next post in this series, we'll see how many more do we need to make RadListView databind automatically to a JSON service. I bet on -8, making a total of 0 (zero) lines of javascript needed for automatic web service binding. How many do you expect?

If we managed to catch your attention, don't stop here. Try the live RadListView demos, download the trial today and give the sweet stuff a go yourself. Leave a comment, suggestion or share the joy below in the comments or in our beta forums.


About the Author

Veli Pehlivanov

is a Technical Lead at one of Telerik’s ASP.NET AJAX teams, where he primarily works on RadGrid and a few other data- and input-centric controls, including RadListView, RadCalendar and RadInput. Veli's interests lie in the area of web development, C#, .NET, JavaScript and agile project management. He likes being on the cutting edge of technology and is keen on delivering efficient software and a greater value for the user.

Comments

Comments are disabled in preview mode.