The table with the data-bindings currently looks like below:
Source Calls ChargeableCalls
Car Insurance
08434599111 3 2
08934345122 2 1
Home Insurance
08734599333 3 2
08034345555 2 1
The desired output should be like in the bellow example, The table should contain total values for Calls
and ChargeableCalls
grouped by Division, and total values for all Calls
and ChargeableCalls
within the table.
Source Calls ChargeableCalls
Car Insurance
08434599154 3 2
08934345555 2 1
Total Calls 5 Total CC 3
Home Insurance
08434599154 6 3
08934345555 1 0
Total Calls 7 Total CC 3
Total Calls All 24 Total CC All 12
Here are the bindings within the table:
<table class="table table-condensed" id="reportData">
<thead>
<tr>
<th>Source</th>
<th>TotalCalls</th>
<th>ChargeableCalls</th>
</tr>
</thead>
<tbody data-bind="foreach: groups">
<!-- ko foreach: $root.getGroup($data) -->
<tr data-bind="if: $index() == 0">
<td colspan="3" data-bind="text: division" class="division"></td>
</tr>
<tr>
<td data-bind="text: source"></td>
<td data-bind="text: totalCalls"></td>
<td data-bind="text: chargeableCalls"></td>
</tr>
<!-- /ko -->
</tbody>
Here's my ViewModel:
function GroupedReportingViewModel() {
var self = this;
self.results = ko.observableArray();
self.groupedResults = {};
self.getGroup = function (group) {
return self.groupedResults[group];
};
self.groupedResultsC = ko.computed(function () {
self.groupedResults = {};
ko.utils.arrayForEach(self.results(), function (r) {
if (!self.groupedResults[r.division]) self.groupedResults[r.division] = [];
self.groupedResults[r.division].push(r);
});
return self.groupedResults;
});
self.groups = ko.computed(function () {
var g = [];
for (x in self.groupedResultsC())
g.push(x);
return g;_
});
}
var model = new GroupedReportingViewModel();
ko.applyBindings(model);
The results
observableArray gets populated from an ajax response, like below:
success: function (jsondata) {
model.results(jsondata["Data"]["Report"]);
}
The jsondata
object looks like below:
{"Data":
{"Report":[ {"source":"08434599494","division":"Car Insurance","totalCalls":5, "chargeableCalls":23},
{"source":"08434599172","division":"Car Insurance","totalCalls":512,"chargeableCalls":44},
{"source":"08434599129","division":"Home Insurance","totalCalls":4, "chargeableCalls":2},
{"source":"08434599215","division":"Home Insurance","totalCalls":234, "chargeableCalls":54},
{"source":"08434599596","division":"Car Insurance","totalCalls":332, "chargeableCalls":266}
]
}
}
Q: How can I achieve the desired output?
In your example, groupedResults is a list of arrays. Instead of this, try making a ViewModel for a group. This ViewModel can then be used for working out the totals. For example...
function GroupViewModel(division) {
var self = this;
self.Division = division;
self.Items = ko.observableArray();
self.Count = ko.computed(function() {
var count = 0;
ko.utils.arrayForEach(self.Items(), function(r) { count += r.totalCalls; });
return count;
});
self.ChargeableCount = ko.computed(function() {
var count = 0;
ko.utils.arrayForEach(self.Items(), function(r) { count += r.chargeableCalls; });
return count;
});
}
You can simplify your main Viewmodel too, and push the items into the GroupViewModel instead:
function GroupedReportingViewModel() {
var self = this;
self.results = ko.observableArray();
self.groupedResults = ko.computed(function() {
var groups = [];
ko.utils.arrayForEach(self.Results(), function(r) {
var g = ko.utils.arrayFirst(groups, function(g) { return g.Division === r.division; });
if (!g) {
g = new GroupViewModel(r.division);
groups.push(g);
}
g.Items.push(r);
});
return groups;
});
self.TotalCount = ko.computed(function() {
var count = 0;
ko.utils.arrayForEach(self.results(), function(r) { count += r.totalCalls; });
return count;
});
self.TotalChargeableCount = ko.computed(function() {
var count = 0;
ko.utils.arrayForEach(self.results(), function(r) { count += r.chargeableCalls; });
return count;
});
}
Finally in your view, iterate through the groups, and then the items:
<tbody>
<!-- ko foreach: groupedResults -->
<tr>
<td colspan="3" data-bind="text: Division" class="division"></td>
</tr>
<!-- ko foreach: Items -->
<tr>
<td data-bind="text: source"></td>
<td data-bind="text: totalCalls"></td>
<td data-bind="text: chargeableCalls"></td>
</tr>
<!-- /ko -->
<tr>
<td>Total Calls</td>
<td data-bind="text: Count"></td>
<td>Total Chargeable:</td>
<td data-bind="text: ChargeableCount"></td>
</tr>
<!-- /ko -->
<tr>
<td>Total Calls All</td>
<td data-bind="text: TotalCount"></td>
<td>Total Chargeable All</td>
<td data-bind="text: TotalChargeableCount"></td>
</tr>
</tbody>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With