gdumitrescu
6/3/2011 - 6:03 PM

Unobtrusive Knockout support library for jQuery

Unobtrusive Knockout support library for jQuery

/*
 Unobtrusive Knockout support library for jQuery

 @author Joel Thoms
 @version 1.1
*/
(function(a){function e(a){var b=[],c;for(c in a){var d=a[c];switch(typeof d){case "string":b.push(c+":"+d);break;case "object":b.push(c+":{"+e(d)+"}");break;case "function":b.push(c+":"+d.toString())}}return b.join(",")}if(!a||!a.fn)throw Error("jQuery library is required.");a.fn.dataBind=a.fn.dataBind||function(f){return this.each(function(){var b=a.extend({},a.fn.dataBind.defaults,f),b=e(b);b!=null&&b!=""&&a(this).attr("data-bind",b)})}})(jQuery);
/** 
* @preserve Unobtrusive Knockout support library for jQuery
*
* @author Joel Thoms
* @version 1.1
*/

(function($) {

    if (!$ || !$['fn']) throw new Error('jQuery library is required.');

    /**
    * Private method to recursively render key value pairs into a string
    * 
    * @param {Object} options Object to render into a string.
    * @return {string} The string value of the object passed in.
    */
    function render(options) {
        var rendered = [];
        for (var key in options) {
            var val = options[key];
            switch (typeof val) {
                case 'string': rendered.push(key + ':' + val); break;
                case 'object': rendered.push(key + ':{' + render(val) + '}'); break;
                case 'function': rendered.push(key + ':' + val.toString()); break;
            }
        }
        return rendered.join(',');
    }

    /**
    * jQuery extension to handle unobtrusive Knockout data binding.
    * 
    * @param {Object} options Object to render into a string.
    * @return {Object} A jQuery object.
    */
    $['fn']['dataBind'] = $['fn']['dataBind'] || function(options) {
        return this['each'](function() {
            var opts = $.extend({}, $['fn']['dataBind']['defaults'], options);
            var attr = render(opts);
            if (attr != null && attr != '') {
                $(this)['attr']('data-bind', attr);
            }
        });
    };

})(jQuery);
Choose a ticket class: <select id="tickets"></select> 

<p id="ticketOutput"></p> 
        
<script id="ticketTemplate" type="text/x-jquery-tmpl"> 
    {{if chosenTicket}}
        You have chosen <b>${ chosenTicket().name }</b>
        ($${ chosenTicket().price })
        <button data-bind="click: resetTicket">Clear</button>
    {{/if}}
</script> 
    
<script type="text/javascript"> 
    var viewModel = {
        tickets: [
            { name: "Economy", price: 199.95 },
            { name: "Business", price: 449.22 },
            { name: "First Class", price: 1199.99 }
        ],
        chosenTicket: ko.observable(),
        resetTicket: function() { this.chosenTicket(null) }
    };

    $("#tickets").dataBind({
        options: "tickets",
        optionsCaption: "'Choose...'",
        optionsText: "'name'",
        value: "chosenTicket"
    });

    $("#ticketOutput").dataBind({ template: "'ticketTemplate'" });

    ko.applyBindings(viewModel);
</script>