JSFiddle - React, Tailwind, and code Playground

by Josh Carroll

HTML

<script src="http://github.com/downloads/SteveSanderson/knockout/knockout-1.2.1.js"></script>
<h3>Display</h3>
A: <input type="text" data-bind="value: a" /><br />
B: <input type="text" data-bind="value: b" /><br />
C: <input type="text" data-bind="value: c" /><br />
D: <input type="text" data-bind="value: d" /><br />
<br />
<h3>Actual</h3>
A: <span data-bind="text: a.val"></span><br />
B: <span data-bind="text: b.val"></span><br />
C: <span data-bind="text: c.val"></span><br />
D: <span data-bind="text: d.val"></span><br />

JavaScript

//wrapper for an observable that protects value until committed
ko.formattedObservable = function(initalValue) {
    //private variables
    var _backingField = ko.observable(initalValue);

    var result = ko.dependentObservable({
        read: function() {
            return _backingField().toPrecision(4);
        },
        write: function(newValue) {
            var parsed = parseFloat(newValue);
            _backingField(isNaN(parsed) ? newValue: parsed);
        }
    });

    result.val = _backingField;
        
    return result;
};

//Example of calculation view model
var viewModel = {
    a: ko.formattedObservable(0), 
    b: ko.formattedObservable(0), 
    c: ko.formattedObservable(0), 
    d: ko.formattedObservable(0), 
    calculate_d: function(){
        this.d.val(this.a.val() + this.b.val() + this.c.val());
    }
};

viewModel.a.subscribe(function() {
    this.b.val(this.a.val() * 0.001);
    this.calculate_d();
}, viewModel);

viewModel.b.subscribe(function() {
    this.c.val(this.b.val() * 3.145689393);
    this.calculate_d();
}, viewModel);

viewModel.c.subscribe(function(){
    this.calculate_d();
}, viewModel);

ko.applyBindings(viewModel);