JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<div id="vm1">
<input data-bind="value: MyExistingObservable" type="text"/>
<label data-bind="text: MyExistingObservable"></label>
</div>
<div id="vm2">
<input data-bind="value: MyExistingObservable" type="text"/>
<label data-bind="text: MyExistingObservable"></label>
</div>
JavaScript
ko.extenders.numeric = function(target, precision) {
//create a writeable computed observable to intercept writes to our observable
var result = ko.computed({
read: target, //always return the original observables value
write: function(newValue) {
var current = target(),
roundingMultiplier = Math.pow(10, precision),
newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
//only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
} else {
//if the rounded value is the same, but a different value was written, force a notification for the current field
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({ notify: 'always' });
//initialize with current value to make sure it is rounded appropriately
result(target());
//return the new computed observable
return result;
};
var data = {
MyExistingObservable : 0,
OtherVar: "test",
somethingelse: "foobar"
};
var mapping = {
'MyExistingObservable': {
create: function(options) {
return new ko.observable(options.data).extend({ numeric: null });
}
}
}
var vm = ko.mapping.fromJS(data,mapping);
ko.applyBindings(vm, document.getElementById('vm1'));
vm.MyExistingObservable(999.9);
var vm2 = ko.mapping.fromJS(data);
ko.applyBindings(vm2, document.getElementById('vm2'));
vm2.MyExistingObservable.extend({ numeric: null });
vm2.MyExistingObservable(999.9);