Reputation: 41
function for Violation:
function Violation(violCd, desc, amt) {
this.violCd = ko.observable(violCd);
this.desc = ko.observable(desc);
this.amtToPay = ko.observable(amt);
}
View Model:
self.violations = ko.observableArray([]);
self.addViol = function () {
alert('adding');
self.violations.push(new Violation({ violCd: "28-0000", desc: "DUI OR SOMETHING",
amtToPay: "300" }));
}
self.total = ko.computed(function () {
alert(total);
var total = 0;
for (var i = 0; i < self.violations.length; i++) {
total += self.violations[i].amtToPay;
}
return total;
});
The html is:
<input data-bind="value: total()" />
I need the total to auto update as soon as a violation is added.
Thanks.
Upvotes: 0
Views: 52
Reputation: 7958
So the main issue is to do with self.violations
. This needs to be declared as an observablearray
so that if items are added then knockout knows that they have been added and can update the computed total.
self.violations = ko.observableArray();
Then when ever you access the array to get the contents you will need to use self.violations()
so your computed function should be:
self.total = ko.computed(function () {
alert(total);
var total = 0;
for (var i = 0; i < self.violations().length; i++) {
total += self.violations()[i].amtToPay;
}
return total;
});
One other issue is that amtToPay is set as a string so in javascript 0 + "300" = "0300"
. It should be set as an int or float:
self.violations.push(new Violation({ violCd: "28-0000", desc: "DUI OR SOMETHING",
amtToPay: 300 }));
You could possibly have to also make the properties in Violation
as observable as well if it's possible to just modify the value of a property without modifying the array.
eg:
self.violations()[0].amtToPay = 300;
That change won't be noticed by knockout so you would need to declare amtToPay as an observable:
self.amtToPay = ko.observable();
Then to access the value you would need to use self.violations[i]().amtToPay()
.
If it's input from the user then it would be a string so you would need to convert it to an int or float using parseInt or parseFloat.
Upvotes: 1
Reputation: 41
I fixed it using this:
self.violations = ko.observableArray([]);
self.addViol = function () {
self.violations.push(new violation({ violCd: "28-0000", desc: "DUI OR SOMETHING", amt: "300" }));
self.violations.valueHasMutated();
}
self.total = ko.computed(function () {
var total = 0;
ko.utils.arrayForEach(self.violations(), function (violation) {
var value = parseFloat(violation.amt());
if (!isNaN(value)) {
total += value;
}
});
return total.toFixed(2);
});
Now it seems to notice a change.
Upvotes: 0