Skip to content

Bootstrap multiselect blur event not triggering

I’m trying to do some logic after user completes a selection and moves away from a bootstrap multi-select dropdown.

I tried hooking into the blur event:

      <select id="select1" multiple="multiple" class="form-control" data-bind="options: availableValues, selectedOptions: selectedValues, multiselect: {
    includeSelectAllOption: true
  }, event: { blur: $root.onBlur}">
      </select>  

Defining a onBlur function in my viewModel:

onBlur: function(){
    alert('OnBlur');
}

But it never kicks-in. I even tried setting the event binding directly without the $root.onBlur, just blur: onBlur but didn’t work.

Here is a sample JS fiddle:

https://jsfiddle.net/gtzatrL2/

Am I missing something? or is the blur event not applicable to bootstrap multi-selects?

The reason I want to hook into blur is because I have some backend logic to do through Ajax after ALL items have been selected. If I subscribe to my observableArray changes it will trigger my backend call for each item added which is not what I want.

Answer

Bootstrap is actually hiding the original select element and showing a div in its place, so the blur on the select never gets hit because it isn’t being focused in the first place.

I think because the bootstrap controls are using divs it might be impossible to support blur at all because divs aren’t normally focusable. There are a couple of workarounds but it might not work in this particular case. See How to blur the div element?

One option instead – you could rate-limit your observableArray so that the subscription doesn’t fire immediately every time an option is selected. This will also reduce the backend calls, but it does not guarantee it won’t fire before the user is finished.

http://knockoutjs.com/documentation/rateLimit-observable.html

this.selectedValues = ko.observableArray().extend({ rateLimit: { timeout: 500, method: "notifyWhenChangesStop" } });

this.selectedValues.subscribe(function() {
    alert("BLUR: " + this.selectedValues().length + " elements selected");
});