Module inheritance and instantiation

Modules that work with behavior delegation, yet have a public accessible API, hiding many of the internal functions. The public API can be instantiated to use it multiple times on the same page.

by JibstaMan

HTML

<div class="page">
    <div id="comments-tab" class="tab-content">
        <div id="comments" data-game="somegameid">
            <table class="table">
                <tr class=".template">
                    <td></td>
                </tr>
            </table>
            <div class="help-message">
                <p>No message</p>
            </div>
        </div>
    </div>
</div>

JavaScript

var Framework = {};

(function()
 {
     function _parseOptions(options)
    {
        var defaults = {
            // The parent of all elements, to allow multiple instances on the same page.
            parent: '',
            // The selector to the messages container.
            container: '#comments',
            // The selector to the messages template.
            template: '.template',
            // The selector for the comments spinner (AJAX busy indicator).
            spinner: '#spinner-comments',
            // The selector for the message shown when there are no comments yet.
            message: '.help-message'
        };

        return $.extend(defaults, options)
    }

    Framework.Messages = {

        $: function(selector)
        {
            if (this.parent == null)
            {
                return $(selector)
            }
            return this.parent.find(selector);
        },
        
        setup: function(options)
        {
            this.options = _parseOptions(options);

            this.parent = (this.options.parent) ? $(this.options.parent) : null;
            this.container = this.$(this.options.container);
            this.template = this.container.find(options.template).detach();

            // TODO remove selector from template.

            this.spinner = this.$(this.options.spinner);
            this.message = this.$(this.options.message);

            this.length = 0;
        },
        
        get: function()
        {
            
        },
        
        add: function(message)
        {
            var $message = this.create(message);
            this.container.prepend($message);

            this.length++;
            this.updateMessage();
            this.show();

            this.call(this.onChange);
            this.call(this.onAdded);
        },
        
        call: function(fn, params)
        {
            if (typeof fn === 'function')
            {
                fn();
            }
        }
   ...