Knockout and JSRender Converter Example

In this blog, I will create a small sample to demonstrate how we can use the jsrender converters to separate code from templates. 

I am assuming that you have basic understanding of ASP.NET MVC as my code is written in that framework. Let's look at the cshtml first:
<h2>Converter Example</h2>

<button data-bind="click:showDetails">Get Data</button>
<div data-bind="html:opHtml"></div>

<script src="../../Scripts/converterexample.js" type="text/javascript"></script>
The html is pretty basic, it has a button and a div data bound to two properties in our view model which is defined in the converterexample.js file. The js file looks like:
/// <reference path="knockout-2.0.0.js" />
/// <reference path="jsrender.utils.js" />

var my = my || {};

$(document).ready(function () {
    my.converterVM = function () {
         var data = {
         players: [{name: 'Sachin Tendulkar', age: 39},
             { name: 'Roger Federer', age: 30 },
             { name: 'Rafael Nadal', age: 26 },
             {name: 'Michael Jordan', age: 49}]};
            
        var opHtml = ko.observable();
        var showDetails = function () {
            my.utils.renderTemplate({
                name: 'converter',
                data: data.players,
                selector: opHtml
            });
        };

        return {
            showDetails: showDetails,
            opHtml: opHtml
        };
    } ();

    ko.applyBindings(my.converterVM);
});
Here we have data which is a collection of players with their name and age. We have opHtml which is bound to the div above and the function showDetails which is bound to the click of the button in the cshtml. In showDetails we call a utility function (code below) which finds the 'converter' template, combines the template with player data and assigns the html to the opHtml property. The code for renderTemplate is below:
var my = my || {};
$(document).ready(function () {
    my.utils = function () {
        var getPath = function (name) {
            return "../Templates/_" + name + ".tmpl.html";
        };

        var renderTemplate = function (item) {
            var file = getPath(item.name);
            $.when($.get(file))
                .done(function (tmplData) {
                    $.templates({ tmpl: tmplData });
                    item.selector($.render.tmpl(item.data));
                    //$(item.selector).html($.render.tmpl(item.data));
                });
        };

        return {
            getPath: getPath,
            renderTemplate: renderTemplate
        };
    } ();
});
The code for converter template is below:
<li><span>{{:#index+1}} - {{:name}} - {{:age}} ({{ageConverter:age}})</span></li>
Here, we are displaying the name and age properties and also calling the converter 'ageConverter'. We are passing the value of age to this function. This function is defined in another js file and the code is below. With this syntax, jsrender engine makes sure that this converter is available everywhere jsrender is available.
$.views.converters({
    ageConverter: function (value) {
        if (value < 20) {
            return 'Too young to play';
        } else if (value < 30) {
            return 'Great Age to play';
        } else if (value < 40) {
            return 'About to retire';
        } else {
            return 'Too old to play';
        }
    }
});
The 'ageConverter' function takes in the age as its value and outputs a string depending on the value. The output looks like: