Understanding click binding in Knockout.js

Click Binding adds click event to element on View. You can do click binding with any function in ViewModel or you can bind to any normal function.

clip_image001

Let us try to understand it with a very simple ViewModel. We have a ViewModel as below

 var viewModel =
 {
 display: function ()
 {
 console.log("display");
 }
 }

As you see there is one function as property of ViewModel and that can be click bind on view as below,


<button data-bind="click:display" >display</button>

Let us consider one more example and in this we will update value of other observable on click of element on View. We have ViewModel as below,


var viewModel =
 {
 count : ko.observable(0) ,
 display: function ()
 {
 this.count( this.count() + 1);
 }
 }

On View we are doing click binding and text binding as below


<button data-bind="click:display" >display</button> <br/>
 Number of clicks <span data-bind="text:count" ></span>

Sometime you may have to pass current item in click binding. Assume a requirement that you have done foreach binding on element with observable array. Now on click of a particular item, you need to pass that item in ViewModel function to work with that. That can be solved as below. As you see in below ViewModel,

  • There is an observable array. This will be bind to ul or tr element on View
  • There is a function. It takes input which will be used to delete item from observable array.

function viewModel()
 {
 var self = this ;
 self.subject= ko.observableArray(["Phy", "Che", "Bio"]),
 self.removeSubject= function (item)
 {

 self.subject.remove(item);
 }
 }


ko.applyBindings(new viewModel());

On the View we need to do click binding and pass current item to function on which click binding is getting performed.


<ul data-bind="foreach: subject">
 <li>
 <span data-bind="text: $data"></span>
 <button data-bind="click: $parent.removeSubject">Remove</button>
 </li>
</ul>


If you notice we are passing current item using current binding context. So to pass current we are using parent.

In some scenario you will have to pass event object. Event object can be passed as given below,


function viewModel()
 {
 var self = this ;
 self.subject= ko.observableArray(["Phy", "Che", "Bio"]),
 self.removeSubject= function (data,event)
 {
 if (event.shiftKey) {
 self.subject.remove(data);
 }
 }
 }


On View binding can be done as below


<ul data-bind="foreach: subject">
 <li>
 <span data-bind="text: $data"></span>
 <button data-bind="click: $parent.removeSubject($data,event)">Remove</button>
 </li>
</ul>

&nbsp;

Now an item would be deleted on pressing shift key . Understanding of click binding is very useful to create apps using KO. I hope you find this post useful. Thanks for reading.

Control Flow bindings in Knockout.js

You can control flow of element on the view using Control Flow bindings of Knockout.js. There are four Control Flow bindings

  • foreach binding
  • if binding
  • ifnot binding
  • with binding

Out of these four bindings foreach and if bindings are used very often.

foreach binding

foreach binding repeat same markup for number of times equivalent to number of elements in an array. It also binds each repeat of mark-up to corresponding item of the array.

image

Let us try to understand it with an example. Assume we have a ViewModel which contains observable array as one of the observable.


var viewModel =
 {
 students: ko.observableArray
 ([
 {name :"Dan W", subject : "JavaScript" },
 { name: "Glenn B", subject: "Node" },
 { name: "Pinal D", subject: "SQL" }
 ])
 }

ViewModel contains a property students which is an observable array. We can bind this on view to a table or lists elements.


<table>
 <thead>
 <tr>
 <th>Name</th>
 <th>Subject</th>
 </tr>
 </thead>
 <tbody data-bind="foreach: students">
 <tr>
 <td data-bind="text: name"></td>
 <td data-bind="text: subject"></td>
 </tr>
 </tbody>
 </table>

As you notice that on the table body we are performing foreach binding. So mark-up inside table body would be repeated 3 times in this case. Since number of elements in observable array is 3.

On running this application you will get table rendered with three rows as below,

image

Next let us consider one complex scenario in which we want to add and remove students. So let us go ahead an update view model with computed observable to add and remove items from observable array


