<!DOCTYPE html> <html> <head> </head> <body class='ui-widget'> <header class='ui-widget-header'> <h1>"Fun" Run</h1> </header> <div class='ui-widget-content'> <label>Laps Run</label><input data-bind="value:LapsRun" /> <table> <thead> <tr> <th>Name</th> <th>Pledge Per Lap</th> <th>One Time Donation</th> <th>Amount Owed</th> <th>Is Collected?</th> </tr> </thead> <tbody data-bind="template:{name:'sponsorLine',foreach:Sponsors}"> <tr class="ui-state-highlight" data-bind="visible:NoSponsors"><td colspan=5>No Sponsors.</td></tr> </tbody> <tfoot data-bind="template:{name:'totalLine',data:Totals}" /> </table> <button data-bind="click:AddSponsor">Add a Sponsor</button> </div> </body> <script type='text/html' id="sponsorLine"> <tr> <td><input data-bind="value:Name" /></td> <td><input data-bind="value:PledgePerLap" class="money"/></td> <td><input data-bind="value:OneTimeDonation" class="money"/></td> <td data-bind="text:AmountOwed"></td> <td><input type="checkbox" data-bind="value:IsCollected" /></td> </tr> </script> <script type='text/html' id="totalLine"> <tr> <td>Total</td> <td data-bind="text:PledgePerLap"></td> <td data-bind="text:OneTimeDonation"></td> <td data-bind="text:AmountOwed"></td> <td data-bind="text:AmountCollected"></td> </tr> </script> </html>
var Sponsor = function(parent) { $.extend(this, { Name: ko.observable(), PledgePerLap: ko.observable(0), OneTimeDonation: ko.observable(0), IsCollected: ko.observable(false) }); this.AmountOwed = ko.dependentObservable(function() { return this.PledgePerLap() * parent.LapsRun() + parseFloat(this.OneTimeDonation()); }, this); }; var sum = function(values, func) { var total = 0; $.each(values, function(i, o) { total += parseFloat(func(o)); }); return total; }; var viewModel = { LapsRun: ko.observable(0), Sponsors: ko.observableArray([]), AddSponsor: function() { this.Sponsors.push(new Sponsor(viewModel)); } }; viewModel.NoSponsors= ko.dependentObservable(function(){ return this.Sponsors().length === 0; },viewModel); viewModel.Totals = { PledgePerLap: ko.dependentObservable(function() { return sum(this.Sponsors(), function(o) { return o.PledgePerLap() }); }, viewModel), OneTimeDonation: ko.dependentObservable(function() { return sum(this.Sponsors(), function(o) { return o.OneTimeDonation() }); }, viewModel), AmountOwed: ko.dependentObservable(function() { return sum(this.Sponsors(), function(o) { return o.AmountOwed() }); }, viewModel), AmountCollected: ko.dependentObservable(function() { return sum(this.Sponsors(), function(o) { return o.IsCollected() ? o.AmountOwed() : 0 }); }, viewModel) }; ko.applyBindings(viewModel);