Reputation: 351
I've got a text field that is bound to an observable:
<input type="text" data-bind="value: chartOptions.zoomLevel" value="100%" />
This works fine, except that the field needs to lose focus before the observable is updated. What I need is to update that the observable only changes when the enter key is pressed.
I've looked at the possible valueUpdate parameters, but none of them seem to be suitable.
Upvotes: 2
Views: 2158
Reputation: 18922
Here's a polyfill that may help - forces IE to fire 'change' event on enter
key (as other browsers do) which in turn triggers Knockout's value
binding.
var isIE = !!document.documentMode;
if (isIE) {
$("body").on("keydown", "input[type='text']", function (e) {
// Ensure 'value' binding is fired on enter in IE
if ((e.keyCode || e.which) === 13) {
$(this).blur();
}
});
}
Upvotes: 0
Reputation: 63699
There's probably a way to do this with custom bindings, but here's a straightforward way to do it using the event
binding. You seem to imply that the observable should only change iif the enter key is pressed. However, I've added the blur
event as a trigger too; it's easy to remove that anyhow.
var ViewModel = function() {
var self = this;
self.zoomLevel = ko.observable('100');
self.newZoomLevel = ko.observable('100');
self.tryCommitZoomLevel = function(data, event) {
if (event.keyCode === 13 || event.type === "blur") {
self.zoomLevel(event.target.value);
}
// Make sure the event bubbles to let the value binding also handle events:
return true;
};
};
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="text" data-bind="event: { keypress: tryCommitZoomLevel, blur: tryCommitZoomLevel }, value: newZoomLevel" />
<br />
The zoom level you've entered is: <strong data-bind="text: zoomLevel"></strong>%
The snippet keeps a seperate "new value" copy of the actual observable, and only commits it if the user presses enter or the input looses focus.
Upvotes: 1