Template Selector control


MvvmJS control: TemplateSelector

WinJS enables the developers to use declarative programming in UI layer. It fits very well with MVVM architectural style. The main idea is that UI (view which is HMTL part) can be managed by the javascript object ( ViewModel ). All of this works automatically thankfully to data-binding.

Example: lets have a HTML element wich is “bound” to ViewModel (JS object). Changes done in ViewModel can be reflected on HTML element, i.e. it can change a style, color, change a text inside, etc. Full example can be checked here

The idea can be extended a level higher. The idea is taken from WPF/Silverlight world, especially from Caliburn (as I worked with it for more than a year).

MvvmJS.UI.TemplateSelector control

The goal of this control is simple: selects a template for the databinding context object and then renders it with that template.

The common usage scenario is: let’s have ListView which displays messages and each message has a type. Each type contains different properties and is handled and rendered differently. Solution is simple.

Code behind part

    var elm = document.body;

    var list = new WinJS.Binding.List();

    list.push({ type: 'call', duration: 100 });
    list.push({ type: 'text', text: 'Hello world!' });
    list.push({ type: 'call', duration: 300 });
    list.push({ type: 'call', duration: 200 });
    list.push({ type: 'text', text: 'WinJS is cool!' });

    WinJS.UI.processAll(elm).then(function () {
        return WinJS.Binding.processAll(elm, { messages: list });
    });
    

The above code creates list of the messages and each message has a type (call, text). Message types have different properties. After filling the list we process all win controls within the document.body and then we run databinding process over it.

Rendering part

    <div id="messageTemplate" data-win-control="WinJS.Binding.Template">
        <div class="message" data-win-control="MvvmJS.UI.TemplateSelector" 
            data-win-bind="winControl.model:self MvvmJS.Binding.wbind"
            data-win-options="{ selector: {
		                            type: MvvmJS.UI.TemplateSelector.PropertySelector,
		                            property: 'type',
		                            pattern: '/default.html#{0}',
	                            } }">
        </div>
    </div>
    <div data-templateid="call" data-win-control="WinJS.Binding.Template">
        <div class="call">Call, duration <span data-win-bind="innerText:duration"></span>s</div>
    </div>

    <div data-templateid="text"class="message text" data-win-control="WinJS.Binding.Template">
        <div class="text">Text message: <span data-win-bind="innerText:text"></span></div>
    </div>

    <div id="listView"
        data-win-control="WinJS.UI.ListView"
        data-win-bind="winControl.itemDataSource:messages.dataSource"
         data-win-options="{ itemTemplate: messageTemplate }">
    </div>
    

There is a listview which gets the messages as an input. The template used for the rendering refers to a template with template selector control. Template selector control gets the message as the input (setting property model) and renders it. Template selector selects the template based on the property (setting selector option to PropertySelector class) “type” of the input object (in this case a message).

Templating

The templates are located in the file default.html and are identified by data-templateid attribute. Template selector uses template loading mechanism with caching capabilities. The templates are identified by “#”. For the above example, in case message is of ‘call’ type, then the pattern ‘/default.html#{0}’ will be replaced to ‘/default.html#call’ which identifies the template with data-templateid attribute ‘call’ in the file ‘/default.html’. The recommended approach is to store the templates in the separate file, i.e. templates.html.

The result

Just another example

Another common situation is just having a general “alert” dialog which gets an object as the input. Based on the object type it’s possible to choose appropriate template to render the message, i.e. exception, business messages, etc. In the traditional scenario it’s necessary to write Javascript code with ifs or switch/case and manualy inject HTML into UI.

Summary

The above mentioned problems are very common and they have very similar solution which I isolated into a control. The control is under development and there will be several enhancements added, i.e. animations. The complete example can be found on http://mvvmjs.codeplex.com/

One thought on “Template Selector control

Leave a reply to never cold call again Cancel reply