Beginners Guide to KnockoutJS: Part 2

Share this article

A Beginners Guide to KnockoutJS: Bindings

Knockout provides a whole set of useful built-in bindings for the most common tasks and scenarios. Each of these bindings allows you to bind simple data values or use JavaScript expressions to calculate the appropriate value. This provides a lot of flexibility and makes it easy to create very dynamic UIs with minimum effort.

The syntax for using the built-in bindings is to include the Knockout binding name and the view model property pairs inside of the data-bind attribute of an HTML element.

// syntax: data-bind="bindingName: bindingProperty"
<span data-bind="text: msg"></span>

If you want to data bind to more than one property in the HTML element, simply separate the bindings by a comma using this syntax:

<span data-bind="text: msg, visible: toggle"></span>

You should bear in mind that the most of the bindings attempt to convert any parameter to a boolean value. If you give a value that isn’t actually boolean, it will be interpreted loosely as truthy or falsy. This means that nonzero numbers and non-null objects and non-empty strings will all be interpreted as true, whereas zero, null, undefined, and empty strings will be interpreted as false.

If you understand how to use one type of data binding, then the others should be pretty easy to learn. Now we are going to explain each one of them by providing a description and short example.

Simple Bindings

We’ve already seen text binding when dealing with observables in the previous tutorial. It sets the text of the associated element to the value of your parameter. This is the equivalent of setting the innerText(for IE) or textContent (for other browsers) property of the DOM element. If your parameter is something other than a number or string then the binding will assign the results of toString() to the element.

If this parameter is an observable value, the binding will update the element’s text whenever the value changes. If the parameter isn’t observable, it will only set the element’s text once and will not update it again later. This is valid for all bindings.

The text binding is often used to display values in a span or div element. When it is used, any previous text will be overwritten.

<p>The tip of the day is: <span data-bind="text: tipOfTheDay"></span></p> 

function viewModel() {
 var self = this;
 self.tipOfTheDay = ko.observable('Relax.Take it easy!')
};
ko.applyBindings(new viewModel());

value binding sets the value of the associated element to the value of your parameter. This is typically used for form elements like input, select and textarea. When the user edits the value in the associated form control, it updates the value on your view model. Likewise, when you update the value in your view model, this updates the value of the form control on screen. This is known as two-way binding. If your parameter is something other than a number or string then the binding will assign the results of toString() to the element.

By default, Knockout updates your view model when the user transfers focus to another DOM node, on the change event, but you can control when the value is updated using the valueUpdate parameter described below. If your binding also includes a parameter called valueUpdate, this defines which browser event Knockout should use to detect changes.

"change" is the default event and it updates your view model when the user moves the focus to a different control, or in the case of <select> elements, immediately after any change.

"afterkeydown" – updates your view model as soon as the user begins typing a character. This works by catching the browser’s keydown event and handling the event asynchronously. If you want to keep your view model updated in real-time using "afterkeydown" will be the best choice.

"keyup" – updates your view model when the user releases a key

"keypress" – updates your view model when the user has typed a key. This updates repeatedly if the user holds a key down

<input data-bind="value: name, valueUpdate: 'afterkeydown'"></input>
<p data-bind="text: name"></p>

function viewModel() {
 var self = this;
 self.name = ko.observable()
};
ko.applyBindings(new viewModel());

Control Mark Up

The html binding isn’t used as often, but it’s very handy for rendering HTML content in your view model. This binding sets the HTML of the associated element to the value of your parameter and is the equivalent of setting the innerHTML property on the DOM element. If your parameter is something other than a number or string then the binding will assign the results of toString() to the element.

Since this binding sets your element’s content using innerHTML, you should be careful not to use it with untrusted model values, because that might open the possibility of a script injection attack. If you cannot guarantee that the content is safe to display, then you can use the text binding instead.

<div data-bind="html: markup"></div>

function viewModel() {
 var self = this;
 self.markup = ko.observable('<p><strong>Knockout</strong> is so <em>cool</em>!</p>')
};
ko.applyBindings(new viewModel());

