Quick and Dirty Web Data-Binding

Comments 0

Share to social media

Web developers seem to either love immersing themselves in JavaScript, or merely tolerate it like a bitter-tasting medicine. Developers in the former camp will probably use AngularJS to build their web pages; typically within some sort of Single-Page Application (SPA) model. The latter, more cautious, type of web developer is more likely to want the smallest and simplest way of using HTML and JavaScript to generate markup dynamically.

An AngularJS application is built on top of a HTML template and uses directives to instruct the runtime on how to modify the DOM. A directive usually takes the form of an HTML attribute. No AngularJS directives are directly processed by the host browser but they contribute to changing the content of the DOM. Directives can be quite complex and include chainable formatters and filters. AngularJS just works, and the way that it adds new elements to existing HTML is relatively easy to learn. ‘Easy to learn’, though, doesn’t mean ‘no effort and no change of mindset required’. So the question changes and becomes: “what if all you need to do dynamically is quick and dirty HTML data binding?”

Those Web Developers who are less enamored with JavaScript are for the most part former ASP.NET Web Forms developers who are accustomed to do most of the work on the server side. These developers can survive a bit of JavaScript but bridle at having to resort to a large, though modular, framework such as AngularJS when all they require is an easy way to manipulate HTML templates and fill parts in by means of a few JSON properties. In this article, I’ll just bring to your attention a very small yet effective JavaScript library that merely manipulates HTML templates. In less than 8K of minified script, Mustache.JS will let you create markup dynamically out of predefined HTML templates padded with data placeholders. Needless to say, Mustache.JS, as well as a bunch of equivalent libraries, is very good at doing templates but that’s all it can do. If you expect more from a JavaScript framework, then you might want to hook up with more sophisticated frameworks such as Knockout.JS or the aforementioned AngularJS.

Getting Familiar with Mustache.JS

Mustache.JS is considered to be the core library of JavaScript templates because it’s often incorporated within other more advanced projects. You can get it from the following Github address: http://github.com/janl/mustache.js. It is most commonly used by putting it on your own web site and referencing it from there. The mechanics of Mustache.JS is fairly simple: you need a HTML template, a fragment of the DOM to update and some JSON data. Both the HTML template and JSON data can be taken from anywhere, in the sense that both can live within the boundaries of the host page or can be downloaded from a given endpoint. Before getting into the details of the Mustache.JS micro-framework, let me share a few thoughts about the reasons that led me to look into the smallest, simplest but effective piece of HTML and JavaScript to generate markup dynamically.

Working in the context of a custom Content Management System, I faced having to generate many customer-specific screens repeatedly on top of nearly the same data. The overall application is an ASP.NET MVC application and the views to be rendered are for the most part Razor views. A Razor view is a template file processed on the server that requires a full page refresh to render, unless you resort to some tricks like the multiple partial view results that I discussed in another article on Simple-Talk. (See Revisiting Partial View Rendering in ASP.NET MVC.) Sometimes, you just want some quick way to grab data and turn it into nice HTML. Mustache.JS, much more than blockbusters like Knockout.JS and AngularJS, does this work quickly and effectively and with minimal overhead.

Injecting HTML vs. Injecting JSON

In a comment to my aforementioned article on multiple partial view results, a user raised the excellent point that injecting HTML in an existing page is quite a quick operation because all that the browser has to do is to update the DOM via the innerHTML property. That’s probably just the fastest operation a browser can do when it comes to rendering content. On the other hand, HTML is still larger content to download than any JSON. The reason is fairly obvious: HTML is about data and layout whereas JSON is only about data plus a minimum extra amount to format plain content into downloadable content. Speaking of JSON it should be noted that a serialized property that holds NULL takes up four bytes instead of zero in JSON. Similarly, the longer is the name of the property, the more time it takes to download. And then there is the overhead of URLs that sometimes may be embedded in data. All this suggests that the reason that JSON is better than HTML is not because JSON is necessarily compact. The choices of using partial rendering via HTML, or downloading JSON are both good, and depend on the type of pages you deal with. When you download JSON, though, you must solve the additional problem of integrating this data in the existing DOM. This is where Mustache.JS or other analogous frameworks fits in.

Mustache.JS in Action

Imagine you have a page in the figure. It’s a rather common page with a sidebar where the user can choose an option and a details view that opens up aside. Typically, the content in the sidebar can be paged and it’s not usually a great idea to pack all the possible child views in a single download. If you keep the amount downloaded to the bare minimum for each request, then you have the problem of drilling down in the details when the user clicks on any of the sidebar items.

2137-1-30efb779-5343-4f9c-85f6-b4dadbcf2

