jQuery Templates and Data Linking (and Microsoft contributing to jQuery)

The jQuery library has a passionate community of developers, and it is now the most widely used JavaScript library on the web today.

Two years ago I announced that Microsoft would begin offering product support for jQuery, and that we’d be including it in new versions of Visual Studio going forward. By default, when you create new ASP.NET Web Forms and ASP.NET MVC projects with VS 2010 you’ll find jQuery automatically added to your project.

A few weeks ago during my second keynote at the MIX 2010 conference I announced that Microsoft would also begin contributing to the jQuery project.  During the talk, John Resig -- the creator of the jQuery library and leader of the jQuery developer team – talked a little about our participation and discussed an early prototype of a new client templating API for jQuery.

In this blog post, I’m going to talk a little about how my team is starting to contribute to the jQuery project, and discuss some of the specific features that we are working on such as client-side templating and data linking (data-binding).

Contributing to jQuery

jQuery has a fantastic developer community, and a very open way to propose suggestions and make contributions.  Microsoft is following the same process to contribute to jQuery as any other member of the community.

As an example, when working with the jQuery community to improve support for templating to jQuery my team followed the following steps:

  1. We created a proposal for templating and posted the proposal to the jQuery developer forum (http://forum.jquery.com/topic/jquery-templates-proposal and http://forum.jquery.com/topic/templating-syntax ).
  2. After receiving feedback on the forums, the jQuery team created a prototype for templating and posted the prototype at the Github code repository (http://github.com/jquery/jquery-tmpl ).
  3. We iterated on the prototype, creating a new fork on Github of the templating prototype, to suggest design improvements. Several other members of the community also provided design feedback by forking the templating code.

There has been an amazing amount of participation by the jQuery community in response to the original templating proposal (over 100 posts in the jQuery forum), and the design of the templating proposal has evolved significantly based on community feedback.

The jQuery team is the ultimate determiner on what happens with the templating proposal – they might include it in jQuery core, or make it an official plugin, or reject it entirely.  My team is excited to be able to participate in the open source process, and make suggestions and contributions the same way as any other member of the community.

jQuery Template Support

Client-side templates enable jQuery developers to easily generate and render HTML UI on the client.  Templates support a simple syntax that enables either developers or designers to declaratively specify the HTML they want to generate.  Developers can then programmatically invoke the templates on the client, and pass JavaScript objects to them to make the content rendered completely data driven.  These JavaScript objects can optionally be based on data retrieved from a server.

Because the jQuery templating proposal is still evolving in response to community feedback, the final version might look very different than the version below. This blog post gives you a sense of how you can try out and use templating as it exists today (you can download the prototype by the jQuery core team at http://github.com/jquery/jquery-tmpl or the latest submission from my team at http://github.com/nje/jquery-tmpl). 

jQuery Client Templates

You create client-side jQuery templates by embedding content within a <script type="text/html"> tag.  For example, the HTML below contains a <div> template container, as well as a client-side jQuery “contactTemplate” template (within the <script type="text/html"> element) that can be used to dynamically display a list of contacts:

image

The {{= name }} and {{= phone }} expressions are used within the contact template above to display the names and phone numbers of “contact” objects passed to the template.

We can use the template to display either an array of JavaScript objects or a single object. The JavaScript code below demonstrates how you can render a JavaScript array of “contact” object using the above template. The render() method renders the data into a string and appends the string to the “contactContainer” DIV element:

image

When the page is loaded, the list of contacts is rendered by the template.  All of this template rendering is happening on the client-side within the browser:

image 

Templating Commands and Conditional Display Logic

The current templating proposal supports a small set of template commands - including if, else, and each statements. The number of template commands was deliberately kept small to encourage people to place more complicated logic outside of their templates.

Even this small set of template commands is very useful though. Imagine, for example, that each contact can have zero or more phone numbers. The contacts could be represented by the JavaScript array below:

image

The template below demonstrates how you can use the if and each template commands to conditionally display and loop the phone numbers for each contact:

image

If a contact has one or more phone numbers then each of the phone numbers is displayed by iterating through the phone numbers with the each template command:

image

The jQuery team designed the template commands so that they are extensible. If you have a need for a new template command then you can easily add new template commands to the default set of commands.

Support for Client Data-Linking

The ASP.NET team recently submitted another proposal and prototype to the jQuery forums (http://forum.jquery.com/topic/proposal-for-adding-data-linking-to-jquery). This proposal describes a new feature named data linking. Data Linking enables you to link a property of one object to a property of another object - so that when one property changes the other property changes.  Data linking enables you to easily keep your UI and data objects synchronized within a page.

If you are familiar with the concept of data-binding then you will be familiar with data linking (in the proposal, we call the feature data linking because jQuery already includes a bind() method that has nothing to do with data-binding).

Imagine, for example, that you have a page with the following HTML <input> elements:

image

The following JavaScript code links the two INPUT elements above to the properties of a JavaScript “contact” object that has a “name” and “phone” property:

image

When you execute this code, the value of the first INPUT element (#name) is set to the value of the contact name property, and the value of the second INPUT element (#phone) is set to the value of the contact phone property. The properties of the contact object and the properties of the INPUT elements are also linked – so that changes to one are also reflected in the other.

Because the contact object is linked to the INPUT element, when you request the page, the values of the contact properties are displayed:

image

More interesting, the values of the linked INPUT elements will change automatically whenever you update the properties of the contact object they are linked to.

For example, we could programmatically modify the properties of the “contact” object using the jQuery attr() method like below:

image

Because our two INPUT elements are linked to the “contact” object, the INPUT element values will be updated automatically (without us having to write any code to modify the UI elements):

image

Note that we updated the contact object above using the jQuery attr() method. In order for data linking to work, you must use jQuery methods to modify the property values.

Two Way Linking

The linkBoth() method enables two-way data linking. The contact object and INPUT elements are linked in both directions. When you modify the value of the INPUT element, the contact object is also updated automatically.

For example, the following code adds a client-side JavaScript click handler to an HTML button element. When you click the button, the property values of the contact object are displayed using an alert() dialog:

image

The following demonstrates what happens when you change the value of the Name INPUT element and click the Save button. Notice that the name property of the “contact” object that the INPUT element was linked to was updated automatically:

image

The above example is obviously trivially simple.  Instead of displaying the new values of the contact object with a JavaScript alert, you can imagine instead calling a web-service to save the object to a database. The benefit of data linking is that it enables you to focus on your data and frees you from the mechanics of keeping your UI and data in sync.

Converters

The current data linking proposal also supports a feature called converters. A converter enables you to easily convert the value of a property during data linking.

For example, imagine that you want to represent phone numbers in a standard way with the “contact” object phone property. In particular, you don’t want to include special characters such as ()- in the phone number - instead you only want digits and nothing else. In that case, you can wire-up a converter to convert the value of an INPUT element into this format using the code below:

image

Notice above how a converter function is being passed to the linkFrom() method used to link the phone property of the “contact” object with the value of the phone INPUT element. This convertor function strips any non-numeric characters from the INPUT element before updating the phone property.  Now, if you enter the phone number (206) 555-9999 into the phone input field then the value 2065559999 is assigned to the phone property of the contact object:

image

You can also use a converter in the opposite direction also. For example, you can apply a standard phone format string when displaying a phone number from a phone property.

Combining Templating and Data Linking

Our goal in submitting these two proposals for templating and data linking is to make it easier to work with data when building websites and applications with jQuery. Templating makes it easier to display a list of database records retrieved from a database through an Ajax call. Data linking makes it easier to keep the data and user interface in sync for update scenarios.

Currently, we are working on an extension of the data linking proposal to support declarative data linking. We want to make it easy to take advantage of data linking when using a template to display data.

For example, imagine that you are using the following template to display an array of product objects:

image

Notice the {{link name}} and {{link price}} expressions. These expressions enable declarative data linking between the SPAN elements and properties of the product objects. The current jQuery templating prototype supports extending its syntax with custom template commands. In this case, we are extending the default templating syntax with a custom template command named “link”.

The benefit of using data linking with the above template is that the SPAN elements will be automatically updated whenever the underlying “product” data is updated.  Declarative data linking also makes it easier to create edit and insert forms. For example, you could create a form for editing a product by using declarative data linking like this:

image

Whenever you change the value of the INPUT elements in a template that uses declarative data linking, the underlying JavaScript data object is automatically updated. Instead of needing to write code to scrape the HTML form to get updated values, you can instead work with the underlying data directly – making your client-side code much cleaner and simpler.

Downloading Working Code Examples of the Above Scenarios

You can download this .zip file to get with working code examples of the above scenarios.  The .zip file includes 4 static HTML page:

  • Listing1_Templating.htm – Illustrates basic templating.
  • Listing2_TemplatingConditionals.htm – Illustrates templating with the use of the if and each template commands.
  • Listing3_DataLinking.htm – Illustrates data linking.
  • Listing4_Converters.htm – Illustrates using a converter with data linking.

You can un-zip the file to the file-system and then run each page to see the concepts in action.

Summary

We are excited to be able to begin participating within the open-source jQuery project.  We’ve received lots of encouraging feedback in response to our first two proposals, and we will continue to actively contribute going forward.  These features will hopefully make it easier for all developers (including ASP.NET developers) to build great Ajax applications.

Hope this helps,

Scott

P.S. [In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu]

52 Comments

  • I like the concept, however, the code for templating looks like a dogs breakfast. I still think rendering on the server is the best approach.

  • Love it, thanks for posting. I have a feeling this will be the 'drag data-grid on new page' demo equivalent of 2010+.

  • Great features. Keep it up!

  • I also like this concept especially in client-centric.
    I use templating from asp.net ajax and all UI logic ,bindings and rendering put in js files in imperative way.
    Its help me keeping pure HTML and data separately.

  • This is good news. Lately I've found myself moving more and more ui code to the client and just keeping biz-logic on the server. Personaly I think this model is really sweet!
    I'm very glad to see that you embrace jQuery instead of going your own way. I like this "new" thinking from Microsoft! Keep it up :)

  • I was wondering whether the linkBoth() method updates the object from the input box on key press or only when the textbox is blurred. If it's only on blur, can it be altered to trigger from keyup?

  • We have been using the jquery templating engine successfully in our project to get custom grid kind of functionality.

    However, the version we use allows for inline javascript code within the template using the {% %} syntax. That syntax is similiar to the WebForms view engine in asp.net mvc. I don't know why you guys would want to tame down the power of templating by adding additional commands, instead of allowing people to harness the power of raw javascript. I haven't looked at the new syntax though. These things aside, I think you guys are doing an *amazing* job by providing developers with plugins like these. Thank you very much :)

  • That the best practices to do JS template and create your page from array'object => ligter pages => fater navigation etc..
    However, I find this more cleaner to get my template from an HtmlHelper, it's help me to create dynamic template, and more easily maintainable.

  • Spiffy. What's the best way to link the scripts for ASP.NET Master Pages site-wide? thx

  • I'm sad to see the ASP.NET AJAX 4 loosing it's features..
    I've invested in it and now I'll have to migrate to this new engine...

    This is one feature we need "yesterday" and it's coming "the day after tomorrow"

  • Great stuff! This could be really handy when it comes to presenting JSON data returned by the SharePoint 2010 REST interface (or any other OData interface) in a browser without using ASP.NET AJAX (OpenDataServiceProxy). I want to use jQuery, but I don't want to traverse my JSON response and explicitly extract values from it before I can display them, I just want to bind (or link) the whole JSON response.

    Thanks Scott!

  • Great features, loved it!

  • Script templating structure is very useful and important. Advanced Ajax applications can be developed easily. Thanks.

  • I really hope speed is a top priority, AFAIC that's the only reason why I would bother to develop a pure AJAX app over a standard website in the first place.

    Looking at the syntax though it doesn't look like it is. Also the template syntax looks foreign, so it's going to be yet another language in a language developers will need to remember.

    Is there a reason for not using a familiar JSP/EL or Smarty-like sytax, ala: ${ expression } ?

  • This is great, but how can I use these templates to populate data server-side? I'm using partial views to encapsulate display layouts, then using ajax to call and display the rendered control. It would be great to replace that with jquery templates by creating one template that can be used to render the initial view and then update it client-side.

  • Awesome!!!!!!!

  • Instead of templating you could just use partial views so i'm not sure how usefull it really is but great that jquery is getting the attention it deserves. Now if only entity framework would get an overhaul ;/

  • Wow that looks blisteringly ugly! Might want to hire some graphic designers eh lads!

  • I just wanted to express how excited I am that Microsoft is contributing the jQuery. I have been an ASP.NET developer for a little over 5 years and ever since I discovered jQuery about 2 years ago, I have used it in almost every project I have had.

    So, thanks!

  • @Demis: ${expression} is supported as well, as a shortcut for {{=expression}}

  • I like the IDEA of templates I am curious why you don't just nest the renders to manage the application of lists within the template. you could make a call like {{= $('#phoneTemplate').Render(phones) }} You could even do some inline conditional javascript to do your if statement. It would be much cleaner and more jquery like.

  • I don't understand why you are not proposing the use of templating/linking specific HTML elements and/or attributes in their own namespace within XHTML. Wouldn't you gain the benefit of the existing DOM Parser? Wouldn't it play "nicer" with editors, validators, intellisense, or anything else built on standards?

    I just don't understand why anyone proposes a new delimiter based scheme these days when XML fills that role. It's almost like people with a heavy focus on scripting want to see braces everywhere. They have no place in markup.

    I can't see how this validates well either. If you have {{each .....}} within a table element, that isn't going to validate.

    The best example I can think of for using the power of extending XHTML is the Backbase Client Library (http://demo.backbase.com/explorer/#|examples/welcome.xml). I do not represent them or work for them in any way shape or form. I have not used that library for anything in production. But I do respect how it accomplishes what it does by extending XHTML which is the way XHTML was designed.






  • This stuff looks cool, but why bother with the whole "proposal" process? Why not just create a plugin, throw it out there, and take feedback from people? Isn't that how the jQuery community works?

  • Hi,

    It is really nice as Template Support include in JQuery.

    One more thing that comes to my mind that there should be new page type in ASP.net project in Visaul Studio Which has something like this

    Default.aspx
    - Default.aspx.cs
    - Default.aspx.jQueryTemplate
    So As part of Page rendering template also render to page. Developer manually create js if make jquery call and use template

    Means there should be way for seprate out template from original page.

  • Kevin,

    They want to get it in jQuery Core. I don't think the template engine belongs in the core, but I think the data linking is a good fit.

  • @richardcollette: re validation: the template is not markup, it's within a script element. It is treated as plain text. It is not html, it is a language which describes how to build html.

  • Templating is a key feature for client side dev for sure...

    One odd choice in the above to me is on why you'd want to limit the template to a specific syntax. Why not just use JavaScript and allow all that the language offers like in the original micro-templating that John Resig threw out a while back? It gives so much more control rather than being bound by having to create custom extensions.

    Keeping logic out of templates is a weak argument - developers should be able to control what goes where and they can excercise the restraint if they so desire. There are too many odd situations where a replace or substr or format needed and having to write custom converters for each micro-scenario is a pain in the butt.

    Rather than dealing with value converters what we really need is a solid formatting (and localization/globalization?) library for dates and numbers that works across JavaScript in general. Most of the support out there today is limited and clumsy (it's not easy to build solid formatters)... if it's plain JS and templates support embedding of plain JS expressions one shot fits all...

  • What does browser compatibility look like for templating?

  • It's really good I will try it in my new project.

  • @Jonathan Park: I immediately thought of XSLT when I started reading about this. Of course, it would be handy if it became part of the jQuery core and didn't require a plugin, but that's not for Microsoft to decide.

    I wonder what the other advantages would be over using an XSLT plugin? Anyone?

  • Wow, yet another unneeded abstraction. How is this any better or easier than simply using selectors and dom elements? To be honest it looks like you are taking something really simply and making it more complex...

  • Very nice, loving the client side templates.

  • Great!
    I have a deadline for a demo tomorrow, and just read your post. 5 minutes later I am up and running with your code. This is a real timesaver!

  • Hi,

    This article is very nice. I have to learn a lot after going through this article.

    Thanks,
    Thanigainathan.S

  • This is great work, Scott. Especially client-side templating.

    You guys LOVE data binding at Microsoft. I can't count how many times I've learned this pattern for different frameworks and technologies, yet real applications always outstrip its capabilities fairly quickly. Nevertheless, it's very useful at times.

  • Ah I've been waiting for something like this for a while!

    In the 'Two Way Linking' section, you alert out the values via contact.name rather than $(contact).attr('name')

    This is a little deceiving since you should only read that value via contact.name. Writing to it bypasses the binding, so alerting it out that way just seems odd. However, I do suppose it does demonstrate that the binding changes the underlying object.

    The only thing that bugs me about all of this is that if I want to change the value programatically, I have to do $(contact).attr('name', 'new value'); and by doing that, I loose all intellisense on the attribute "name" since its a string at that point.

    I do suppose one could write a $(contact).setName('new value'); function that simply calls this.attr('name',value); to retain databinding and intellisense. It does seem a bit verbose, unfortunately.

  • Say if contact.name = { firstName = "bob", lastName = "smith" }

    does the linkTo / linkFrom support that? I've been experimenting to see if it does and so far I cant get it to work.

  • Its is possible to use jquery templates in imperative way?

  • How does it affect "Microsoft Client Templates"? Is it going away? Are you replacing it with jQuery Templates?

  • I just implemented a templating solution, written about by Rick Strahl, and it worked out well. I look forward to Microsoft supporting (and now contributing to) jQuery into the future. I've been working with Microsoft Technologies for the past 14 years and have always been slightly annoyed by the dictatorial, rather than collaborative, approach to pushing out tools. The change is great!

  • Hi... is this available only to VS2010 or can be done in VS2008?
    Thanks!

  • It is nice to have this powerful features available on the client side, any security support from client to backend service?

  • I am having flashbacks of XML Data Islands circa 2001.

  • This is really a nice features Idea is cool to have client side templates to display data. Thanks for sharing gr8 work Scott.

  • Hey! How is the better way to adapt this feature to work following the non-obstrusive javascript?

  • this post i'm looking for.

  • I have a question.
    How can I place a button inside of the template? And let's say if I have 5 contacts in my template how am I gonna understand which button is clicked?
    Thank you

  • I love Jquery And Microsoft Is Doing Very Best In Merging Both.
    Thank You.

  • Is it release formally?
    When does it to be added into jquery core?

  • Fantastic, cant wait to see these features added to JQuery.

  • I will severely miss the ASP.NET AJAX 4.0 Preview Client-Side Templating. Sure, it will live on in unsupported limbo, but will lose momentum and die out.

    I believe the speed and elegance of that project, along with the ability for it to integrate deeply with WCF Data Services would have been as revolutionary as the original ASP.NET was to web development.

    It was amazing how the Microsoft Ajax 4.0-preview templating engine was able to dynamically compile the code for instantiating the templates (all in client-side script), and the databinding syntax was clean and powerful. I really thought that Microsoft Ajax 4.0-preview6 was evidence of a new programming paradigm for the web, and that Microsoft was "hiding in plain sight" putting out that fantastic bunch of code (and getting so little recognition for it). The jQuery templating library is rudimentary in comparison.

    Unfortunately it seems as though promising projects such as the Ajax 4.0 Preview, and Script# (another amazing library which I suspect the client templating preview was built with, having looked at the code) are only given "preview" or "side-project" levels of support at Microsoft. Those projects have the most potential to be so awesome!

    All signs point toward having all web applications in the future be heavily client-side using javascript (which could be done with Script#) and rendered from server-side data (a perfect use case for ADO.NET Data Services and the Preview6 template library). Why on earth would the ASP.NET team shift back to working on server-side technology? I am extremely frustrated with that decision.

  • I haven't used it yet. But as VS 2010 has default support for jQuery I will try it.

    thanks for sharing...

Comments have been disabled for this content.