dev

April 15, 2008

jQuery template engine

Filed under: AJAX, HTML, Javascript, template — Tags: , , , , — Zeal_ @ 7:58 pm

As per popular demand (well, one person asked for it), this is the jQuery version of the template engine described in my earlier post, titled MooTools template engine (a new approach). To see what it does and for some usage examples I recommend reading that post first.

Here, instead of uploading the .js file as an attachment, I publish it section-by-section, providing comments along the way.

This is the $type function taken straight from Mootools 1.11, customized somewhat so it meets my needs better.

function $type(obj){
        if (obj == undefined) return false;
        if (obj.htmlElement) return 'element';
        var type = typeof obj;
        if (type == 'object' && obj.nodeName){
                switch(obj.nodeType){
                        case 1: return 'element';
                        case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
                }
        }
        if (type == 'object' || type == 'function'){
                switch(obj.constructor){
                        case Array: return 'array';
                        case RegExp: return 'regexp';
                }
                if (typeof obj.length == 'number'){
                        if (obj.item) return 'collection';
                        if (obj.callee) return 'arguments';
                }
        }
        return type;
};

The next function, fillTemplate, is used internally by both public methods for doing the actual templating work. The argument target represents a template to be fileld, and data is the data to fill the template with.


function fillTemplate(target, data) {
    var target = $(target);
    for(var key in data) {
        var tmpEls = target.find('.' + key);
        var obj = data[key];
        switch($type(obj)) {
        case 'array':
            // clone array of 'el'
            for(var i=0;i<obj.length;i++) {
                var tmpEl = $(tmpEls&#91;i%tmpEls.length&#93;);
                var a = tmpEl.clone(true);
                tmpEl.parent().append(a);
                if (($type(obj&#91;i&#93;) == 'array') || ($type(obj&#91;i&#93;) == 'object')) {
                    fillTemplate(a, obj&#91;i&#93;);
                } else {
                    a.text(obj&#91;i&#93;);
                }
            }
            tmpEls.remove();
            break;
        case 'object':
            // object, descend
            fillTemplate(tmpEls&#91;0&#93;, obj);
            break;
        default:
            // set text of el to obj
            tmpEls.text(obj);
        }
    }
}
&#91;/sourcecode&#93;

And now for the public functions. On the details of their usage, refer to the relevant parts of the original post linked above.

Our first public function, <strong>expandTemplate</strong> copies a template DOM node to the <strong>target,</strong> and fills it with <strong>data.</strong>


function expandTemplate(template, target, data) {
    var template = $(template);
    var target = $(target);
    target.empty();
    target.append(template.clone().contents());
    fillTemplate(target, data);
}

The function tmpl is the AJAX front-end for fillTemplate. It gets JSON data from the given url posting any optional data (postData) and fills the template with the response. This slightly differs from the approach of the mootools version.

function tmpl(template, target, url, postData) {
    var template = $(template);
    var target = $(target);
    $.getJSON(url, function(data) {
        expandTemplate(template, target, data);
    }, postData);
}

Summary

Using jQuery, the code got slightly simpler and a tad bit faster. Have fun using it :)

(As a side note, a PHP version is still on the way, it has some performance issues.)

February 21, 2008

Update when user is idle

Filed under: AJAX, Javascript, MooTools, OOP — Tags: , , , , — Zeal_ @ 11:44 pm

Recently I had to update a list based on what the user entered into an input field. I thought it should somehow detect that the user finished typing, but that seemed a rather obscure notion at first glance.

But then it occured to me that it simply means that there has not been any input in, say, 1s or any specified amount of time. Even if the user just stopped for a sec or is disturbed, it is nice to have the list updated for her, and indeed, it does not interfere with what we have in mind when thinking about typing. It doesn’t destroy the feeling of “right now I am telling the computer what I want to”, it bears no interrupting quality whatsoever.

It is so simple:

<input type="text" id="typehere" />
<div id="target"></div>

and then,

new IdleUpdate('typehere', {
    delay:500,
    onIdleChange:function(el) {
        new Ajax('stuff.php', {
            data:el.value,
            update:$('target')
       }).request();
    }
});

In this example you can see how the class fits nicely in the MooTools style of design, and how expressive a language javascript can be. :)

Options supported are

  • delay: amount of idle time before the event is fired,
  • onIdleChange: the event handler

Needless to say, anything can be done in the event handler, not just Ajax calls but it is also nice for checking password strengts clientside or computing the total of a bill etc.

Check it out yourself, it’s well under 1K ;) You may want to change the extension. idleupdate.js

Blog at WordPress.com.