function viewModel()
 {
 var self=this;
 self.students= ko.observableArray
 ([
 {name :"Dan W", subject : "JavaScript" },
 { name: "Glenn B", subject: "Node" },
 { name: "Pinal D", subject: "SQL" }
 ]);
 self.addStudent= function ()
 {
 self.students.push({ name: "dj", subject: "JavaScript" });
 };
 self.removeStudent= function ()
 {
 self.students.remove(this);
 }
 }

ko.applyBindings(new viewModel());

There is nothing much fancy in above ViewModel. We just added computed observables to add and remove students. Next we can bind that to a view contains unordered list as below


<h4>Students</h4>
 <ul data-bind="foreach: students">
 <li>Name at position <span data-bind="text: $index"></span>:
 <span data-bind="text: name"></span>
 <a href="#" data-bind="click: $parent.removeStudent">Remove</a>
 </li>
 </ul>
 <button data-bind="click: addStudent">Add</button>

On running application you will find that now you can add and remove student

image

You can use $index, $parent, $data with foreach binding as well. For example

  • You can read index of a particular element using $index.
  • You can read array element using $data. Not a particular element
  • You can read parent viewmodel or other properties of viewmodel using $parent

if binding

if binding allows whether a section of mark-up will appear or not. Unlikely visible binding if binding add or remove markup from the DOM. It performs following tasks,

  • Add or remove markup from the DOM
  • Make sure that data-bind attribute is having applied on the markup

Now let us take if binding in action. Let us say you have ViewModel as below


var viewModel =
 {
 show : ko.observable(false)
 }

ko.applyBindings(viewModel);

On View we can do binding as follows


<label><input type="checkbox" data-bind="checked: show" />Display Div</label>
<div data-bind="if: show">Visible/Hide using if binding </div>

As you notice that we are doing checked binding on input checkbox whereas performing if binding on div. If value of ViewModel property evaluates to non-false value then then div would be visible. Input is toggling value of show property.

Let us take another example in which we will learn that how if binding is useful in case of working with null. As you know if binding add or removes elements on the DOM having their data binding applied on that. Consider following ViewModel


function viewModel() {
 var self = this;
 self.students = ko.observableArray
 ([
 { name: "Dan W", subject: null },
 { name: "Glenn B", subject: { music: 'guitar' } },
 { name: "Pinal D", subject: { music: 'drum' } }
 ]);

};

Next we need to do if binding on the view,


<h4>Students</h4>
 <ul data-bind="foreach: students">
 <li>
 Student: <b data-bind="text: name"> </b>
 <div data-bind="if: subject">
 Subject: <b data-bind="text: subject.music"> </b>
 </div>
 </li>
</ul>

Above you see that we are applying if binding on div going to display subject. If binding add or remove on basis of non-falsie value. So for student subject value is set to null this div will not get created. If you try to achieve it using visible binding then for any student for which value if subject is set to null you will get subject.music throwing exception.

Ifnot binding

This is exactly the same as if binding. it only inverts the value passed to it.

So let us say you have ViewModel as below,


var viewModel =
 {
 display : ko.observable(false)
 }

and you bind this to a view as given below,


<div data-bind="ifnot: display">
 <h1>hello</h1>
 </div>

On running you will find div is added on the DOM even though display property in ViewModel is set to false. Because ifnot binding invert value of property in ViewModel.

When you create MVVM application using Knockout.js , control flow binding is very useful. You will use it very often and I hope you find this post useful in understanding control flow binding. Thanks for reading.

Computed Observable in Knockout.js

In this post we will take a look on Computed Observable in Knockout.js. Let us start with an example, you have a ViewModel


var viewModel =
 {
 name: ko.observable("G Block"),
 age: ko.observable(40)
 };

Now you want a custom message to be rendered on the view, that message will depend on other observable of ViewModel. To create that custom message you need to create a Computed Observable. Computed Observable can be created as below,

image

It takes two required parameter,

  • First parameter as function. This function will work with other observable and calculate computed observable
  • Second parameter is name of the function. If you are creating computed observable inside ViewModel then second parameter should be this

So ViewModel with computed observable is as follows,


var viewModel =
 {

name: ko.observable("G Block"),
 age: ko.observable(40),

 };

viewModel.greet = ko.computed(function () {
 return this.name()
 + " is " +
 this.age() +
 " years old";
 }, viewModel);

 ko.applyBindings(viewModel);

On View binding can be done as follows,

 


<input type="text" data-bind="value:name" />
 <input type="text" data-bind="value:age" /> <br />
 <span data-bind="text:greet" />

Few points worth knowing about computed observable

  • It gets evaluated as soon as the computed observable is created. So we may get into problem in a scenario in which computed observable is based on properties which not yet computed or initialized or loaded.
  • If computed observable is based on simple property (not observable property) then change in property will not trigger change in computed observable
  • Change in computed observable triggers if any of the observable property it is based on gets changed.

Computed observable can be created in one more ways as well. You can create ViewModel as below,


function viewModel() {
 var self = this;
 self.name = ko.observable("G Block");
 self.age = ko.observable(40);
 self.greet = ko.computed(function () {
 return self.name()
 + " is " +
 self.age() +
 " years old";
 }, this);
 };

As you notice that we have added computed observable as part of ViewModel. If you follow this way of creating ViewModel then you need to manage this explicitly. We are passing second parameter as this. Without passing it we can’t evaluate computed observable and cannot access other observable to calculate computed observable. So if you don’t pass this as second parameter, you won’t able to access this.age() and this.name(). In above scenario we are preserving this in self inside ViewModel and using self instead of this.

Writeable Computed Observable

So far we have created computed observable reading values of other observables and then returning value based of them. These observables are Read-Only Computed Observable.

You can create writeable Computed Observable as well. You wish to create writeable computed observable in following possible scenarios

  • Interpreting user input
  • Validating user input
  • Setting values of other observables on based on some logic

So let us see how we can use writeable computed observable. Let us say you have a view as below,

clip_image001

Requirements are,

  • When you change run Average should get updated.
  • Average is computed observable and based on Runs and Match

We can achieve above requirement by creating a simple ViewModel and a read only computed observable.

One of other requirement is that when you change Average, Runs should get updated. This can be done by creating a writeable observable.

Let us start with creating a ViewModel,


var playerViewModel =
 {
 name: ko.observable("Sachin T"),
 runs: ko.observable(10000),
 match: ko.observable(100)
 };

Now we need to create a writeable computed observable.


playerViewModel.average = ko.computed({
 read: function ()
 {
 var avg = this.runs() / this.match();
 return avg;
 },
 write: function (value)
 {
 var r = value * this.match();
 this.runs(r);
 },
 owner: playerViewModel
 });

To create writeable computed observable

  • You need to pass JavaScript object to ko.computed function
  • That takes options like read, write, owner etc.
  • Read property takes a function and return value based on other observable
  • Write property also take a function as input. This function take an input parameter “value”. You may wish to perform operation on value and write back resulted value to other observable.
  • You need to ViewModel as owner. This defines the reference of the key

image

In this way you can create writeable computed observable. You can bind values to View as below,


<span data-bind="text:name"></span> <br />
 Runs: <input type="text" data-bind="value:runs" /> <br />
 Match: <input type="text" data-bind="value:match" /> <br />
 Average: <input type="text" data-bind="value:average" />

Deferred Evaluation of computed observable

Before we end this post let us discuss one more concept of deferred execution of computed observable. As we discussed in beginning of this post that computed observable get evaluated at time of creation. So if it is based on observable which is not loaded at time of creation of computed observable then you might run into problem. KO gives you option to deferred execution of computed observable. You can do that by setting deferEvaluation value to true

image

We learnt in this post about Computed Observable. I hope you find this post useful. Thanks for reading.

Why we need Observable Properties in Knockout.js

In this post we will take a look on why we need observable properties in Knockout.js

Before you read further this blog post, I would recommend you to read

Setting up Visual Studio for Knockoutjs Development

Create your First MVVM based JavaScript App in two simple steps using Knockoutjs

Inbuilt Bindings in Knockout.js: Controlling Text and Appearance

MVVM is, “When View Model changes View must be notified such that UI will be refreshed automatically

image

Let us try to understand Knockout feature Automatic UI Refresh with an example,

Let us create a simple ViewModel


var viewModel =
 {
 message: "Hello World",

 };

Now create a simple View. In View we are performing value and text binding on input and span element respectively.


<input type="text" data-bind="value:message" /> <br />
 <span data-bind="text:message" /> <br />

Now on running application, you will notice that when you change value in input textbox that value is not getting refreshed automatically on view.

image

To achieve automatic UI refresh, you need to create ViewModel properties as observable properties. You can create that as following,


var viewModel =
 {
 message: ko.observable("Hello World")

 };

Essentially you need to convert normal properties of ViewModel as observable properties to achieve automatic UI refresh.

image

Now on running application you will find that UI is getting refreshed automatically. You will notice that when you change value in input textbox that value is getting refreshed automatically on view.

clip_image001

Now these are the main tasks performed by observable properties

  • Notify about changes to subscribers
  • Automatically detect dependencies
  • To update view automatically

Reading ViewModel properties

You can read ViewModel property as below,


var m = viewModel.message();
 console.log(m);

Writing ViewModel properties

You can write ViewModel property as below,


viewModel.message("whatsup")

Writing multiple observable properties

KO allow you to write multiple observable property with chained syntax. Let us say we have a ViewModel as below,


var viewModel =
 {
 message: ko.observable("Hello World"),
 greet : ko.observable(23)
 };

And you want to update both properties. You can do that using chained syntax as below,

viewModel.message("whatsup").greet(45);
 var m = viewModel.message();
 var n = viewModel.greet();
 console.log(m);
 console.log(n);

So essentially we need observable properties in KO to achieve,

  • Two way binding
  • Notify the subscribers
  • Automatic refresh UI

I hope you find this post useful. Thanks for reading.

Inbuilt Bindings in Knockout.js: Controlling Text and Appearance

Setting up Visual Studio 2013 for Knockoutjs Development

Create your First MVVM based JavaScript App in two simple steps using Knockoutjs

In simpler terms we can define Knockoutjs binding as a mechanism to establish relationship between view and ViewModel. View takes user action and pass the instruction to ViewModel. One of the most popular example of this could be clicking on a button or selection of an item on the View by user. After each action of user, view got the task to instruct ViewModel about the same. This is done through the BINDING. On the other hand we can define binding as manipulating DOM elements and their appearance on the basis of ViewModel properties. Binding establish the relationship between View and ViewModel.

image

KO Bindings can be categorized in various categories,

  • Controlling Text and Appearance
  • Controlling Flow
  • Controlling User Actions like Click, Submit etc.

If required you can create Custom Binding as well. In this post we will focus on bindings which control text and appearance. Those bindings are as follows,

clip_image002

Now one by one let us take a look on different text control and appearance binding.

Visible binding

You use visible binding to find when an element on DOM should be visible or when it should not be. This binding is very simple to use.

Let us say you have a ViewModel as below,


var viewModel = {

display: ko.observable(false)

};

You can use visible binding on view as below,


<div data-bind="visible: display">
 <h2>hey I am visible through visible binding </h2>
 </div>

Some points about visible binding is worth discussing here, If value of ViewModel property will resolved to following values then bind DOM element view property will be set to block.

  • Null
  • undefined
  • number zero
  • Boolean false

For DOM elements if ViewModel property value is yielding to false then visible binding will always have more priority than CSS attributes.

image

Text binding

You use text binding to display a text on View. You can do text binding with elements like

  • <h1>,<h2>
  • <em>
  • <span>
  • <input>
  • Practically you can do text binding with any element on View.

Let us suppose you have ViewModel as below,


var viewModel = {

message : "hey welcome to KO "

};

You can do text binding on View as below,


<div>
 <h2 data-bind="text : message"></h2>
 </div>

If ViewModel property contains a HTML encoded value and you bind that property on View using text binding.


var viewModel = {

message: "hey welcome to KO ",
 messagehtml:"<i>hello there</i>"

};

binding is done as below ,


<div>
 <h2 data-bind="text : message"></h2>
 <span data-bind="text: messagehtml"></span>
 </div>

You will get output HTML encoded value as plain text. It will not get rendered. You will get ouput as below,

clip_image001

In text binding

  • All the previous value of the Element on View will be overwritten
  • If ViewModel property contains any value than string or number then in text binding that value will get displayed as value.toString()

HTML binding

You use HTML binding to set InnerHtml property of View’s Elements. So let us take a ViewModel with property value encoded HTML value.


var viewModel = {

message: "hey welcome to KO ",
 messagehtml:"<h1>hello there</h1>"

};

html binding can be done as following ,


<div>
 <h4 data-bind="text : message"></h4>
 <span data-bind="html: messagehtml"></span>
 </div>

Now View will render html from ViewModel. Html binding always set innerHtml attribute of Element and text binding set innerText property. You should be cognizant using html binding because it may cause potential injection of script on the view.

CSS binding

You use CSS binding to apply CSS class to elements on View. Let us say you have a CSS class defined as below,


.red
{
 color:red

}

You want to apply red background to div on a condition from ViewModel property. Let us assume we have a ViewModel as following,


var viewModel = {

message: "hey welcome to KO ",
 messagehtml: "<h1>hello there</h1>",
 warningmessage : false

};

Let us assume that we want to apply red class from CSS on basis of warningmessage property of view. We can do css binding as below,


<div data-bind="css: {red : warningmessage}">
 hello world
 </div>

Let us see that how can we work with dynamic classes in CSS binding. Assume that we have following classes,


.red
{
 color:red

}
.blue
{
 color:blue
}
.green{
 color : green
}

We need to dynamically bind one of these classes to element on View. Suppose we have ViewModel as below,


var viewModel = {

message: "hey welcome to KO ",
 messagehtml: "<h1>hello there</h1>",
 messagelevel : 10

};

On basis of ViewModel property messagelevel we need to apply a css class dynamically. To do this a computed observable is required. Computed observable will return css class.


viewModel.colorMessage = ko.computed(function () {

if (this.messagelevel > 0)
 {
 return 'green';
 }
 else if(this.messagelevel <0)
 {
 return 'red';
 }
 else if(this.messagelevel==0)
 {
 return 'blue';
 }

}, viewModel);

And CSS binding at View can be done as follows,


<div>
 <div data-bind="css: colorMessage,
 html: messagehtml">

 </div>

 </div>

In this post we learn various binding which help to control text and appearance of elements. I hope you find this post useful. Thanks for reading.

Can you answer these 10 basic Knockout Questions?

Q1. KO performs following operations

 

  1. Automatic Refresh
  2. Two way Binding
  3. Templating
  4. All of the above

 

Q2. On which event bindings in KO fire notification

 

  1. Change event
  2. Update event
  3. On Any event
  4. None of the above

 

Q3. Value of computed observable is determined at

  1. Time of creation
  2. Time of update
  3. Time of DOM loading
  4. Depends on implementation

 

Q4. ko.toJSON is used for following purpose

 

  1. convert objects that include observables to a JSON string
  2. to convert string to object
  3. to consume JSON service
  4. to consume any service

 

Q5. How we can add reference of KO in project

 

  1. using local reference
  2. using CDN
  3. using Nuget package
  4. all of the above

 

Q6. On which value of ViewModel property visible binding will be set to block?

 

  1. Null
  2. Undefined
  3. Zero
  4. All of the above

 

Q7. ViewModel can be created as

 

  1. Object literal
  2. Function
  3. Both
  4. None of the above

 

Q8. Click binding can be bind to what kind of property in ViewModel

 

  1. Function
  2. Boolean
  3. Array
  4. All of the above

 

Q9. For what purpose we use foreach binding in KO

 

  1. To duplicates section of markup for each entry in array
  2. To duplicates section of markup for each entry in ViewModel
  3. To duplicates section of markup for each entry in Model
  4. None of the above

 

Q10. The Value binding should be used with

  1. <input> , <select> , <textarea>
  2. <span>, <div>
  3. <radiobutton> <table>
  4. All of the above combination

Create your First MVVM based JavaScript App in two simple steps using Knockoutjs

Read all Knockoutjs posts here

Setting up Visual Studio 2013 for Knockoutjs Development

Okay purpose of this post is very simple to explain you why Knockoutjs. I will try to put it in simplest way that Why we need to work Knockoutjs. If you are not a begineer then probably this post may appear very simple to you. However I request keep reading this post.

Without Knockoutjs

Let us start with an application as given below. Application got two input box and a span to display a message.

image

Requirement of this application is as follows ,

  • Pull data from a data source. In this scenario data source is a plain JavaScript object.
  • Create a custom message.
  • Display message in label.
  • When data changes in input boxes notify back to data source.

Let us do it using jQuery and without Knockoutjs. Above view can be created simply as below,



 <h1>KO Demo</h1>   
     <span id="spnProductName">Product Name</span> <input type="text" id="txtProductName" />
     <span id="spnProductPrice">Product Price</span><input type="text" id="txtProductPrice" /><br />
    <h2> <span id="spnMessage"></span> </h2>   


A datasource can be created as plain JavaScript object. This can be created as below,


  var Product =
        {
            productName: "Pen",
            productPrice: 200
        };

Next we need to bind this data to input boxes element on DOM. This can be done using jQuery selectors. We need to select elements and assign values to elements.


    $("#txtProductName").val(Product.productName);
    $("#txtProductPrice").val(Product.productPrice);
    var message = Product.productName + " costs " + Product.productPrice;
    $("#spnMessage").text(message);


In above code snippet we are creating a custom message reading values from JavaScript object and then assigning that to span element on DOM.

This is what all we need to do. When you run application you should get elements are prepopulated with data from JavaScript object.

clip_image001

One major problem in above implementation is that if you change Product Name or Product Price, it will not get notified to data source. Here you are pulling data from the data source and there is no binding between elements and data source.

In simple words when you change value of Product Name or Product Price custom message will not change by default. Off course you can implement it using jQuery but that would be complex.

With Knockoutjs

Now let us implement above requirement using Knockoutjs. In Ko we need to create

  • Model
  • ViewModel
  • View

In this requirement we will create only ViewModel and View.

Step 1: Creating View

A View is nothing but HTML elements. So we can reuse view used in above example. But we need to use data-bind attribute of HTML5 to bind data from data source. For example if you want to display (bind) Product Name in first input box. To do this we will bind value attribute to productName (this is property representing Product Name in ViewModel)

image

We can create complete View of application as below,



<h1>With KO</h1>
     <span id="spnProductNamek">Product Name</span> 
    <input type="text" 
          id="txtProductNamek" 
           data-bind="value:productName" />

     <span id="spnProductPricek">Product Price</span>
    <input type="text" id="txtProductPricek" 
        data-bind="value : productPrice" />
    <br />
    <h2> <span id="spnMessagek" data-bind="text:message"></span> </h2>



You can see in View implementation that we are binding Product Name, Product Price and Message to different elements.

Step 2: Creating ViewModel

A ViewModel can be created as a simple JavaScript Objects. We need to keep in mind that to enable Two Way Binding properties of object should be as Knockout Observable. ViewModel can be created as follows,


 var ProductViewModel =
      {
          productName: ko.observable("Pen"),
          productPrice: ko.observable(200),
                 
      };


Next we need to create Message property as Computed Observable. Computed Observable can be created follows,

image

To create computed observable you need to pass a function and name of the ViewModel. Note that there are various ways to create ViewModel. For purpose of this post we followed this approach to add computed observable to ViewModel.

As last step we need to apply binding or link ViewModel to a Node on DOM. If you want to bind ViewModel to whole body then you can skip second parameter.

image

Putting above discussion together and full source code to create app using MVVM and KO are as follows


   var ProductViewModel =
      {
          productName: ko.observable("Pen"),
          productPrice: ko.observable(200),
                 
      };

    ProductViewModel.message= ko.computed(function () {
        var m = this.productName() +
                 " costs " +
                 this.productPrice();
        return m;
    }, ProductViewModel)

    ko.applyBindings(ProductViewModel)


Now let us go ahead and run application.

clip_image001[6]

In above application when you change value in any of the input boxes, immediately message in label will be changed.

So we witnessed that two way binding and automatic UI refresh is very simple to implement using Knockoutjs.  I hope you find this post useful. Thanks for reading.