Using the jTemplate jquery plugin with ajax and ASP.NET

Download source

A guy in work introduced me to jTemplates, a template engine plugin for jQuery. It allows you to easily bind JavaScript objects to a defined template and also has some other nifty features.

I’ve found jTemplates to be particularly good when using ajax to display any information quickly and easily.

First I’ll explain how to create a simple template to display data, and then how to use the foreach and cycle features.

Create a new web project, add a new ASMX web service and include the jQuery library as described in my previous post.  You’ll also need to download the jTemplates plugin from here and add a reference to it.

The web service will have two methods, GetCustomer which gets a single customer by ID, and GetCustomers which gets all customers. In the web service you may get your customer data in any way you like; from database, XML etc.  For simplicity I’ve created a list of generic customer objects in the constructor:

 

private List<object> _customers;

public MyService()
{
    _customers = new List<object>() {
        new { Forename = "Joe", Surname = "Stevens", DOB = "31/01/1983", Location = "Sydney" },
        new { Forename = "Tom", Surname = "Male", DOB = "02/02/1977", Location = "Brisbane" },
        new { Forename = "Emily", Surname = "Stevens", DOB = "14/01/1988", Location = "Melbourne" },
        new { Forename = "Leroy", Surname = "Phipps", DOB = "05/12/1982", Location = "Sydney" },
        new { Forename = "Saul", Surname = "Stevens", DOB = "02/08/1984", Location = "Perth" }
    };
}

My two web methods then look like this:

 

[WebMethod]
public object GetCustomer(int customerID)
{
    return _customers[customerID];
}

[WebMethod]
public List<object> GetCustomers()
{
    return _customers;
}

In my web form I want to get a customer’s details by selecting their name from a list. I have created a static dropdown list of names with ID’s that correspond to the position in my list. I have also added a button, and a DIV which will contain the contents of my template:

 

<asp:DropDownList ID="ddlCustomer" runat="server">
    <asp:ListItem Value="0">Joe</asp:ListItem>
    <asp:ListItem Value="1">Tom</asp:ListItem>
    <asp:ListItem Value="2">Emily</asp:ListItem>
    <asp:ListItem Value="3">Leroy</asp:ListItem>
    <asp:ListItem Value="4">Saul</asp:ListItem>
</asp:DropDownList>

<asp:Button ID="btnGetDetails" Text="Get Details" OnClientClick="CallService(); return false;" runat="server" />

<div id="placeholder" style="clear: both;"></div>

Clicking on the button calls a JavaScript function, CallService, which makes an ajax call to my web service passing the ID of the selected customer (if you arent familiar with jQuery and ajax take a look at my previous post):

 

<script type="text/javascript">
    function CallService() {
        $.ajax({
            type: "POST",
            url: "MyService.asmx/GetCustomer",
            data: "{customerID:" + $("#ddlCustomer").val() + "}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: Success,
            error: Error
        });
    }

    function Success(data, status) {
        $('#placeholder').setTemplateURL('JTemplates/Template.htm');
        $('#placeholder').processTemplate(data.d);
    }

    function Error(request, status, error) {
        $("#placeholder").html(request.statusText);
    }
</script>

One cool thing to note here is that I am returning an anonymous object from my web service, which will result in an XML response.  jQuery then converts this to JSON where it can then be used as a JavaScript object. You can tell your web service to return data as JSON rather than XML if required.

This means that in the Success callback ‘data.d’ is my customer data as a JavaScript object.  Before explaning what is happening in this function lets look at the template I will use.  Templates can just be a string, or can be a seperate file which I have done here.  This is how Template.html looks:

<table>
    <tbody>
        <tr>
            <th>
                Forename:
            </th>
            <td>
                {$T.Forename}
            </td>
        </tr>
        <tr>
            <th>
                Surname:
            </th>
            <td>
                {$T.Surname}
            </td>
        </tr>
        <tr>
            <th>
                DOB:
            </th>
            <td>
                {$T.DOB}
            </td>
        </tr>
        <tr>
            <th>
                Location:
            </th>
            <td>
                {$T.Location}
            </td>
        </tr>
    </tbody>
</table>

