Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Binding Metro UI Tiles with Knockout.js

, 10 Jan 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
Knockout is a JavaScript library which dynamically binds data between different html contents and follow Model-View-View-Model (MVVM) design pattern.  It’s one of the core feature is Observable, which can detect changes in the view model....

View Live Demo 


Introduction 

Knockout is a JavaScript library which dynamically binds data between different HTML contents and follow Model-View-View-Model (MVVM) design pattern. It’s one of the core feature is Observable, which can detect changes in the view model and updates the model according to that change. It’s a special JavaScript object that can detect dependencies among controls automatically. In this article we will mostly use observable to bind controls and update data dynamically.

Problem

Consider a metro tile where each tile has a title and description. It has a background color as well. There can be multiple tiles of same type. Our target is to create tiles dynamically and with every tile there would be an edit panel where user can edit its title, description and background color. If you are confused about this scenario then I recommend you to view demo first.

Solution

One of the main features of Knockout is, it can track each element of UI and can update automatically. We will use this feature to bind our metro tiles with its edit panel and when user will change in edit panel, tiles of that panel will change automatically. Knockout will track edit panel with its correspondent tile. For this, first we have to take a JavaScript object where all the property of a metro tile is defined. Here we have title, description and color as an observable. This observable will detect dependencies between each tile and its edit panel and it will keep each tile object updated automatically. Here is a how Tile object looks:

var Tile = function (title, description, color) {
     var self = this;
     self.title = ko.observable(title);
     self.description = ko.observable(description);
     self.tileColor = ko.observable(color);
     self.editPanel = ko.observable(false);
     self.expandEdit = function () {
          self.editPanel(true);
     };
     self.collapseEdit = function () {
          self.editPanel(false);
     };
};

Another additional observable is taken named editPanel which will detect visibility of its tile’s edit panel. expandEdit and collapsEdit will make editPanel true or false on click event. Here ObservableArray is taken to store all tiles. addTile and removeTile functions will add new tile on the view and remove tile will delete its corresponding tile from the view and from the observableArray as well. 

var TileModel = function () {
     var self = this;
     self.lines = ko.observableArray([
           new Tile("Batman", "The Dark Night Rises", "#525252"),
           new Tile("Transformer", "Revenge of the Fallen", "#DA532C")
     ]);
     self.addTile = function () {
          self.lines.push(new Tile("Title", "Description", RandomColor()))
     };
     self.removeTile = function (line) { 
          self.lines.remove(line) };
     };

ko.applyBindings(new TileModel());   

Also two tiles are pushed into the array on load and observable will bind them with the HTML control automatically. Then finally we’ve bind the full model with Knockout with ko.applyBindings().

Now let’s take a look at HTML controls which are bind with observable object:
<a id="aCreate" class="btn-add-tile" data-bind='click: addTile'>Add Tile</a>
<div class="tile-container" data-bind='foreach: lines'>
     <div class="tile-area">
          <div class="tile-elem" data-bind="style: { background: tileColor }">
               <p class="tile-description" data-bind="text: description"></p>
          </div>
          <span class="tile-title" data-bind="text: title" style=""></span>
          <div class="bottom-bar">
               <span class="arrow" data-bind='click: expandEdit, ifnot:editPanel'>
                    <img src="Styles/images/MetroDown.png" alt="Open edit panel" /></span>
               <span class="arrow" data-bind='click: collapseEdit, if:editPanel'>
                    <img src="Styles/images/MetroUp.png" alt="Close edit panel" /></span>
               <span class="close-btn" data-bind='click: $parent.removeTile'>
                    <img src="Styles/images/MetroClose.png" alt="Remove tile" /></span>
          </div>
          <div data-bind="if: editPanel">
               <div class="edit-panel">
                    <label>Title:</label>
                    <input class="text-title" data-bind="value: title, valueUpdate: 'afterkeydown'" maxlength="12" />
                    <label>Description:</label>
                    <textarea class="txtdesc" rows="2" data-bind="value: description, valueUpdate: 'afterkeydown'"></textarea>
               </div>
          </div>
     </div>
</div> 

Here Knockout will search for data-bind attribute to bind data with its model. Now on clicking Add Tile button we are calling addTile function from TileModel which adds a new object to lines. With foreach, Knockout is generating all the tile object stored in lines with a loop. Every time a tile is added or removed, it tracks the changes in the model and bind tiles dynamically. Now edit panel’s <textarea> is bind with <p> of tile element with description object. <p> is updated when <textarea> has an input character. We are updating the description object after key down. Title will update same way like description. So the main thing is all the observables track dependencies among the HTML controls and it updates automatically.

Why Knockout?

Situation like this, where we have to bind data dynamically and need to track all the dependencies among controls, then Knockout is best choice. We will bind observable with UI controls and observable will notify about changes and it will update automatically. Another good feature is, it can update data very frequently, like when we bind afterkeydown method, observable detects change and update correspondent element at that moment.

Run Source Code

Download the zip file, extract it, open KnockoutTiles.sln file and hit F5. It’s a Asp.Net web project written in Visual Studio 2012 and used knockout.js version 2.2.0. 

Conclusion

Knockout follows MVVM pattern where observable track dependencies between model and view model and update view automatically. This article gives a very basic idea on observable. I recommend to download the source file and see for yourself how it actually works.

Reference

http://knockoutjs.com/


License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sk. Tajbir
Software Developer (Senior) Desme
Bangladesh Bangladesh
I've started working on C#.Net WinForm in 2011 and developed a desktop application named NoseOp for Microsoft Imagine Cup 2011 and my team scored one of the top 6 teams of Bangladesh. NoseOp is an application for physically disable person to operate computer easily and do everyday work. Later on I scored 1st in software exhibition of American International University - Bangladesh's(AIUB) Software Engineering day.
 
After that I've started working on Asp.Net and developed several websites which are running successfully in different countries. I'm very much interested and passionate about learning new technologies.
 
www.sktajbir.com
 
My Projects:
 
CodeProject Achievement:
  • 2nd in Best Web Dev article of December 2012
  • 7th in Best overall article of April 2013
  • 3rd in Best Web Dev article of April 2013
Follow on   Twitter   LinkedIn

Comments and Discussions

 
Generalkeep going.. PinmemberMonjurul Habib14-Dec-12 21:45 
GeneralRe: keep going.. PinmemberSk. Tajbir14-Dec-12 21:50 
GeneralMy 5 PinmemberShahriar Iqbal Chowdhury14-Dec-12 4:45 
GeneralRe: My 5 PinmemberSk. Tajbir14-Dec-12 4:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141216.1 | Last Updated 10 Jan 2013
Article Copyright 2012 by Sk. Tajbir
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid