Sunday, June 8, 2008

JsonTV - JsonML concept to create TreeView components

For those that do not know JsonML, this is a little summary.
JsonML aim is to use JSON to transport layouts, instead of simple data.
Unfortunately, for this purpose the size of the code could be even bigger than regular layout, considering that with a good usage of classes, internal styles, as attributes, are often superfluous.
At the same time, there are still several problems with DOM, for its not standard nature, thanks to those browsers that do not respect W3 or generic predefined guidelines.
For these reasons, and probably others, JsonML has not been widely adopted, as is for his daddy JSON.

An alternative purpose, based on both same concept and grammar


A daily common task in web development, is menu, files and directories, or trees creation, that allow us, as users, to organize data in a better, friendly, and easy to manage, way.
Removing some intermediate step, and thinking about standard data presentation, with useful information and nothing else, it is possible to use the same JsonML grammar to create automatically a DOM based tree.
The schema could be transformed in this way:

element
= '[' name ',' attributes ',' element-list ']'
| '[' name ',' attributes ']'
| '[' name ',' element-list ']'
| '[' name ']'
| json-string
;
name
= json-string
;
attributes
= '{' attribute-list '}'
| '{' '}'
;
attribute-list
= attribute ',' attribute-list
| attribute
;
attribute
= attribute-name ':' attribute-value
;
attribute-name
= json-string
;
attribute-value
= json-string
;
element-list
= element ',' element-list
| element
;

As you can observe, the only difference is with name, instead of tag-name.
The element-list, if present, will be the nested list of informations inside a branch, while name will be the real name of that branch, or leaf, if no element-list is present inside.

The attribute-list will be a dedicated object that will contain, if present, every information we need for that leaf, or branch.
At this point, with a simple piece of code like this one, is possible to create a menu:

["root",
["demo.txt", {size:12345, date:"2008/06/07"}],
["temp",
["file1.tmp"],
["file2.tmp"],
["file3.tmp"]
],
["sound.wav", {size:567, date:"2008/05/07"}]
]

Above code will create automatically a list like this one:

  • root

    • demo.txt

    • temp

      • file1.tmp

      • file2.tmp

      • file3.tmp



    • sound.wav




Every leaf, or branch, will contain at the same time passed information, as object.
In this way, as I wrote before, we are not sending an xhtml or xml structure, but simply a schema of our menu, folder navigator, or whatever we need.

The JsonTV object


This is my JsonTV object implementation. It is truly simple to use and, if you want, raw, but it is only the core which aim is to transport, transform, create, or parse from DOM, every kind of schema that will respect showed grammar.
For example, this is a piece of code that will automatically create above tree, and will hide, or show, internal leafs, if presents, and starting from the root.

onload = function(){
var directory = JsonTV.parseArray(
["root",
["demo.txt", {size:12345, date:"2008/06/07"}],
["temp", ["file1.tmp"], ["file2.tmp"], ["file3.tmp"]],
["sound.wav", {size:456, date:"2008/05/07"}]
]
);
document.body.appendChild(
directory
).onclick = function(e){
var target = (e ? e.target : event.srcElement).parentNode,
ul = target.getElementsByTagName("ul")[0];
if(/li/i.test(target.nodeName)){
if(ul)
ul.style.display = (target.clicked = !target.clicked) ? "none" : "";
else {
var __JSON__ = [];
for(var key in target.__JSON__)
__JSON__.push(key + " = " + target.__JSON__[key]);
if(__JSON__.length)
alert(__JSON__.join("\n"));
};
};
};
directory.className = "directory";

// this is only an assertion like check
setTimeout(function(){
var clone = document.body.appendChild(JsonTV.parseArray(JsonTV.parseDOM(directory)));
if(directory.outerHTML === clone.outerHTML)
document.body.removeChild(clone);
}, 1000);
};


Simplified API


As is for JSON object, JsonTV contains two main public methods: parse, and stringify.
The first one, parse, will convert a JSON string that contains a valid schema Array, a schema Array, into a DOM based Tree.
There is an exception, if you pass a DOM based Tree to parse function, it will convert them into an Array that will respect JsonTV schema.
On the other hand, the stringify method will convert a string, a DOM based Tree, or an Array, into JsonTV string, using, if present, the official JSON.stringify method, or not standard Gecko toSource one, if there is no JSON parser.

Conclusion


This is only my first step inside JsonTV technique, but I am sure that with a good usage of CSS, and few lines of JavaScript, using or not third parts libraries, a common intermediate protocol to manage, send, save, and show tree views, could let us develop truly interesting tree based applcations, making portings from different languages more simple than ever, as it has been for JSON de-facto standard.
Stay tuned for next examples ;)

No comments:

Post a Comment