22

I am working on a website that auto populates search result in a table after user entered some text in the input text box (similar to google instant search).

I managed to get knockout js to update view model as user enters information by adding

valueUpdate: 'afterkeydown'

into my data-bind attribute, however, I also need to handle the case where user right click and paste some text into the textbox so I tried:

valueUpdate: ['afterkeydown','mouseup']

but that didn't work and when I tried to read the value of the text box through the view model I kept getting the old value until I tab out of the input text box.

Anyone know how can I fix this?

Oscar

oscarkuo
  • 10,431
  • 6
  • 49
  • 62
  • Knockout now has a new binding for this. See my answer below. http://stackoverflow.com/a/19957131/143739 – kzh Sep 11 '14 at 18:30

2 Answers2

27

You can use valueUpdate:'input'. I have testet it to work in Opera, Firefox and Chrome. I'm on a Linux box, so I can't test it in IE. Check this fiddle

UPDATE: I have now testet it in IE8, and it doesn't work. But using the following seems to work.

valueUpdate:['afterkeydown','propertychange','input']

Thanks to Michael Best for his comment about this :) I have updated the fiddle

UPDATE okt 2014: As kzh mention in a comment below, in one of the later versions of Knockout.js the textInput binding was added. This binding handles this scenario and has build in browser quirks handling http://knockoutjs.com/documentation/textinput-binding.html

aaberg
  • 2,253
  • 15
  • 14
  • 8
    `valueUpdate: ['afterkeydown','propertychange','input']` covers all the bases (except deleting using the mouse in IE9 which doesn't fire any event and so can't be handled). – Michael Best Jun 20 '12 at 01:31
  • There is now the textInput binding. – kzh Oct 24 '14 at 19:35
10

New Way

Instead of:

data-bind="value: myValue, valueUpdate: ['input', 'textchange']"

One can now use the textInput binding:

data-bind="textInput: myValue"

From the documentation:

The textInput binding links a text box (<input>) or text area (<textarea>) with a viewmodel property, providing two-way updates between the viewmodel property and the element’s value. Unlike the value binding, textInput provides instant updates from the DOM for all types of user input, including autocomplete, drag-and-drop, and clipboard events.

Old Way

valueUpdate: ['afterkeydown','propertychange','input']

Does not work in IE9 if you want to support RightMouseClickDelete or RightMouseClickCut.

The solution I came up with involves using jQuery and a jQuery plugin called jQuery Splendid Textchange. After you have both the jQuery and the plugin scripts loaded, you can happily use the 'textchange' event.

valueUpdate: 'textchange'

But, I may one day stop supporting bad browsers, so I have this:

valueUpdate: ['input', 'textchange']

Here is a fiddle I made for testing this and other events: http://jsfiddle.net/kaleb/w3ErR/

N.B. If you are using requirejs, jquery may have to be a hard dependency of knockout for this to work properly all the time.

kzh
  • 19,810
  • 13
  • 73
  • 97
  • "New Way" (i.e. textInput binding) starts working from v3.2.0 of Knockout, see http://blog.stevensanderson.com/2014/08/18/knockout-3-2-0-released. So if you use older version, it's probably time to update. – Evereq Oct 05 '15 at 15:57