How do I make knockoutJS react to property changes in real time?
The code below should do the following:
- When I enter a new name, it will show me "Welcome: xxx" in between.
- When I remove all characters in the textbox, nothing appears in the gap yet.
The problem is that when I delete one word (assuming the textbox value is "Bill Gates" by default) and I delete "Gates" I want the range to show me "Bill" in real time when I do not leave the field.
So how do you get KnockoutJS to support changes to the "Real Time" properties? I want to see the range change as I type instead of leaving the text box or hitting the Enter key.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Knock Out Sample</title>
</head>
<body>
Your Name, please: <input type="text" data-bind="value: myName" />
<br />
<span data-bind="text: myNameShown, visible: showWelcome" id="spName"></span>
</body>
<script src="KnockOutJS.js" type="text/javascript"></script>
<script type="text/javascript">
var model = {
myName: ko.observable("Bill Gates")
};
model.myNameShown = ko.dependentObservable(function () {
return "Welcome: " + model.myName();
}, model);
model.showWelcome = ko.dependentObservable(function () {
return model.myName() && model.myName().trim() != "";
}, model);
ko.applyBindings(model);
</script>
</html>
source to share
@ Luis answer using valueUpdate: 'afterkeydown'
in combination with binding value
works great, but if you are using Knockout 3.2 or higher, the preferred alternative answer is: use bindingtextInput
. This binding is more concise and handles cross-browser quirks. Use it like this:
ko.applyBindings({myName: ko.observable('initial value')});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
Input: <input type="text" data-bind="textInput: myName" />
<hr />
Result: <strong data-bind="text: myName"></strong>
To quote the aforementioned docs on the difference between textInput
and value
:
While value binding can also do two-way binding between text fields and viewmodel properties, you should prefer textInput whenever you need immediate realtime updates. The main differences are:
- Immediate updates [...]
- Working with events for the browser [...]
source to share
To force the binding to update in real time or on a key press, as opposed to when you leave the control (blur), use the binding update value with "afterkeydown", as described in the docs here:
http://knockoutjs.com/documentation/value-binding.html
So, in your input element, you will need to use the binding like this:
<input type="text" data-bind="value: myName, valueUpdate:'afterkeydown'" />
The spell is here:
source to share