Archive

jquery plugins with external template option

One of the nice features that ExtJs (now sencha) has is that allows you to overwrite the default HTML template its widgets. This features has not quite penetrated in the jQuery plugin community (not event jQuery UI). Now, thanks to the jQuery.tmpl() plugin, there is a very elegant way to build into all your plugins. The idea is that you want allow the user to modified the HTML that your plugin creates, if he needs to do so and thus give full control (not just CSS) over the presentation layer.

So I created this "hello world" plugin template that illustrates how this new plugin "design pattern" should work.

So this is how it works: I follow the class pattern of looping through all the elements, using private methods, and object based options with default values. The addition comes, that apart of jquery, I am using the anonymous function to do "dependency injection" of the jQuery.tmlp() plugin. I later use it's local shortcut as "tmpl". The template uses one simple example of "HTML helper" in my case truncate() that is called from within the template. Finally, the full template is exposed to be overwritten through the options object, in case the user of the plugin wants to modify it. When the HTML gets build, there is one more "trick" that I call "pre-render" binding, where I run the selector on the HTML before it gets to the DOM, ad an event to an element (in my case the button) and then put it to the DOM. This is something ExtJs also does weel: building the elements and adding events to them before putting them into the DOM, which is the single most efficient performance optimization you can do.

(function($, tmpl) {

    //truncate function
    var truncate = function(string, length) {

        if (string.length < length) {
            return string;
        }
        else {
            return "<span title=\"" + string + "\">" + string.substring(0, length) + "...</span>";
        }
    };
    
    //build content HTML
    var buildHtml = function(defaults) {
        //creates html using template, object and HTML helper that truncates text
        return tmpl(defaults.contentTemplate, defaults, { truncate: truncate });
    };

    // plugin definition
    $.fn.myPlugin = function(op) {
        
        //default
        var defaults = {
            contentTemplate: "<div><button>{{html $item.truncate(defaultText, maxTextLength)}}</button></div>",
            defaultText: "text",
            maxTextLength: 15
        };

        // build main options before element iteration
        $.extend(defaults, op);

        // iterate and reformat each matched element
        return this.each(function() {

            var _this = $(this), //element shortcut
                content = $(buildHtml()), //new content
                button = $("button", content); //button withing content
            
            
            //add an event to the content before it gets to the DOM
            button.click(function() {

                alert("hello world");

                return false;
            });

            //put to DOM
            _this.html(content);

        });
        
    };


})(jQuery, jQuery.tmpl);

Comments: