Dynamic Content Using Html Templates

About 2-3 years ago, I was working on this project where I was receiving JSON data from the server then injecting the results into dynamically created content using the built-in JavaScript DOM methods.  It worked alright, but was a pane in the butt.  Lately, I came across idea using client side templates.  The concept of templates isn’t new, but I never thought to embed one in my HTML code.  What is even more cool, is that there are a few approaches to using the templates.  One such approach can be found here on Rick Strahl’s blog.  I saw this gentleman talk at 2009 DevConnections, really cool guy.  His approach is to clone some DOM segment and then update the element values where needed.  This works really well.  As I was searching I came across a second approach that knocked my socks off.  Below describes how this approach is used.  Currently I’m using the ASP.NET MVC pattern with my web pages but this could be done with WebForms, though there might be challenges with client IDs.  There are some helper methods from ASP.NET MCV within the html below, but they should be self explanatory.

Basics steps:

  1. Embed some hidden DOM inside a <script type=”text/html”> tags inside your page document.
  2. Make a JSON request or build an object which will be used as a data source.
  3. Using jQuery and this templating extension, you can inject the data from step 2 into the template.
  4. Insert this data injected template somewhere in your page.

So those are the basic steps, lets see some code.  I’m going to be using a html table as an example because that lends itself to the obvious add a row concept.

1. The html page with embedded template html snippet


<table id="OrderTable" width="100%" cellpadding="0" cellspacing="0">
<th />
<th />
<td><a href="”/Order/abc1234/Edit/1”">Edit</a></td>
<td> 1 </td>
<td>Some Product</td>
<td />

<script id="RowTemplate" type="text/html"> 1:
<tr id="${Tag}_Order">
<td><a href="<%= Url.Action("Edit")%>/${Tag}">Edit</a></td>
<td>${Price} </td>
<td><a id="${Tag}_Delete" href="<%= Url.Action("Delete")%>/${Tag}">Delete</a></td>

<div id="AddProduct">
<% using (Html.BeginForm("AddProduct", "Orders", FormMethod.Post))
{ %>
<div><input type="submit" value="Add Product" /></div>
<label>Product:</label><%= Html.DropDownList("products")%>
<label>Quantity:</label><input id="Quantity" name="Quantity" type="text" />
<% } %>

<script type="text/javascript">
$("#AddProduct form").submit(addProduct); // hijax product add form submission using jQuery

The key part of this html code is the template that is sitting inside the <script> block.  Notice there are some funny ${…} looking items in there.  This will be what our data is bound to, or in other words substituted for.  One thing I’m not diving into too much detail here, is that the events I wired up to the A links have been done in a “hijaxing” manor using jQuery
2.  Make a JSON request in order to get back some data in the form
Since our example form submission will be handled by client side JavaScript, lets look at a simple call.  Below shows the request using jQuery library which will get back a json object.   On successful call, we call the method “addProduct_succss” which will take care of our template data binding.

3 & 4.  Using the jQuery template extension inject the data and append to DOM

function addProduct_sucess(response)
// using template libarary, create template object using html snippet
var t = $.template($("#RowTemplate").html());
// response = { Tag:3, Quantity:2, Name:"Snuggy", Price:19.95 }, notice that property names match to template ${...} names.
var row = $(t.apply(response));
// appned this DOM row object to our table
$("#OrderTable tbody").append(row);
The jQuery template library will use the html snippet from the <script> block to create a template object.  Then the JSON that was returned will be applied to the template.  The key to remember here is that the JSON’s object properties, such as Quantity or Price, match to names in the template like ${Quantity} or ${Price}, respectively.

No comments: