Reputation: 5721
When adding a change event binding to an input box using knockout.js the old value is passed to the change function when the event is fired. I can work around this by using blur. Is this the intended behavior? Is the idea to use the change event to have the old value and then use a normal selector to get the value from the dom? It seems counter intuitive.
JavaScript
----------
var data = {
saved_value:"1",
value_changed: function(data){
alert(data.saved_value());
}
};
var viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
HTML
----
Current Value:<span data-bind="text:saved_value"></span><br/>
<input data-bind="event:{change:value_changed},value:saved_value"></input>
Upvotes: 38
Views: 77692
Reputation: 60021
Update: For newer versions of knockout, you can replace the value binding with textInput, which handles many edge cases not covered by valueUpdate
.
No, this is not the right way to do things.
You're getting the old value because saved_value doesn't get updated until the textbox loses focus.
If you want to push the new value in as the user types, using the valueUpdate option of the input binding:
<input data-bind="event: { change: value_changed }, value: saved_value, valueUpdate: 'afterkeydown'" />
The valueUpdate option takes an event name (e.g. 'keyup'). When that event fires, your saved_value will be updated.
Now let me propose an alternate solution.
Still do the valueUpdate binding like I showed above, but instead of listening for the changed event, just subscribe to the observable:
<input data-bind="textInput: saved_value" />
Then in JS:
var viewModel = {
saved_value: ko.observable("1"),
};
viewModel.saved_value.subscribe(function (newValue) {
alert(data.saved_value());
});
ko.applyBindings(viewModel);
Upvotes: 82
Reputation: 39
Try this in the data bind write event handlers, after the value handlers and not before:
<input data-bind="value: property, event:{ change: doSomething}" />
Upvotes: 3
Reputation: 139
If you put the 'event' option at the end you don't need the 'valueUpdate' option. Like this:
<input data-bind="value: saved_value, event: { change: value_changed }" />
Also note that when you make use of subscribe to an observable, it gets triggered every time your value changes. (either by user interaction or programmatically).
Upvotes: 13
Reputation: 5813
Try using the text and value bindings:
Current Value:<span data-bind="text: saved_value"></span><br/>
<input data-bind="value: saved_value"></input>
And change the JavaScript to this:
var data = {
saved_value: "1"
};
var viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
Here's an associated jsFiddle: http://jsfiddle.net/6zmJs/
If you want to alert()
the value of saved_value
when it is updated you could use ko.computed
or viewModel.saved_value.subscribe(function(value) { alert(value); });
-- although those aren't the only ways to do this.
Upvotes: 8