I just came across the issue that if I have an HTML5 input element with type
set to number
and data-bind="textInput ..."
then the resulting binding value is a string. I would like to avoid converting each single string to a number as this would trigger all dependent subscriptions of the observables and lead to recursive calls. As a workaround I followed these instructions use enable the valueAsNumber property within the ko.selectExtensions.readValue function that is used by the value
binding.
Unfortunaltey I don't know how to do the same with the textInput
binding, and therefore I would like to know if such an integration is planned for future.
I'm sure a good chunk of the code below came from SO, here or the newsgroup. Anyway, here's what we use in our project.
It could probably do with some options about how you'd like to behave when presented with non-numeric input. For example, do you keep the old value, force to undefined, force to NaN, ignore it...?
//A binding handler that uses a textInput binding, only accepting numeric input for writing
ko.bindingHandlers.numericInput = {
init: function (element, valueAccessor, allBindings, data, context) {
var interceptor = ko.computed({
read: function () {
return ko.unwrap(valueAccessor());
},
write: function (value) {
var writer = valueAccessor();
if (!ko.isObservable(writer)) {
console.warn('Non ob used with numeric input - cannot store', value);
return;
}
if (value === ""){
valueAccessor()(0);
} else if (!isNaN(value)) {
valueAccessor()(parseFloat(value));
}
},
disposeWhenNodeIsRemoved: element
});
ko.applyBindingsToNode(element, { textInput: interceptor }, context);
}
};
Thanks, I will try it! But still I would prefer direct support of HTML5 numeric fields.
It is not as trivial as you might think. input[type=number]
valueAsNumber
is horribly broken in MS Edge - it always throws an exception. You may want to implement a solution for that as well.
Most helpful comment
I'm sure a good chunk of the code below came from SO, here or the newsgroup. Anyway, here's what we use in our project.
It could probably do with some options about how you'd like to behave when presented with non-numeric input. For example, do you keep the old value, force to undefined, force to NaN, ignore it...?