Monday, October 4, 2010

jQuery Templates is now an Official jQuery Plugin

Update - October 2011: Please see recent post: "jQuery Templates and JsViews: The Roadmap" for current information on the jQuery Templates roadmap.

Joint announcements were made today by jQuery and Microsoft that jQuery has decided to make the jQuery Templates, Data Link, and Globalization plugins 'Official jQuery Plugins'.

See the following blog announcements for more details:
Of course I am very pleased by this news, which is the result of some active collaboration with members of the jQuery team.

What this means:

A new home for the plugins...

First thing it means, of course, is that the repositories where those plugins live have now moved to a new home. The code that was at GitHub under the http://github.com/nje/ project has been moved to the following repositories under the jQuery project:
The above projects constitute Beta releases of the plugins.

The previous repositories under the http://github.com/nje/ project may continue to exist, but if they do then it will be for exploratory work which may or may not find its way back into the official plugins in a later update.

New documentation on the jQuery API site...

Another very important consequence of this announcement is that from now on, documentation for the jQuery Templates plugin and for the jQuery Data Link plugin will be available on the jQuery API site at http://api.jquery.com.

From today, new documentation is available there, which is much more complete than the previous Wiki provided on our repository.
One goal I have with this blog entry is to give you an idea of how the new documentation for jQuery Templates is organized, and to provide a convenient set of links to the various topics. Each topic concerns either a method from the plugin API, or a template tag that you can use within your template markup to obtain some of the rich features that this plugin provides.

API documentation topics:

Template tag documentation topics:


I hope this new documentation will help you to take advantage of some of the rich features of jQuery Templates.

For extra help I'm expecting soon to provide some more blog entries that continue the series Introducing jQuery Templates...

