dial with green option NEW and red option OLD

Meet JsRender -- the Next Version of jQuery Templates

Explore JsRender, which can help you minimize JavaScript coding in HTML5 web apps

RELATED: "4 More Web Development Tips to Improve Your jQuery Coding" and "Better Mobile Website Development Using the jQuery Mobile Library."

Back in 2011 I wrote an article for Dev Pro that demonstrated how you could use the jQuery Templates plug-in to reduce the amount of JavaScript coding you need to do and simplify application maintenance in the process (see "Rendering Data on the Client with jQuery Templates"). Although the topics and code discussed in that article are still valid and relevant in today's client-centric applications, since that article was written things have changed somewhat regarding the future of jQuery Templates. I've had several questions come up in jQuery classes that my firm offers, at the DevConnections conference, and online about the future of jQuery Templates, so I thought I'd address the issue here and provide details about the current roadmap for client-side templates. 

You can get the full story in a blog post by Boris Moore, the creator of jQuery Templates. In a nutshell, the jQuery UI team decided to go in a different direction with client-side templates and use an alternative syntax to that provided by jQuery Templates. As a result, a new script has been released called JsRender that will ultimately replace jQuery Templates (that's the current plan, anyway). I'll review a few things mentioned in my initial article for those who aren't familiar with templates, then show examples of using the new JsRender functionality in an application. The good news is that if you're already using jQuery Templates, a significant portion of your template code can easily be updated to use JsRender if you want to make the switch.

Why Use Client-Side Templates?

Nearly every language out there uses templates in some manner to minimize the amount of code that has to be written. By using templates, you can define a template structure and use it to generate code, HTML, or other formats. If you've created ASP.NET applications, you're aware of how powerful and productive templates are when it comes to generating HTML output. However, what if you want to use templates on the client side to generate HTML rather than writing a lot of JavaScript to manipulate the Document Object Model (DOM)?

Since many HTML5 applications rely heavily on JavaScript to provide canvas, web storage, geolocation, and other features, minimizing the amount of code in an application wherever possible can simplify maintenance down the road. For example, you may want to avoid having to write the code shown in Figure 1 to update a list of items dynamically in a page. This simple example could certainly grow bigger and bigger depending on the type of dynamic HTML content being generated.

var total;
$(order.Items).each(function()
{
    var item = this;
    $('#item' + item.ID)
     .append('
' + item.Title + '
'); total += item.Total; }); $('#total').html(total);

Although templates have been available in jQuery for quite a while through various plug-ins, the JsRender template framework provides a new solution that doesn't use Cascading Style Sheets (CSS) in strange ways or require a lot of knowledge about a template language. By using JsRender, you can define HTML templates in web pages and use them to render HTML output dynamically at runtime.

You can download the JsRender script along with samples here. Although I won't discuss it in this article, JsRender has a companion script called JsViews that can be used for data binding. You can read more about JsViews here.

Getting Started with JsRender

You can use client-side templates by referencing the JsRender script in your page and then defining a

Once the script tag is defined, you can place template code inside of it. Any HTML you add into the template is output automatically once the template is rendered. Of course, adding static HTML doesn't accomplish much, so JsRender provides several tags that can be placed inside a template to define data that should be output, perform conditional logic, iterate through items, render nested templates, and perform other actions.

Two general types of tag categories can be defined in templates: property binding tags and action tags. Property binding tags allow properties in a JavaScript Object Notation (JSON) object to be bound into a template at runtime. They're similar to the <%# Eval("PropertyName") %> bindings that you'll see in ASP.NET Web Forms pages. For example, the following template tag handles binding the FirstName property of a JSON object into a template:

{{=FirstName}}

Here is an example of a simple template that renders a FirstName property inside of a

element using the JsRender binding syntax:


Several different types of action tags are available as well, such as if and each. Both of these tags use a # character in the template tag:

{{#if}}
{{#each}}

Figure 2 lists the main template tags available with JsRender and examples of using them.

{{else}} {{/if}} {{/each}}
Template Tag Example Description
Figure 2: Template tags available in JsRender
{{=fieldNameOrExpression}}
{{=DeliveryFee}}
Used to define data values that should be rendered in the template. Evaluates the specified property on the current data item and encodes the value.
{{=fieldNameOrExpression!}}
{{=Comments!}}
Used to define HTML markup strings that should be rendered by the template (notice that a ! character is placed at the end of the string). Evaluates the specified field on the current data item and doesn't encode the value.
{{#if condition}}
{{#if DeliveryFee > 0}}
   {{=DeliveryFee}} added
{{/if}}
Used for conditional insertion of content.
{{else}}
{{#if MainItems.length===0}}
    
No items selected
Ordered items!
Used to add additional conditional logic into JsRender templates.
{{#each}}
{{#each MainItems}}
    
{{=mi.NumberOrdered}} at ${{=mi.Price}}
Used to iterate over a data array and render the content for each data item.
{{#each
   tmpl="#NestedTemplateID"}}


Used for composition of templates. Renders one or more nested template items within the rendered output of the parent template.

Rendering a JsRender Template

Once a template is defined using a

This code uses the if and each tags. Looking through the code, you'll see that the each tag references another template named ItemsTemplate using the each tag's tmpl property. Here's an example of using tmpl:

{{#each MainItems tmpl="#ItemsTemplate"}} 

The ItemTemplate child template is reusable and handles writing out the products and accessories that were purchased. As the each tag iterates through the different items, it passes each item to the child template for rendering.

The template is rendered to a div with an ID of OrderSummaryOutput using the code shown in Figure 7. The code first creates a JSON object by retrieving data from controls in a checkout wizard, then calls the render() function provided by JsRender.

function LoadApprovalDiv() {
    var subTotal = parseFloat($('#SubTotal').text());
    $('#ClientSubTotal').val(subTotal.toFixed(2));
    var salesTaxRate = parseFloat($('#SalesTaxRate').val()) / 100;
    var salesTaxAmount = (subTotal * salesTaxRate) * .9;
    var deliveryFee = parseFloat($('#DeliveryFee').val());
    var adminFee = ((subTotal + salesTaxAmount + deliveryFee) * .05);
    var total = (Round(subTotal) + Round(salesTaxAmount) + Round(deliveryFee) +
         Round(adminFee));
    $('#ClientTotal').val(total);
    var deliveryAddress = $('#Delivery_Street').val();
    //See if they entered a suite
    if ($('#Delivery_Suite').val() != '') deliveryAddress += ', Suite ' +
    $('#Delivery_Suite').val();
    deliveryAddress += ' ' + $('#Delivery_City').val() + ' ' +
   $('#Delivery_StateID option:selected').text() + ' ' +
   $('#Delivery_Zip').val();
    var creditCard = $('#Payment_CreditCardNumber').val();
    var abbrCreditCard = '*' + creditCard.substring(creditCard.length - 5);

var json = {
           'FinalSubTotal'  : subTotal.toFixed(2),
           'FinalSalesTax'  : salesTaxAmount.toFixed(2),
           'FinalTotal'     : total.toFixed(2),
           'DeliveryFee'    : deliveryFee.toFixed(2),
           'AdminFee'       : adminFee.toFixed(2),
           'DeliveryName'   : $('#Delivery_Name').val(),
           'DeliveryAddress': deliveryAddress,
           'CreditCard'     : abbrCreditCard,
           'DeliveryDate'   : $('#Delivery_DeliveryDate').val(),
           'DeliveryTime'   : $('#Delivery_DeliveryTime
                    option:selected').text(),
           'MainItems'      : GenerateJson('Main'),
           'AccessoryItems' : GenerateJson('Accessory')
       };

//jQuery template example
    $("#OrderSummaryOutput").html($("#OrderSummaryTemplate").render(json));
}

In addition to the JsRender features I've shown here, several others are available, including the ability to define custom tags, helper tags, and functions. Additional details about these features are outside the scope of this article, but you can read more about them at the JsRender site on GitHub. The site even includes examples of using JsRender without jQuery (although I'm a huge fan of jQuery and highly recommend it!).

Improve Productivity, Reduce Coding

If you're working with dynamic web applications that leverage a lot of client-side functionality and Ajax, you'll find that JsRender can significantly increase your productivity and eliminate a lot of code that you'd otherwise have to write. Although JsRender is still new (at the time this article was written, anyway), it's definitely worth looking into. Next, we'll switch topics and focus on HTML5's canvas element, which expands your options for rendering text, images, shapes, and more.

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish