After taking Stephen’s comment into account on my last post, I’ve decided to turn the code into a jQuery plugin. Being a boring, and very unimaginative, developer I decided to call it jqml (grab the source here). Compressed, the code is under 1/2KB.
The same method is used to generate element attributes that is used in jQuery (jQuery.fn.attr.call). While simple, this also provides a tremendous amount of flexibility and power. Events can be tied to elements as they are being created. Here’s an example:
1 2 3 4 5 6 7 8 9 | $.jqml(['nav', ['a', 'home page', { href: '/index.html', click: function(e) { // do stuff }}], ['a', 'about us', { href: '/about.html', click: function(e) { // do more stuff }}]]).prependTo('body'); |
One reason I like building the DOM in JavaScript using JSON is because of the ability to step through each part of the generation process. If an element or attribute isn’t coming out as expected, that code is easy to locate and troubleshoot. Another fun use case is to incorporate immediately executing anonymous functions. This way many elements can be created from a data set and a few lines of code:
1 2 3 4 5 6 7 8 9 10 11 | $.jqml(['table', (function() { var dataArray = ['tbody']; for (var i = 0; i < data.length; i++) { dataArray.push(['tr', ['td', data[i][0]], ['td', data[i][1]], ['td', data[i][2]] ]); } return dataArray; })()]).data(data).appendTo('#dataTable'); |
Above you’ll see the addition of .data(). This helps me track where specific data objects are being used. If AJAX is used to update that table’s data, via .data(), then a simple queue can be created to iterate over all elements that have been updated. No worries about passing arguments around, or polluting the global namespace. The data is where it’s needed.
When something like templating in JavaScript is necessary, using JSONML is my preferred method. Debugging has been easy, overall performance is great, and to me something just feels better.
Update: As you’ll see in the URL, the project was named jsql. But for some reason I named the repository jqml. So as to not break any links that currently exist out there I’ve kept the name as jqml and updated this post to match, but not changed the URL to this post.