A very basic table with some extra jTemplates tags. $T is a jTemplate constant the represents the data. 

Going back to the Success method, I am using the setTemplateURL function on the container where I want my templated data to appear. You can also use setTemplate when you just want to use a string and not the contents of a file.

setTemplateURL can have three parameters, the first being the URL of the template. The second is any jTemplate parameters and the third is any options.  For more details on parameters and options check out the ‘Plugin to jQuery’ page on the jTemplates site.

Now the template has been set I can call processTemplate passing through the data I want to use, and the template will be processed and appear in the specified container. Here I am passing throught ‘data.d’ which is the data returned via the ajax call which will be single customer object.  For that reason I can use ‘$T.Forename’ in my template to display the forename. If I just passed ‘data’ to the template I could use ‘$T.d.Forename’.

If I now run the application, select a customer and click the button the customer’s details should appear on the page.

jtemplates_basic

Very clean and quick, but there are other features to make life easier.  Next I am going to use the foreach feature to display all customers in a table.

Create another page with a single button, container and the jQuery to call the GetCustomers method:

 

<head runat="server">
    <title></title>
    <script src="JavaScript/jquery.js" type="text/javascript"></script>
    <script src="JavaScript/jtemplates.js" type="text/javascript"></script>
    <script type="text/javascript">
        function CallService() {
            $.ajax({
                type: "POST",
                url: "MyService.asmx/GetCustomers",
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: Success,
                error: Error
            });
        }

        function Success(data, status) {
            $('#placeholder').setTemplateURL('JTemplates/ForEachTemplate.htm');
            $('#placeholder').processTemplate(data.d);
        }

        function Error(request, status, error) {
            $("#placeholder").html(request.statusText);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <input type="button" value="Get Customers" onclick="CallService();" />
            <div id="placeholder" style="clear: both;"></div>
        </div>
    </form>
</body>
</html>

Now create the ForEachTemplate.html that looks like this:

<table border="1" cellpadding="3" cellspacing="2">
    <thead>
        <tr>
            <th>
                Forename
            </th>
            <th>
                Surname
            </th>
            <th>
                DOB
            </th>
            <th>
                Location
            </th>
        </tr>
    </thead>
    <tbody>
        {#foreach $T as Customer}
            <tr>
                <td>
                    { $T.Customer.Forename }
                </td>
                <td>
                    { $T.Customer.Surname }
                </td>
                <td>
                    { $T.Customer.DOB }
                </td>
                <td>
                    { $T.Customer.Location }
                </td>
            </tr>
        {#/for}
    </tbody>
</table>

The key part here is {#foreach $T as Customer} {#/for}.  In this case $T in an array of customer objects, so I’m saying for each object as Customer do whatever. This then allows me to use $T.Customer.Forename to get the forename of the current object in the iteration.

Running this gives me a table containing all my customers:

jtemplates_foreach

This is great as I haven’t had to do any manual iterations of my array or anything, I’ve just passed my data to the template and it’s all handled for me.

Within a loop you can also use the cycle features. This allows you to set a number of values which is cycled through for each iteration. A perfect example for this is coloured alternate table rows. Within the for loop amend the tr tag as follows:

<tr bgcolor="{#cycle values=['#AFCFFF','#C0FFBF']}">

This means that for each iteration it will step through the values speficied giving this result:

jtemplates_foreach2

I hope this explains the basic use of jTemplates, I’m sure I’ll be using them more in the future and writing more posts on them!

Download source

Posted on by Joe in Ajax, ASP.NET, JavaScript, jQuery

17 Responses to Using the jTemplate jquery plugin with ajax and ASP.NET

  1. Sean

    Thanks for the clear and detailed explanation!

  2. Joe

    Hi Sean

    Glad you found it useful

    Joe

  3. David Sheardown

    Hi there… well I too am a native of old Blighty.. up Lincoln way, although been here in Oz for 12 years..

    Thanks for this! I was really trying to find an easy way to present data that is looped… ie.. foreach. I have a mechanism already that auto-maps database fields direct to HTML elements (i.e. single values), but again I needed something easy to present repeating items.

    Thanks very much.. for once a clear easy to follow example… that actually explains the whole process!

  4. Joe

    Hi David

    Glad you found it useful, it’s pretty cool.

    I also did a post where I did inline table editing using jTemplates. It’s not the greatest as it does an ajax update for every field changed but it shows how easy it can be.

    Only been here in Sydney for 12 months myself but can’t see myself heading back to the UK any time soon.

    Joe

  5. Jonathan

    Hi Joe

    Not sure if you could help but I figure why not ask and see what happens.

    I’ve used the templates for a while. I currently have a for loop within a for loop.

    I’m trying to access a value from the outer for loop within the inner for loop. Don’t suppose you know how to do this?

    Thanks
    Jon

  6. Joe

    Hi Jonathan

    Do you have an example of what you’re trying to achieve?

    From my example above I could extend the object created in the web service to have a list of skills for each customer. I could then do the following to iterate through each customer and their skills:

    <ul>
        {#foreach $T as Customer}
            <li>
                { $T.Customer.Forename } { $T.Customer.Surname }
                
                <ul>
                    {#foreach $T.Customer.Skills as Skill}
                        <li> { $T.Skill.Name } ({ $T.Customer.Location }) </li>
                    {#/for}
                </ul>
            </li>
        {#/for}
    </ul>
    
    

    In the inner for loop I an using the current iteration of the outer for loop to display the location with each skill (doesn’t really make sense to do this but just as an example).

    Is this what you mean?

    Joe

  7. Amy

    Thanks for the clear and detailed explanation!

  8. Bruce

    Thanks for the clear and detailed explanation!

  9. Vincent

    Wish I found that earlier, it’s so simple to create a AJAX templating system using jQuery and jTemplate with this explanation! No problem with de webservice returning XML when you know the trick of data.d!

    Thanks for the great post!

  10. Craig

    Another great post!

    Question: I need to hide/show a “delete” button in my template. In my json object returned I have ‘created_by_id’. If ‘created_by_id’ = a hidden value on my form (hdn_user_id) then I want to display the delete button. Otherwise I want to hide it.

    Can I do this w/ the template approach?

    thanks,
    Craig

  11. Joe

    Hey Craig

    Yeah that’s possible. I assume your hidden field is set outside of your jTemplate somewhere?

    Here is how I’d do it with my for loop example using the Forename, which you could easily adapt for your Id.

    Add a hidden field to my form (I’m using a hardcoded value)

    <input type="button" value="Get Customers" onclick="CallService();" />
    <input id="hidName" type="hidden" value="Emily" />
    <div id="placeholder" style="clear: both;"></div>
    

    Pass the value of this hidden field as a paramater to the template when I press the Get Customers button. Am using jQuery to get the value from the hidden field.

    $('#placeholder').setTemplateURL('JTemplates/ForEachTemplate.htm');
    $('#placeholder').setParam('hidName', $('#hidName').val());
    $('#placeholder').processTemplate(data.d);
    

    Use the #if jTemplate syntax in the jTemplate loop to check if the current name matches the parameter value and if so dispay the delete button

    {#if $T.Customer.Forename == $P.hidName }
        <td>
            <input type="button" value="Delete" />
        </td>
    {#else}
        <td></td>
    {#/if}
    

    Hope that helps

    Joe

  12. Paul Smith

    Joe,
    Thanks for your well explained and useful example! I’ll be able to put this (and another of your examples) to good use today.
    Paul

  13. celio

    nice and clean thanks!!!

  14. Joshy

    Hi ,

    Very thanks for the article.

    I have added button and text boxes to template and its working fine for me.But i am not getting the textbox value when i click on the button .Any help is greatly appreciated.
    Thanks,
    Joshy

  15. Joe

    Hi Joshy

    It’s hard to guess you problem without seeing your code, but as a pure guess, if you’re adding a textbox and a button inside a jTemplate you may need to use the jQuery.Live function to hook up the event handlers.

    Cheers
    Joe

  16. Nadav

    Very clear and helpful, as usual.

    Thank you.

  17. Faheem Ahmad

    Hi Joe,
    You simply put a great job.
    It is really simple to understand.
    Thanks dude.
    Keep it up.

Add a Comment