positive numeric value in binding
by rniemeyer
HTML
<script src="http://knockoutjs.com/downloads/knockout-2.1.0.js"></script>
<div data-bind='template: { name: "personTemplate", foreach: persons }'>
<hr/>
<div data-bind="text: ko.toJSON(viewModel)"></div>
<script id='personTemplate' type='text/html'>
<div>
<input type="text" name="firstname" data-bind="value: firstname" />
<input type="text" name="lastname" data-bind="value: lastname" />
<input type="text" name="age" data-bind="positiveNumericValue: age" />
</div>
</script>
CSS
input { width: 75px; }
JavaScript
ko.bindingHandlers.positiveNumericValue = {
init : function(element, valueAccessor, allBindingsAccessor) {
var underlyingObservable = valueAccessor();
var interceptor = ko.computed({
read: underlyingObservable,
write: function(newValue) {
var current = underlyingObservable(),
valueToWrite = isNaN(newValue) ? 0 : parseFloat(+newValue);
if (valueToWrite < 0) {
valueToWrite = 0;
}
//only write if it changed
if (valueToWrite !== current) {
underlyingObservable(valueToWrite);
} else {
//if the rounded value is the same as it was, but a different value was written, force a notification so the current field is updated to the rounded value
if (newValue !== current) {
underlyingObservable.valueHasMutated();
}
}
}
});
ko.bindingHandlers.value.init(element, function() { return interceptor }, allBindingsAccessor);
},
update : ko.bindingHandlers.value.update
};
var viewModel = {
persons: ko.observableArray([{"firstname":"Kenneth","lastname":"None","age":ko.observable(37)},{"firstname":"Michael","lastname":"None","age":ko.observable(45)}]),
save: function() {
console.log('saving model with...');
console.log(ko.toJS(viewModel));
}
};
ko.applyBindings(viewModel);