In my previous knockout.js post, I just gave introduction and explained how knockout works. We learnt about how knockout uses bindings to make UI dynamic and how it connects to the view model

In this article we will learn custom binding. There are built in bindings like click, value, text, visible and so on. But you are not restricted to use only those binding , you can create your own custom binding.

It’s always better to create custom binding for DOM elements instead of writing jquery. Advantage of creating custom binding is, you can reuse it for any number of DOM elements.
You can use third party javascript libraries with custom binding.

Once you create custom binding, you can use it like any other built-in bindings for any number of DOM element.

<div data-bind=”bindingName:value”></div>

Let’s first go through syntax for creating custom binding :

ko.bindingHandlers.BindingName={
init : function(element,valueAccessor,allBindings,viewModel,bindingContext)
{
	//Code Here
},
update : function(element,valueAccessor,allBindings,viewModel,bindingContext)
{
	//Code Here
}
} 

Well knockout binding Handler has two handlers init and update. It is not necessary to call both the handlers for each binding. You may need both the handlers or anyone can help to achieve your desired outcome.

Lets see what this two calls handle:

init : This is called, when binding is first applied to DOM element. You can write code relating to initialing states of DOM element, adding event handlers

update : This is called, when binding is first applied to DOM element as well as when there is any change in observable occurs. It changes the state of DOM elements based on changes in observables value.

You can see both init and update have no. of parameters, let’s see what is the use of each parameters:

element : This is nothing but a DOM element on which binding is applied. you can directly write jquery to this element, need not to lookup for element

valueAccessor : This is the value assigned to binding. It can be observable or any expression. In order to access this value, you have to call ko.unwrap. It removes the wrapper over the values assigned.

allBindings : DOM elements can have more than one bindings assigned to it. In order to access these bindings you can use allBindings. Custom binding has functions like get to retrive value from one of the bindings assigned to it or has to check whether binding exists for current element
(e.g. if data-bind =”value:name, tooltip:tooltipText” then get(“tooltip”) will return tooltipText)

viewModel : knockout deprecated this parameter. You can now access it as bindingContext.$data.

bindingContext : Its object that holds context for current element’s binding. This can be use to access ancestors bound to the context. You can use $parent, $parents, $root to access parents data

Modal is displayed using bootstrap and jquery. Let’s take example of modal custom binding we used in our project

ko.bindingHandlers["modal"] = {
    init: (element, valueAccessor, allBindings, viewModel) => {
    // Setting show modal to false at initial state
        $(element).modal({
            show: false,
            keyboard: false,
            backdrop: 'static'
        });
    }
}

As I explained, init is called for initialing states, add event handlers etc. You can see in code, modal’s show property is set to false as we don’t want modal to appear on page load

update: (element, valueAccessor, allBindings, viewModel) => {
    //Whenever value of observable assigned to binding changes update gets called
        var value = valueAccessor();
        //Will contain observable assigned to binding
        //Shows modal when value is true else hides it
        if (ko.utils.unwrapObservable(value)) {
            $(element).modal({
                show: true,
                keyboard: false,
                backdrop: 'static'
            });
        }
        else {
            $(element).modal('hide');
        }
    }

Update handler gets called when first time binding applied to element and later when there is change is observable assigned to binding . As you can see in code, observable's value is unwrapped from valueAccessor . Based on this value, modal is shown or hide

You can assign modal binding as

<div data-bind="modal:modalbox"></div>

You can refer jsfiddle of the same example at below link

https://jsfiddle.net/VipulS/yrnuhch8/

You can find some more sample code for custom binding at my jsfiddle

Thanks for reading, hope this article added some knowledge for you as well as me ;)

References: