So we can build clean, responsive user interfaces with the MVC design pattern using client-side XSLT. Nice. Now let’s imagine something much better.
What if we could take plain Javascript objects as our model (perhaps transferred to/from the server in JSON form), and translate them into a HTML user-interface using a clean, fast, and familiar templating language? A language as familiar as… Javascript itself?
Perhaps we could even set up a simple framework that would let us route events in the UI (such as button presses) into our own Javascript handler functions, and then after we update the model, it automatically refreshes the UI…
Introducing jMVCIt’s really simple. It’s a templating engine written in less than 100 lines of Javascript (excluding comments). jMVC provides a templating language which is actually Javascript, so you don’t have to learn any new syntax.
It uses ASP-style <% code %> syntax, like this:
Here are some items from an array: <ul> <% for(var i = 0; i < model.items.length; i++) { %> <li><%= model.items[i].name %></li> <% } %> </ul>
There are only three syntactical constructs (plus everything you can normally do in Javascript):
<% if(model.cart.count > 0) { %> You have some stuff in your cart. <% } else { %> You have nothing in your cart. <% } %>
Hello <%= model.name %>, the time is <%= new Date() %>.
<input type="button" value="Delete" onclick="<%* function(currentItem) { deleteItem(currentItem) } %>" />
Simple, eh?
Notice the last one – closures – because this is the only bit that isn’t completely obvious. While code blocks and evaluations run at template-processing time, the closures run later, for example when the user clicks a button or link. The magic <%</span> function() { ..code..* } %> syntax (notice the asterisk) means, “Here’s a block of code, don’t run it now, just register it to this event handler”.
They are closures because you can reference any variable from your model that’s in scope at the time. This is really helpful when your UI contains lists with buttons next to each item, as you can pass in the relevant item as a parameter to the event handler.
After your closure runs (during which you’ll probably update the model), the UI is automatically refreshed – that’s one less thing to think about.
Online demosJust to prove it works, here are two demos. They will launch in a new window. They’re deliberately kept simple to demonstrate the method, so don’t expect fancy graphics.
Simple list-editing demo – download the source code to see how easy this is.
Recursive controls demo – this replicates the demo given for the XSLT method, but shows how jMVC is much more streamlined. Source code
Integrating with ASP.NET… or another server-side language is pretty easy, because as you will see from the second demo, the JSON model can be kept in a hidden INPUT field or TEXTAREA so it gets posted back to the server. I haven’t explained this in more detail but it is simple, and I will do so if needed.
###
DownloadYou can download the full source code version here (~5kb).
There’s also a minified version (i.e. comments & blanks removed) here (~2kb).
At the moment there isn’t any documentation beyond this blog post, the source code, and the demos. It’s under 100 lines of code long, you can probably work it out. Nonetheless, if there is interest, I will write more documentation/tutorials.
LicenseYou’re free to use and include this in commercial and non-commercial projects, including making your own modifications. You only have to retain the original copyright notice and link in the source code.
Note: it uses (and includes) the json.js library, placed into the public domain by json.org.
AlternativesThis is not a completely new idea. Although jMVC provides some unique benefits, there are loads of related projects and frameworks, each with their own advantages. Most are more developed than jMVC.
I like jMVC because it’s so small and simple. The main other benefits, compared to most Javascript templating systems, are:
Here are some alternatives you might like to check out:
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4