In an attempt to avoid repetition, I am trying to use mustache for templating on both the server and client side. I have a template something like the following:
<html>
<head>...</head>
<body>
<table>
<tbody id="#this">
{{rows}}
<tr>{{row}}<tr>
{{/rows}}
</tbody>
</table>
</body>
</html>
This works great for my server side templating. On the client side however, I’m having some trouble. I can successfully load the template using ajax, but I don’t need the whole thing to update the rows of the table.
$(function () {
var template;
$.ajax('templates/thetemplate.mustache', {
success : function (data) {
template = $('#this', data).html();
},
dataType : 'html'
});
});
When I use the above jQuery to get at the contents of the #this element however, the {{rows}} and {{/rows}} lines are stripped from the result, while the <tr>{{row}}</tr> between them are returned successfully. How can I get the entire contents?
I’ve tried $('#this', data).contents(); which gives the same results, and $('#this', data).val(); which returns an empty string. Using $(data).find('#this') instead has the same three results. I’ve also tried setting the dataType of the ajax call to 'text' with no apparent effect.
I realize that I could probably accomplish what I want (not duplicating parts of my templates for client vs server side use) by using partials, and that it would have the added bonus of avoiding the transfer of more template than I actually need to the client just to have it thrown away, but that doesn’t answer my question. (tho slick solutions are appreciated)
Thanks
The problem has already occurred at
$('#this', data), which sendsdatavia the browser’s HTML parser to convert it to a DOM fragment. Being error tolerant, the HTML parser does what it can with the template but it’s not what you want because the template itself is not valid HTML. For this reason$('#this', data).anythingYouLike()or$(data).anythingYouLike()will not work.As the HTML must be valid before submitting to the browser’s HTML parser, there’s no other choice than to perform Mustache rendering before submitting valid HTML to the browser with a
$(renderedHTML)expression.With that constraint in mind, there are two realistic options regarding the order of events :
datato just<tbody ...>...</tbody>(witha regular expression), then Mustache render, then
$tbody = $(renderedHTML).datain full, then$tbody = $(renderedHTML).find('tbody')As far as I’m aware, either approach will work. In both cases, you end up with a jQuery object,
$tbody, containing a populated tbody node, which can then be inserted into the DOM with$tbody.appendTo($('#myTable'))or similar.