<!DOCTYPE html> <html> <head> </head> <body class='ui-widget'> <header class='ui-widget-header'> <h1>Give me all of your money</h1> </header> <div class='ui-widget-content'> <p> <label>How much in Cash?</label><input data-bind="value:Cash.formatted,css:{negative:Cash.isNegative}" /> </p> <p> <label>How much in Checks?</label><input data-bind="value:Check.formatted,css:{negative:Check.isNegative}" /> </p> <p> <label>Total:</label><span data-bind="text:Total.formatted,css:{negative:Total.isNegative}" /> </p> <p> <button data-bind="click:showJSON">Show View Model JSON</button></p> </div> </body> </html>
(function(){ var format = function(value) { toks = value.toFixed(2).replace('-', '').split('.'); var display = '$' + $.map(toks[0].split('').reverse(), function(elm, i) { return [(i % 3 === 0 && i > 0 ? ',' : ''), elm]; }).reverse().join('') + '.' + toks[1]; return value < 0 ? '-' + display : display; }; ko.subscribable.fn.money = function() { var target = this; var writeTarget = function(value) { var stripped=value .replace(/[^0-9.-]/g, ''); target(parseFloat(stripped)); }; var result = ko.computed({ read: function() { return target(); }, write: writeTarget }); result.formatted = ko.computed({ read: function() { return format(target()); }, write: writeTarget }); result.isNegative = ko.computed(function(){ return target()<0; }); return result; }; })(); //Wire it up $(function() { var viewModel = { Cash: ko.observable(-1234.56).money(), Check: ko.observable(2000).money(), showJSON: function() { alert(ko.toJSON(viewModel)); } }; viewModel.Total = ko.computed(function() { return this.Cash() + this.Check(); }, viewModel).money(); ko.applyBindings(viewModel); });