The behavior of the sample page is simple: the user clicks the button for a given country and gets some details about the country such as capital, telephone prefix, flag and a map. It’s not much information to download and with jQuery and its configuration of the browser’s built-in cache, the user won’t experience delays or cumbersome full page refreshes. In the context of a CMS system, though, it often happens that any customer or user wants to have a customized template. It can be a lot of work to set up a server-side routing system that picks up the configured Razor view and returns plain HTML. Occasionally, this is just what you need but at other times it is just plain overkill to use server-side HTML. In software, simplicity always wins.

So let’s assume you also have some code in place to retrieve ‘details’ data for the selected countries. For the purposes of this demo, I’ll use the geognos.com service and the country information it returns. (See http://www.geognos.com/api.) Here’s some markup to help you figure out the scenario.

The DIV with the ID of “details” is the area where we’re going to insert any dynamically computed HTML. The sidebar that contains the list of countries may look like below:

When the user clicks the button the following JavaScript runs:

The method invoked in the script is just a server proxy to avoid JSONP cross-site troubles. The done function merely receives the country information to merge with some HTML template handled by Mustache.JS.

Mustache.JS requires a HTML template to parse. A HTML template is a plain string and can be built any appropriate way. It can, for example, be constructed by programmatic string composition or it can be read from the same HTML page. It could even be downloaded from some external or internal web API. In the CMS project that I’m working on these days, we create a bunch of custom pages for every customer. Each page has its own template that is statically defined in a SCRIPT tag. It’s easy to find and easy to modify in case of trouble. The only important thing to keep in mind is that you need to assign a nonstandard value to the type attribute of the SCRIPT tag. The reason for this is to force the browser to ignore the content when it parses the page source.

The type attribute can be any string that makes sense to you or that meets the requirements of the library (but not Mustache.JS). The Mustache.JS template uses the familiar {{ … }} syntax to refer to bindable expressions. The expression is evaluated starting from the data object passed to the Mustache parser. In the simplest case, the expression is just the path to a property. Here’s the JavaScript code that loads the Mustache.JS templates in the page:

You can use jQuery to read the HTML within an element as a string. As an alternative, the template can be created programmatically or downloaded. It’s interesting to notice the role of the parse method. It’s an optional method that doesn’t add up to any special flavor of behavior. However, it tells the Mustache.JS runtime to cache the template for future calls. In this way future rendering of the same template will turn out to be faster. Here’s the code that renders out both templates in the page.

Rendering a template is as easy as calling the render method on the Mustache root object. The method takes two parameters: one is the template as a string and the other is the JSON object that provides that data to merge. The sample site returns country information in the form of

In turn, the CountryDetails class is defined as below. This explains the expressions found earlier in the Mustache templates.

With a bit of Bootstrap to style the view, you can render something as in the figure.

2137-22904870-feef-417d-b6d7-953f12abc84

Switching from one country to the next takes only a few moments and a call to the server is made to download only a bunch of bytes which will be arranged into HTML on the client.

More on Mustache.JS

Mustache.JS expressions are treated as plain data placeholders and the runtime merely replaces the placeholders with actual data. In the light of this, the following complex expression just completes the URL of a PNG image. Basic expressions in Mustache.JS are referred to as “variables”.

Mustache.JS is a very basic library but in no way is it limited to plain variables. An interesting feature is Mustache.JS sections. A section is defined as below. The symbol # identifies the start of a section and the / symbol closes it.

The content displayed within a section depends on the value of the root expression. If the expression evaluates to null or undefined then the content is simply not rendered. If the expression is an array then the content is rendered once for each item in the array. To refer to the direct object in the array you use a dot-based syntax {{.}}, as below:

If the array contains objects instead of plain values you use expressions to navigate to the actual content.

If the object contains methods, you can use them as well. It’s plain JavaScript in the end. Finally, a very handy feature that comes out of the box with Mustache.JS is the possibility of expressing an alternate template for when the bound collection is empty.

The ^ symbol refers to an inverted section and it is rendered only if the value of that section’s root-the countries in the example-is null or undefined.

Summary

Web data binding is a fairly common operation in web pages. Sometimes you can perform it entirely on the server but occasionally it’s good to have a client-side engine that can do templating. For data binding, you have popular choices such as KnockoutJS and AngularJS, but also a very basic engine like Mustache.JS that does its job in 8K of minified JavaScript. In this regard, it represents an excellent choice, especially for mobile sites. In this article, I covered the very minimum you need to know to start using Mustache. The full reference, however, is available at http://github.com/janl/mustache.js.

Load comments

About the author

Dino Esposito

See Profile

Dino Esposito has authored more than 20 books and 1,000 articles in his 25-year career. Author of “The Sabbatical Break,” a theatrical-style show, Esposito is busy writing software for a greener world as the digital strategist at BaxEnergy. Follow him on Twitter: @despos.

Dino Esposito's contributions