While Knockout has many built-in bindings, you will surely encounter some situations for which none exist. For those, Knockout offers the attr binding, which allows you to data bind any attribute to a view model property. The parameter should be a JavaScript object where the property names are the attributes and the property values are the value that will be bound to the attribute. This is very useful in many common scenarios, such as binding the href and title of the a element or the src and alt of the img element.

<img data-bind="attr: {src: url, alt: details}" />

function viewModel() {
 var self = this;
 self.url = ko.observable(images/logo.png)
 self.details = ko.observable('This is logo')
};
ko.applyBindings(new viewModel());

Add Styling

You can bind styles with Knockout using the css and the style built-in bindings.

css binding sets one or more CSS classes for the associated element. The parameter should be a JavaScript object where the property names correspond to the desired CSS classes and the property values evaluate to true or false indicating whether the class should be applied. You can set multiple CSS classes at once.

<style>
.colorize {color: red}
</style>

<p data-bind="css: { colorize: on }">Text</p>

function viewModel() {
 var self = this;
 self.on = ko.observable(true)
};
ko.applyBindings(new viewModel());

You can use an expression to determine when the class will be applied.

<p data-bind="css: { colorize: on() > 3 }">Text</p>

While it is better to use css classes whenever possible, at times you might want to set a specific style as well. Knockout supports this with its style built-in binding which sets one or more style values for the associated element. The parameter should be an object whose properties correspond to CSS styles names, and the values correspond to the style values you wish to apply. Typically this parameter value is declared using JSON.

<p data-bind="style: {color: on() > 3 ? 'red' : 'black'}">Text</p>
function viewModel() {
 var self = this;
 self.on = ko.observable(5)
};
ko.applyBindings(new viewModel());

Note: When you have an attribute or CSS class whose name is not legal JavaScript variable name then you should wrap the identifier name in quotes so that it becomes a string literal. And if you want to apply style whose name isn’t a legal JavaScript identifier, you must use the JavaScript name for that style.

//incorrect:
<div data-bind="attr: { data-something: someValue }">...</div>
<div data-bind="css: { my-class: someValue }">...</div>
<div data-bind="style: { font-weight: someValue }">...</div>

//correct:
<div data-bind="attr: { 'data-something': someValue }">...</div>
<div data-bind="css: { 'my-class': someValue }">...</div>
<div data-bind="style: { fontWeight: someValue }">...</div>

Handling Events

Knockout supports binding to any event through its event built-in binding. It adds event handlers for the specified events to the associated DOM element. You can use this to bind to any defined HTML events. Within your event handler you can access the current view model data item, the event object, or even custom parameters passed as part of the event binding. To use event binding, you pass an object literal containing name value pairs for the event name and the view model method, separated by commas.

<p data-bind="event: { mouseover: hello, mouseout: goodbye }"> Mouse over me! </p>
<p data-bind="text: helloEnabled"></p>
<p data-bind="text: goodbyeEnabled"></p>

function viewModel() {
var self = this;
self.helloEnabled = ko.observable()
self.goodbyeEnabled = ko.observable()
 self.hello = function() {
 self.helloEnabled('Hello!');
 self.goodbyeEnabled('');
 }
 self.goodbye = function() {
 self.goodbyeEnabled('Goodbye!');
 self.helloEnabled('');
 }
};
ko.applyBindings(new viewModel());

click binding, as you may guess, is handling the click event. Because it is the most-used binding for events, it’s simply a shortcut to the event binding.

<button data-bind="click: writeMSG">Show</button>
<p data-bind="text: msg"></p>

function viewModel() {
 var self = this;
 self.msg = ko.observable()
 self.writeMSG = function() {
 self.msg('Hello!')
 }
};
ko.applyBindings(new viewModel());

submit binding is a shortcut for handling the submit event for the form element. When you use the submit binding on a form, Knockout will prevent the browser’s default submit action for that form. In other words, the browser will call your handler function but will not submit the form to the server. This is a useful default because when you use the submit binding, it’s normally because you’re using the form as an interface to your view model, not as a regular HTML form. If you do want to let the form submit like a normal HTML form, just return true from your submit handler.

Instead of using submit on the form, you could use click on the submit button. But using submit binding gives you the benefits of using alternative ways to submit the form, such as pressing the enter key while typing into a text box.

Controling UI

visible binding sets the visibility of the associated element based on the binding parameter value. The binding attempts to convert any parameter to a boolean value. Knockout’s visible binding should be bound to a property that evaluates to true or false. This takes priority over any display style you’ve defined using CSS.

<button data-bind="click: show">Show Message</button>
<button data-bind="click: hide">Hide Message</button>
<p data-bind="visible: msg">Hello, Knockout!</p>

function viewModel() {
 var self = this;
 self.msg = ko.observable()
 self.show = function() {
 self.msg(true)
 }
 self.hide = function() {
 self.msg(false)
 }
};
ko.applyBindings(new viewModel());

enable/disable binding sets the disabled attribute on the associated element based on the supplied value. This is typically used for form elements like the input, select and textarea. Knockout provides built-in bindings to enable and disable input elements. The enable binding will enable the input element if the property it’s bound to evaluates to true, and will disable the element if it evaluates to false. The disable binding does the exact opposite

<input data-bind="value: val, valueUpdate: 'afterkeydown'">
<button data-bind="enable: val">Send</button>

function viewModel() {
 var self = this;
 self.val = ko.observable()
};
ko.applyBindings(new viewModel());

Knockout has a built-in binding named hasfocus that determines and sets which element has the focus. The hasfocus binding is handy when you want the focus to be set to a specific element on a form for example search form when visitor open the page

<input data-bind="value: val, hasfocus: on"> 
<button data-bind="enable: on">Send</button>
function viewModel() {
 var self = this;
 self.val = ko.observable()
 self.on = ko.observable(false)
};
ko.applyBindings(new viewModel());

Dealing with Checkboxes and Radio Buttons

Checkboxes can be data bound to Knockout’s checked binding. The checked binding should be bound to a property or expression that evaluates to true or false. Because the view model properties are defined as observables, the checkbox is updated when the source property changes. Likewise, when a user checks or unchecks the checkbox, the value is updated in the view model property. This binding sets the checked state of radio buttons and checkboxes. For checkboxes, the binding attempts to convert any parameter into a boolean value. For radio buttons, the binding compares the buttons value attribute to the binding parameter.

<p>Let me choose my favorite car: <input type="checkbox" data-bind="checked: car" /></p>
<div data-bind="visible: car">
 Preferred model:
 <div><input type="radio" name="modelsGroup" value="ferrari" data-bind="checked: model" /> Ferrari</div>
 <div><input type="radio" name="modelsGroup" value="lamborghini" data-bind="checked: model" /> Lamborghini</div>
 <div><input type="radio" name="modelsGroup" value="bugatti" data-bind="checked: model" /> Bugatti</div>
</div>

function viewModel() {
 var self = this;
 self.car = ko.observable(),
 self.model = ko.observable("lamborghini") // Initially selects Lamborghini
};
ko.applyBindings(new viewModel());

Creating Dropdown Lists

Dropdown lists have several important properties to load a list of items, display a value, use a different key value and store the user’s selection. Knockout provides a built-in binding for each of these. options binding sets the options which will appear in a drop-down list element. The value should be an array. This binding cannot be used with anything other than <select> elements. For a multi-select list, to set which of the options are selected, or to read which of the options are selected, use the selectedOptions binding. For a single-select list, you can also read and write the selected option using the value binding.

The options binding identifies a list of values to display, usually from an array property on the view model.

<p>Choose your destiny: <select data-bind="options: availableRoles"></select></p>

function viewModel() {
 var self = this;
 self.availableRoles = ko.observableArray(['an artist', 'an actor', 'an author'])
};
ko.applyBindings(new viewModel());

The selectedOptions binding controls which elements in a multi-select list are currently selected. When the user selects or de-selects an item in the multi-select list, this adds or removes the corresponding value to an array on your view model.

<p>Choose your destiny: <select data-bind="options: availableRoles, selectedOptions: selected" multiple="true"></select></p>

function viewModel() {
 var self = this;
 self.availableRoles = ko.observableArray(['an artist', 'an actor', 'an author'])
 self.selected = ko.observableArray(['an author'])
};
ko.applyBindings(new viewModel());