61 comments:

  1. Is anybody working on MVC helper for this? It looks like there's no client and server implementation of templating, besides Mustache that is not available for .NET

    ReplyDelete
  2. Not yet, but we will definitely be working on server integration as we move forward.

    ReplyDelete
  3. @Artem, I think that a lot of us would prefer to simply avoid a lot of server-side integrations that tend to make things more complication in terms of control stacks anyhow.

    ReplyDelete
  4. Is there any way to load unobtrusive templates using the script "src" or similar attribute? (Perhaps even lazy loaded on-demand for pages with many templates.)

    I think it'd be really important if I'm going to use many templates or reuse templates between pages.

    ReplyDelete
  5. Yes, you can load template markup as strings, using any kind of AJAX call, or by loading a static script in which you define the string or strings. Then create a compiled template from the string, and render that.
    See http://api.jquery.com/jquery.template/.

    Certainly defining templates inline as the content of script blocks will not be optimal or appropriate in most real-life apps. For lazy loading, use an AJAX call to get the string.

    ReplyDelete
  6. getting an "object does not support property" error on
    $.tmpl(tmpl, dataObject)
    .appendTo("ul");

    Do I have the wrong jquery library includes?

    script type="text/javascript"
    src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js">
    /script>

    script src="~/Scripts/jquery.tmpl.js" type="text/javascript"></script

    ReplyDelete
  7. @Steve: Do you have a folder called Scripts, with jquery.tmpl.js in it? Get jquery.tmpl.js from http://github.com/jquery/jquery-tmpl.

    ReplyDelete
  8. Is there a way to format data like a date or money field? Something like this ${dateOfBirth,"{0:d}"} I think I read something about that somewhere but am unable to find the documentation on it.

    ReplyDelete
  9. Congrats!

    jquery-tmpl is a great great plugin, the most useful one for Rich Web Application. Thanks a lot for this great work

    ReplyDelete
  10. @MexMax: ${foo} allows foo to be a JavaScript expression. So you can, for example, write your own formatting function, as in ${format(dataOfBirth, someParameter)} or call an existing formatting function. See http://www.borismoore.com/2010/09/introducing-jquery-templates-1-first.html and http://api.jquery.com/template-tag-equal for examples of calling functions. Also the Movie sample on github which has ${formatDate(date)}.

    ReplyDelete
  11. Hi Boris,
    I need trigger and handle an event for each template item rendered. How do I do it?

    Daniel Hoisel

    ReplyDelete
  12. @Daniel: If you take a look at the demos/movies/PagesTmplPlus/movies2.html and demos/movies/PagesTmplPlus/movies3.html samples, you'll see one possible approach. The jquery.tmplPlus.js script is an additional plugin which adds more features including a 'rendered' event.

    ReplyDelete
  13. With this jQuery is dived right into the battle wth Ajax.org. One with very mature and optimized frontend, and the other with Adobe Flex-like data binding and remote capabilities.

    ReplyDelete
  14. I see you have to provide the name of the target for datalinking but could you use a selector as well? for example:
    var target = $("input[name = 'txtName']");
    $(this).link(contact, {
    Name: target
    });

    ReplyDelete
  15. The moment I posted my question I got an idea on how to do it. This works:
    var target = $("input[name = 'txtName']");
    $(this).link(contact, {
    Name: target.attr('Name')
    });

    ReplyDelete
  16. Should we expect to see declarative linking with templates soon, especially with support for automatic efficient updating of nested templates?

    We have been using MSAJAX Client Templating for a year now with amazing success (with our own open source alternative to DataContext, http://exoweb.codeplex.com/). We are close to releasing products using these technologies to our customers but also know that we must transition to jQuery templating and data linking when the time is right.

    It seems without declarative linking support in templates, this leap would be very difficult, but we are very eager to try!

    Also, we appreciated the ability with client templates the ability to extend the declarative markup, so please if possible make the link template command extensible.

    Thanks for working together the JavaScript community to create something great!

    ReplyDelete
  17. @Jamie: Yes declarative data linking within jQuery Templates is in the works. I think we will need to iterate first on the data link APIs and then move towards declarative integration with templates, so it may take a little while...
    You can already provide your own template tags, but it needs more documentation and tutorials, which I hope to get to at some point. I think the declarative linking will be quite extensible too.

    ReplyDelete
  18. Great work, we're seeing some great possibilities with tmpl! Really excited!

    Just out of curiosity, is there a data limit built in to TMPL? I've done a couple of extreme case scenarios with very large datasets, and have managed to cause TMPL to fail (but not jQuery). Don't actually plan on doing anything like that in real life, but it would be nice to know at what point things start breaking down.

    ReplyDelete
  19. Thank's a lot! It is brilliant!!!!
    Maybe the ajax sample could also includes example of item extension using function...

    $( "#movieTemplate").tmpl(movies,{age: function(){return new Date()).getFullYear()-this.data.ReleaseYear;}}).appendTo( "#movieList" );

    ReplyDelete
  20. What is the best way to get help or ask questions related to this plugin? Your blog or the jQuery forum?

    ReplyDelete
  21. @Rob: There is no data limit built in to the plugin. I'd be interested in the nature of the failure you are hitting. There can be some browser-specific limits, such as stack depth. But we are planning some changes in the implementation which may improve some perf and related characteristics...

    @Marco: Thanks, yes, I'll bear in mind adding samples of methods on the options map (hence $item.myMethod()).

    @Matt: In principle the jQuery forum is the right place. I may not (unfortunately) always be very prompt on replying to questions here. But the plugins are both in beta release, so the community (and hence the forum) are only slowly getting up to speed, and of course APIs may change before final release versions...

    ReplyDelete
  22. Hi Boris,
    How do I check to see if an template already exists (I'm remotely loading the template and appends that to the body, following this article: http://encosia.com/2010/12/02/jquery-templates-composite-rendering-and-remote-loading/) I've tried this code (pseudo code here)

    if($.template('#templateName'))
    {
    // Skip getting the template again, just bind data
    $('#templateName').tmpl(data).appendTo('#blogPosts');
    } else {
    // Get the template, then bind data.
    }

    That if statement always return me an "templateName" object but the template is not there yet. Any suggestions? And while we are on this topic, how do I remove an template that's already appended to the body of my html? Thank you very much.

    ReplyDelete
  23. @Xuanvuz
    If you are loading the template into to DOM as a script element, then you need to test for the presence of that element. But if you are using named templates, see http://api.jquery.com/jquery.template/:
    - To determine if a string "someName" is the name of a named template, test whether $.template["someName"] is defined.
    - To remove a previously created named template, use delete $.template["someName"];

    ReplyDelete
  24. Hi Boris,

    Thanks for the suggestions, I'm pretty new to jQuery so I ***think*** that I was loading the template into DOM, using something like this seems to work:

    if($('#templateName').is('*'))... ....

    Not sure if it's the best way, but it's working :)

    Thanks again.

    ReplyDelete
  25. Hi Boris, one more question: how do I replace a content (inside a div) with the newly loaded template? All the examples that see are using somethign like this:

    $('#templateame').tmpl(data).appendTo('#divId');

    I've tried $('#templateame').tmpl(data).text('#divId'); but it didn't work. Thanks.

    ReplyDelete
  26. appendTo is already inserting into the div. You can use .appendTo, .prependTo, .insertAfter or .insertBefore. The first two add content. Use $("#divId").empty() first if you want to replace existing content. You can combine the two in one statement, as:

    $('#templateame').tmpl(data).appendTo($('#divId').empty());

    See http://api.jquery.com/tmpl/ and other linked topics.

    ReplyDelete
  27. Thanks, exactly what I'm looking for.

    ReplyDelete
  28. Hello Boris,

    I'm rendering data from server into a div element and using jquery ui accordion widget to group these elements, but the accordion widget is not working. Is there a way to fire jquery accordion after the template is redered?

    Thanks

    ReplyDelete
  29. @Jhonny
    You can render the template, and then attach the accordion plugin. See samples such as the various versions of the Movies sample under https://github.com/jquery/jquery-tmpl/tree/master/demos/movies, which attaches a jQueryUI datepicker to the rendered items.

    ReplyDelete
  30. Regarding DataLink in the examples it uses an alert to show the update is it possible to somehow attach an event/callback to trigger , for example to issue an alert, when the data is changed?

    ReplyDelete
  31. Nice work. I've evaluated several client side template libraries, and this one is the best.

    ReplyDelete
  32. Hi Boris, how can I do a "live" event with template? I have a template that is loaded via a live event, when that template (a post template that also contains a comment template) is loaded, then I load a comment form. When a comment is submitted, I have jQuery to find the comment template and insert the new comment, but seems like it couldn't find the comment template. My guess is that the post template was loaded after the page load, so it couldn't find the comment template id. Thanks.

    ReplyDelete
  33. Hey Boris,
    first I'd like to thank you for that great plugin.

    I still have a question: Is it possible to escape the expression ${foo} so that it will stay ${foo} after parsing? I trief ${dollar}{foo} and defined dollar to be '$' but that didn't work quite well.

    ReplyDelete
  34. Hi Boris,

    Great work !!! When can we expect the stable release, do you guys have a roadmap for this? Like a concrete date?

    Thanks

    ReplyDelete
  35. @andicrook:
    Yes there is a "changeField" event that you can bind to. (Use the latest build of datalink, that works with jQuery 1.5).

    @xuanvuz:
    Difficult to answer, since I don't have the detail of how your comment template is being loaded, and how you are getting jQuery to look for it. There are several examples under the demos folder on GitHub, or on the jQuery API site which use .delegate or .live. But for doing a $(selector) search, you must make sure to call that after DOM ready, or after inserting the comment template.

    @B-Ranger:
    One way to render out ${foo} in the HTML would be to use an HTML entity for one of the characters – for example: $&#123;bar}. Another - if all you care about is what it looks like to the user - is break the string using an HTML element somewhere, such as: $<span></span>{foo} ${bar}

    @todorov:
    We’ll be bringing out an updated roadmap soon. In fact I also hope to put out a blog soon saying what is in the pipeline from my point of view. (I’ve been very busy – which has also made me much less active on this blog than I would have liked to be).
    I don’t have a date for V1 release yet, but I have been working hard on Beta2 versions for both the templates and the datalink plugins, and the expectation for those is sometime in April. I also plan to put my current investigative code for the Beta2s onto GitHub soon.

    ReplyDelete
  36. Hi Boris,
    first, i want to thank you for this awesome plugin.

    i have some question about it though.

    first, is there any way to do partial template update?

    lets say i have this as template

    <div>
    <span>${HEADER}</span>
    <div>${CONTENT}</div>
    </div>

    now i need to only update the <span> tag, i don't want the <div> of content get re-rendered because some changes are made there.


    second, using the template tag {{tmpl}}, how can i render data from nested template?

    here's the case

    <div>
    {{tmpl "<span></span>"}}
    <div>${CONTENT}<div>
    <div>

    i want to achieve the same result as the first template i described earlier
    using {{tmpl}} tag, any clue?


    thanks alot

    ReplyDelete
  37. Yes, you can update just the content of a nested template. There is even an .update() method on the tmplItem, to make scenario easy. See for example the movies sample, which does it in several places: PagesCore/movies.html. For updating the ${HEADER} content without using template, you should take a look at data linking: github.com/jquery/jquery-datalink.

    ReplyDelete
  38. Hi there...

    I recently got bitten by trying to use the variable "Text" in one of my templates, as in ${Text}. I eventually figured out that it was calling the native global browser function Text().

    Is there any particular reason why ${Text} and ${Text()} both try to call Text()? I would have thought that you'd require the user to add the parenthesis if the user intended to call a function.

    Cheers,

    Matt

    ReplyDelete
  39. @Matt:
    Yes, it is by design that if Text is of type function, ${Text} will call the function. It was designed that way for consistency with similar patterns in jQuery. For example if you do $( element ).attr( "Title", foo ) and foo is a function, then the attribute will be set to the value returned by foo.
    But that said, I am not a fan of this design, in the case of expression evaluation within templates, and I am expecting that in Beta2 onwards, the parens will be required if you want ${Text()}to call the function... But the fact remains that if you don't have a field called Text on your data, it will 'see' any globally defined variable of the same name, and use that instead... So you will still need to be aware of possible collisions, if you have fields which are not always defined on the data...

    ReplyDelete
  40. I'm having an issue where I'm unable to display the value of a key that contains a colon.

    For example, my JSON string contains keys that all have a colon:

    i.e. { "autn:term" : "value" }

    I've verified and tested that the JSON string is good/valid, so no issues there. However, when I attempt to spit out the content onto my page, this does not work:

    ${autn:term}

    I've tried escaping it in various ways, all have been unsuccessful. The only way I could get it to work was by renaming the key value to NOT have a colon. Since this feed is coming from a third-party, I do not have the luxury of changing this, so I'll need to find a solution with what I've got.

    Any ideas?

    ReplyDelete
  41. @Mike: ${$data["autn:term"]}, or ${$data['autn:term']} should work.

    ReplyDelete
  42. When is this projected to move out of Beta? I'd like to use it, but don't want to commit before it's at least v1.0. I see you've not contributed to it on github for over 2 months now. Has development stalled?

    ReplyDelete
  43. Hi Boris,

    Are jquery.templates already in the source code of 1.6? And if not - when could we expect that? (and could we?)

    Thanks

    ReplyDelete
  44. As I read in the jQuery Blog http://blog.jquery.com/2011/04/16/official-plugins-a-change-in-the-roadmap/ the template plugin was adopted by the jQuery UI team.

    ReplyDelete
  45. @thgsb, @Oleg and @HKL: Yes, the template plugin is now owned by the jQuery UI team. Ongoing work on jQuery Templates is happening at https://github.com/BorisMoore/jsrender and https://github.com/BorisMoore/jsviews.

    The jQuery UI team have decided that development on https://github.com/jquery/jquery-tmpl will not continue. They will instead use a new jQuery templates implementation which will be JsRender (or based closely on JsRender). They may also use the integrated templates and data-linking provided by JsViews.

    See the upcoming presentation at the jQuery Conference: http://events.jquery.org/2011/boston/schedule/.

    I'm not sure yet what the detailed roadmap is - when JsRender and JsViews will move to Beta. Hopefully we will be able to define that soon...

    ReplyDelete
  46. verrrrry disappointing to hear that jQuery Templates is not being further worked on. I think this is an excellent, much-needed, part of the jQuery framework. Without templating, we're just using string concatenation and loops to build the presentation from JSON data.

    I used the jQuery template plugin for some work here at my job. My manager told me to remove it because it's Beta, and not supported. Now I have to spend at least a day manually building the DOM with jQuery. It is a shame.

    ReplyDelete
  47. @Lynn: yes, it is unfortunate. But on the plus side, I think JsRender will be better still. You could port right now to JsRender of course. I know it has the same issue for you of being (pre) Beta software, but it should move quite fast now towards a release version (unlike jQuery Templates) and I think the API is fairly close to stable already...

    ReplyDelete
  48. I want to port my code to JsRender , how can I apply code like $(this).tmplItem() ...with JsRender ?

    ReplyDelete
  49. @lujan99: See examples here: http://borismoore.github.com/jsviews/demos/index.html. $(this).tmplItem() corresponds to $(this).view() (or $.view(this)...)

    ReplyDelete
  50. @lujan99: Note that jquery.tmpl.js functionality is factored (in the ongoing implementation) into JsRender and JsViews. The DOM integration, data linking and view context features are provided by JsViews, which is a layer on top of the JsRender template rendering implementation. A view in JsViews is effectively equivalent to a template item in jquery.tmpl.js.

    ReplyDelete
  51. Hello Boris,

    I know that the tmpl library is being phased out, but I have one question for you...

    I have a website that makes extensive use of your plugin and it works great everywhere, except any VA hospital. I've been able to trace it down to the line that does the .appendTo(template stuff):

    $("#tmpl-Comment").tmpl(results).appendTo("#divComments");

    I can see in the response object that the data does come back. It works in all browsers in every other location, but it doesn't work in IE, Chrome or FF from a VA hospital (this happens at one in San Diego and one in Philadelphia).

    Any ideas?

    ReplyDelete
  52. @Jon Wear: No idea, but it sounds like it is not an issue with the templates themselves. If the data is there, then either the data returned is different when the request is going from that location, or the browser settings are different.

    ReplyDelete
  53. The same thing happens with the newer JSRender and JSView. This is baffling. I'm wondering if the script type="text/x-jquery-tmpl" is banned from VA hospital locations (They all share the same network setup). I'm starting to wonder if I should have the DOM built elsewhere and the pushed back into the page so it can be a regular jquery call. Hate to do that kind of a hack just for one location.

    ReplyDelete
  54. Got it fixed. The problem was that the network at the VA did not like non-encrypted ajax requests that employed a non standard script type for the javascript block. Once we put SSL on the whole site, the problem went away. I'm guessing some here, but putting the whole site on SSL fixed it.

    ReplyDelete
  55. Hello,

    Why the documentation for the jQuery Templates plugin is not available on the jQuery API site at http://api.jquery.com any more?

    ReplyDelete
  56. @Natalya: jQuery Templates is now managed by the jQuery UI team, and they have decided not to support it any more. For some background on this, see: jQuery Templates and JsViews: The Roadmap". Recently they decided to also remove the documentation from the jQuery API site (though a lot of people are of course using it).

    I am no longer working on jQuery Templates, but rather on JsRender and JsViews, which are in fact the next-generation of jQuery Templates.

    There have been a number of requests to jQuery to add the jQuery Templates documentation back in to the API site - or at least on the readme. See github.com/jquery/jquery-tmpl/issues/173. If you want to join in making that request, you could get in contact with the jQuery UI team, and/or add comments to that issue.

    ReplyDelete
  57. I am using jquery loadTemplate for single page application. Facing issue with radio button and checkbox grouping. Only one checkbox/redio button is getting checked. All others of the same group are getting clicked but not checked at all.

    Any suggestion highly appreciated.

    Thanks

    ReplyDelete
    Replies
    1. jQuery loadTemplate is nothing to do with jQuery Templates. jQuery Templates are here: https://github.com/BorisMoore/jquery-tmpl. But the project is no longer maintained, and is superseded by JsRender (for templates) and JsViews (for templates with data-binding, single page applications etc.) See http://www.jsviews.com/#jsrender, http://www.jsviews.com/#jsviews.

      Delete
  58. Hi I have a scenario where I have to use my variable in an empty tmpl. Your solution of adding external variable works for tmpl where I have a list of data but not for above scenario. Do you have a way in which i can read a variable.
    ('#tmpl').tmpl(list,{
    index:var}); is working
    ('#tmpl').tmpl({
    index:var}); is not working

    ReplyDelete
    Replies
    1. If by empty template, you mean you want to render the template, but without passing data, You can simply pass {} as first parameter:
      ('#tmpl').tmpl({}, {index:var}).
      That said, I would encourage you to switch to JsRender which is much more complete, and is actively maintained. jQuery Templates is no longer maintained/supported so I will be unlikely to be able to reply to specific questions of this kind, moving forward...

      Delete