<input> lostfocus/onblur event in knockout

devC picture devC · Apr 19, 2013 · Viewed 36.1k times · Source

I want to execute an event on a knockout observable bound to an input. This function should be executed when the control lose focus, even without typing anything. I tried to change the event binding but it doesn't fire when the user moves away from the control without typing anything. I tried mouseout event, but that only fires when the user clicks elsewhere in the form, after losing focus - not exactly what I want. I want the even to fire as soon as the focus is moved away from the control, even with tab.

Following is the code I used for mouseout event:

<input
    type="text"
    id="txtFirstName"
    tabindex="1"
    maxlength="25"
    class="txtbox" 
    style="width: 200px;"
    data-bind="value: FirstName, 
               attr: {title: FirstNameErrorMessage },
               css: {validationFailed: !IsValidFirstName() },
               event: {mouseout: ValidateFirstName}" 
/>

this.ValidateFirstName = function () {
    self.IsValidFirstName(true);
    self.FirstNameErrorMessage('');
    if (self.FirstName() == '') {
        self.IsValidFirstName(false);
        self.FirstNameErrorMessage('First Name is required');
    }
}

Can anyone help please?

Answer

RP Niemeyer picture RP Niemeyer · Apr 19, 2013

I think that there are a few approaches that you could use. A nice option would be to use KO's hasfocus binding: http://knockoutjs.com/documentation/hasfocus-binding.html.

You can bind against a boolean observable, and then subscribe to it. In the subscription, you can choose to only react when the value is now false.

Something like:

self.FirstName = ko.observable();
self.FirstName.focused = ko.observable();

self.FirstName.focused.subscribe(function(newValue) {
   if (!newValue) {
       //do validation logic here and set any validation observables as necessary
   }
});

Bind against it like:

data-bind="value: FirstName, hasfocus: FirstName.focused"

I think that this would be a good option if you want it to fire everytime a user leaves the field no matter how they leave it and regardless of whether a change was actually made.