Sometimes you want to display one value in the dropdown list but use another value when a user selects an item from the list. Knockout’s built-in optionsText and optionsValue bindings help. The optionsText binding is set to the string name of the property to display in the dropdown list, from the options binding. The optionsValue binding is set to the string name of the property to bind to for the selected value of the item in the dropdown list. optionsCaption is useful when you don’t want to have any prticular option selected by default. This parameter set a text such as ‘Select an item…’ on top of the options list and show it when there isn’t any particular item selected.

<p>Locales: <select data-bind="options: locales, selectedOptions: selected, optionsCaption: 'Select your locale...', optionsText: 'country', optionsValue: 'code'"></select></p>
<p data-bind="text: selected"></p>

function viewModel() {
  var self = this;
  self.locales = [
   { country: 'USA', code: 'en_US' },
   { country: 'Spain', code: 'es_ES' },
   { country: 'French', code: 'fr_FR' }
  ]
  self.selected = ko.observableArray();
 }
ko.applyBindings(new viewModel()); 

And that’s all for this part, stay tuned for the finale, same time next week!

Frequently Asked Questions about KnockoutJS

What is the difference between KnockoutJS and other JavaScript libraries?

KnockoutJS is a JavaScript library that helps developers to create rich, responsive display and editor user interfaces with a clean underlying data model. Unlike other JavaScript libraries, KnockoutJS uses a Model-View-ViewModel (MVVM) design pattern where the model and view are separated, making it easier to manage complex data-driven interfaces. It also provides automatic UI refresh when the data model changes and offers declarative bindings for connecting parts of the UI to the data model.

How does KnockoutJS handle data binding?

KnockoutJS uses a system of declarative bindings for connecting parts of the UI to the data model. This means you can easily bind data to HTML elements in a way that’s easy to understand and maintain. When the data model changes, KnockoutJS automatically updates the relevant parts of the UI, eliminating the need for manual DOM manipulation.

Can KnockoutJS work with other JavaScript libraries?

Yes, KnockoutJS can work alongside other JavaScript libraries. It doesn’t make any assumptions about the rest of your technology stack, so it can be integrated with other libraries or frameworks such as jQuery, Bootstrap, or even AngularJS.

How does KnockoutJS handle CSS binding?

KnockoutJS provides a ‘css’ binding that allows you to add or remove one or more named CSS classes to the associated DOM element. This binding is particularly useful when you want to conditionally apply a CSS class to an element based on some data condition.

What are observables in KnockoutJS?

Observables are special JavaScript objects that can notify subscribers about changes, and automatically detect dependencies. This feature is fundamental to KnockoutJS, as it allows the library to automatically update the right parts of the UI whenever the data model changes.

How can I use KnockoutJS with server-side technologies?

KnockoutJS can be used with any server-side technology. It’s agnostic to the server-side language you use, so you can use it with PHP, .NET, Java, Ruby, Python, or any other server-side language. You just need to send JSON data to the client and then use KnockoutJS to bind this data to your HTML.

How does KnockoutJS handle form validation?

KnockoutJS itself does not provide any built-in validation mechanisms. However, it can be easily integrated with other validation libraries such as jQuery Validation or Knockout-Validation, a separate plugin specifically designed for form validation in KnockoutJS.

Can I use KnockoutJS for mobile app development?

While KnockoutJS is primarily designed for web development, it can also be used in mobile app development in combination with other technologies like PhoneGap or Cordova, which allow you to create native apps using HTML, CSS, and JavaScript.

How does KnockoutJS handle event handling?

KnockoutJS provides a ‘click’ binding that allows you to respond to the user’s click event. It also provides other event bindings such as ‘event’, ‘submit’, ‘enable’, ‘disable’, ‘hasfocus’, and more. These bindings make it easy to handle user interactions in a declarative way.

Is KnockoutJS suitable for large-scale applications?

Yes, KnockoutJS is suitable for both small and large-scale applications. Its MVVM design pattern makes it easier to manage complex data-driven interfaces, and its system of observables and bindings helps to keep the code organized and maintainable, even for large applications.

Ivaylo GerchevIvaylo Gerchev
View Author

I am a web developer/designer from Bulgaria. My favorite web technologies include SVG, HTML, CSS, Tailwind, JavaScript, Node, Vue, and React. When I'm not programming the Web, I love to program my own reality ;)

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week