JSONML Array to DOM - jQuery.ml
Hi everybody.
Recently, I have introduced jQuery ( + jQuery UI ) as default JS
framework into company team I am working with.
While I was creating some new component / plugin for our CMS, I though
about introducing an enhanced JSONML Array parser to quickly create
DOM content in a "fast and standard" way.
I wonder if I am missing some information about jQuery DOM creation,
so here I am to ask you if there is a better way to obtain the same
result, or if this proposal could be interesting for everybody.
Here there's the little plugin:
/** JSONML Array to DOM - quick DOM creation
* @author Andrea Giammarchi
* @since 07/07/2008
* @specs JSONML http://jsonml.org/
* @extra events assignment
*/
$.extend({
ml:function(multi){return function(a){
for(var i = 1, length = a.length, node = $
(document.createElement(a[0])), value; i < length; i++){
switch(typeof(value = a[i])){
case "string":
node[0].appendChild(document.createTextNode(value));
break;
case "object":
if(value instanceof Array)
node.append($.ml(value));
else
for(var key in value)
switch(typeof value[key]){
case "string":
node.attr(key === "klass" ?
"class" : key, value[key]);
break;
case "function":
value[key] = [value[key],
undefined];
case "object":
node.bind(key.replace(multi, " "),
value[key][0], value[key][1]);
break;
};
break;
};
};
return node;
}}(/^on| on|_on|_/g)
});
The enhancement consists into ability to assign directly one or more
events, and manage the new content as a generic jQuery result.
i.e.
$.ml(["div", "Hello World"]).appendTo($("body"));
or
$("body").append($.ml(["div", "Hello World"]))
i.e. with events + inline fired event:
$.ml(["a", "show hello", {href:"#hello",style:"color: red",
click:function(){alert('Hello');return false}}]).appendTo($
("body")).click();
A compatibility test could be performed using any "official" JSONML
page demo code, i.e.
$(function(){
$("body").append($.ml(
["ul",
["li",
{ "style" : "color:red" },
"First Item"
],
["li",
{
"title" : "Some hover text.",
"style" : "color:green"
},
"Second Item"
],
["li",
["span",
{ "class" : "code-example-third" },
"Third"
],
" Item"
]
]
))
});
Finally, you can add one or more events to bind, using a bind string
as key, or an underscore based key:
$(function(){
$("body").append($.ml(
["div",{
style:"padding: 4px",
mouseover_mouseout:function(){ // same of "mouseover
mouseout"
this.style.backgroundColor =
(this._hovered = !this._hovered) ? "yellow" :
"white";
}
},
"Hello ",
["strong",
"JSONML"],
" !!!"]
));
});
Where each event could be written as
"onclick" | "click"
Kind Regards
P.S. the reason I have used
node[0].appendChild(document.createTextNode(value)) instead of
node.text(value) is that with node.text(value) the content is
replaced / destroyed if there is some other html content and I don't
know if this is an expected behaviour