Simplifying jQuery tmpl interface
Anatoly Mironov
In one of my previous posts I showed a simple example how to retrieve data from a web service and render it with jQuery tmpl. To render this I used an id for a template and the container:
<script id="contactTemplate" type="text/html">
<div>
Name: {{= Name }} <br>
Phone: {{= Phone }}
</div>
</script>
<div id="contactContainer"></div>To render we select the template and container with jQuery selectors:
function onSuccess(data) {
$("#contactTemplate").tmpl(data.d.results).appendTo("#contactContainer");
}On a page with multiple templates and containers it can be a djungle of different ids you have to track. Johan Leino in his great blog post provides a better and simpler way to organize containers and templates. The solution is to extend jQuery selectors (like :even, :odd and more) and introduce two new: :template and :container. This code comes from Johan Leino:
(function ($, undefined) {
if ($ === undefined) {
throw "Dependency: jQuery is not defined. Please check javascript imports.";
}
$.extend($.expr\[':'\],
{
// :template(name)
template: function (current, index, metadata, elements) {
var arg = metadata\[3\],
d = $(current).data("template-for");
if (d === undefined) {
return false;
}
return arg ? arg === d : true;
},
// :container(name)
container: function (current, index, metadata, elements) {
var arg = metadata\[3\],
d = $(current).data("container-for");
if (d === undefined) {
return false;
}
return arg ? arg === d : true;
}
});
} (jQuery));Now we can forget the ids:
<script type="text/html" data-template-for="contacts">
<div>
Name: {{= Name }} <br>
Phone: {{= Phone }}
</div>
</script>
<div data-container-for="contacts"></div>Our onSuccess method will look like:
function onSuccess(data) {
var $container = $(":container(contacts)");
var $template = $(":template(contacts)");
$template.tmpl(data.d.results).appendTo($container);
}Much simpler, isn’t it? More possibilities to write more generic js code, like extracting “contacts” into a variable. One thing I would like to know how performance is in older IE browsers for custom jQuery selectors. See my post about nested templates where I implement these selectors.