KnockoutJS - Event Binding


Advertisements

This binding is used to listen to specific DOM event and call associated with the handler function based on it.

Syntax

event: <{DOM-event: handler-function}>

Parameters

Parameter is inclusive of a JavaScript object, containing DOM event which will be listened to and a handler function which needs to be invoked based on that event. This function can be any JavaScript function and need not be necessarily ViewModel function.

Example

Let us take a look at the following example which demonstrates the use of event binding.

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Event Binding</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <p>Enter Number :</p>
      <input data-bind = "value: someValue , event: {keyup: showMessage}, 
         valueUpdate: 'afterkeydown' " /><br><br>
         You Entered: <span data-bind = "text: someValue"/>

      <script type = "text/javascript">
         function ViewModel () {
            this.someValue = ko.observable();
         
            this.showMessage = function(data,event) {
            
               if ((event.keyCode < 47) || (event.keyCode > 58 )) {  //check for number
                  if (event.keyCode !== 8)   //ignore backspace
                  alert("Please enter a number.");
                  this.someValue('');
               }
            }
         };
      
         var vm = new ViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Let's carry out the following steps to see how the above code works −

  • Save the above code in event-bind.htm file.

  • Open this HTML file in a browser.

  • Try to key in any non-numeric value and you will be prompted with an alert.

Observations

Passing a current item as a parameter to the handler function

KO will pass the current item as parameter when calling the handler function. This is useful when working with a collection of items and need to work on each of them.

Example

Let us take a look at the following example in which the current item is passed in event binding.

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Event Binding - passing current item </title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <ul data-bind = "foreach: icecreams">
         <li data-bind = "text: $data, event: { mouseover: $parent.logMouseOver }"> </li>
      </ul>
      <p>You seem to be interested in: <span data-bind = "text: flavorLiked"> </span></p>


      <script type = "text/javascript">
         
         function ViewModel () {
            var self = this;
            self.flavorLiked = ko.observable();
            self.icecreams = ko.observableArray(['Vanilla', 'Pista', 'Chocolate', 
               'Mango']);

            // current item is passed here as the first parameter, so we know which 
            // flavor was hovered over
            self.logMouseOver = function (flavor) {
               self.flavorLiked(flavor);
            }
         };
         
         var vm = new ViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Let's carry out the following steps to see how the above code works −

  • Save the above code in event-bind-passing-curr-item.htm file.

  • Open this HTML file in a browser.

  • Flavor, which has the mouse over it, is displayed.

  • Note that self as an alias is used for this. This helps to avoid any problems with this being redefined to something else in event handlers.

Passing more parameters, or referring the event object

There might be a situation where you need to access DOM event object associated with the event. KO passes the event as a second parameter to the handler function.

Example

Let us take a look a the following example in which the event is sent as a second parameter to function.

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Event Binding - passing more params</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <div data-bind = "event: { mouseover: logMouseOver }">
         Press shiftKey + move cursor over this line.
      </div>

      <script type = "text/javascript">
         function ViewModel () {
         
            self.logMouseOver = function (data, event) {
               if (event.shiftKey) {
                  alert("shift key is pressed.");
               } else {
                  alert("shift key is not pressed.");
               }
            }
         };
      
         var vm = new ViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Let's carry out the following steps to see how the above code works −

  • Save the above code in event-bind-passing-more-params.htm file.

  • Open this HTML file in a browser.

  • Press shiftKey + move cursor to the text. Observe that the message will pop up showing if you have pressed the shiftKey.

Allowing default action

Knockout will avoid the event from performing any default action, by default. Meaning if you use keypress event for an input tag, then KO will just call the handler function and will not add the key value to input elements value.

If you want the event to perform a default action, then just return true from the handler function.

Example

Let us look at the following example which allows default action to take place.

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Event Binding - allowing default action</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <p>Enter the flavor you like from available menu: (Vanilla, Pista, Chocolate, 
         Mango)</p>
      <input data-bind = "event: { keypress: acceptInput}"></input>

      <script type = "text/javascript">
         function ViewModel () {
            
            self.acceptInput = function () {
               return true;
            }
         };
         
         var vm = new ViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Let's carry out the following steps to see how the above code works −

  • Save the above code in event-bind-default-action.htm file.

  • Open this HTML file in a browser.

  • Any key pressed is actually shown in the input box because the handler function returns true.

Preventing the event from bubbling

KO will allow the event to bubble up to the higher level event handlers. Meaning if you have two mouseover events nested, then the event handler function for both of them will be called. If needed, this bubbling can be prevented by adding an extra binding called as youreventBubble and passing false value to it.

Example

Let us take a look at the following example in which bubbling is handled.

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Event Binding - preventing bubbling </title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <div data-bind = "event: { mouseover: myParentHandler }">
         <button data-bind = "event: { mouseover: myChildHandler }, 
            mouseoverBubble: false">Click me to check bubbling.</button>
      </div>

      <script type = "text/javascript">
         function ViewModel () {
            var self = this;
            
            self.myParentHandler = function () {
               alert("Parent Function");
            }

            self.myChildHandler = function () {
               alert("Child Function");
            }
         };
         
         var vm = new ViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Let's carry out the following steps to see how the above code works −

  • Save the above code in event-bind-prevent-bubble.htm file.

  • Open this HTML file in a browser.

  • Move the mouseover button and you will see a message. Bubbling is prevented due to the use of mouseoverBubble set to false.

knockoutjs_declarative_bindings.htm
Advertisements