Reputation: 1
I have view model in below format and need to render data in below format. Could you help me to get binding working to render below table format?
var data = {"MonthlySummaries":
[
{"Name": "Jan", "BeginBalance": "1000", "Usage": "100", "EndBalance": "900"}
,{"Name": "FEB", "BeginBalance": "900", "Usage": "100", "EndBalance": "800"}
,{"Name": "MAR", "BeginBalance": "800", "Usage": "100", "EndBalance": "700"}
]
};
This is what the table should look like:
JAN FEB MAR
BeginBalance 1000 900 800
Usage 100 100 100
EndBalance 900 800 700
Upvotes: 0
Views: 668
Reputation: 542
It's true there is no built-in mechanism for doing column based tables in HTML which really sucks. Transposing data is not always an option. I recently struggled greatly with this issue finally found a workaround which seemed to work out great using CSS flexbox.
<div class="container">
<div class="column">
<div class="cell">Label</div>
<div class="cell">Begin Balance</div>
<div class="cell">Usage</div>
<div class="cell">End Balance</div>
</div>
<!-- ko foreach:MonthlySummaries -->
<div class="column">
<div class="cell" data-bind="text:Name"></div>
<div class="cell" data-bind="text:BeginBalance"></div>
<div class="cell" data-bind="text:Usage"></div>
<div class="cell" data-bind="text:EndBalance"></div>
</div>
<!-- /ko -->
</div>
Style sheet
.container {
display:flex;
flex-direction:row;
}
.column {
display:flex;
flex-direction:column;
}
.cell {
margin:.2em;
}
Here is a working jsfiddle using your data. You can add a border to the cell class and use padding instead of a margin in order to make it look like a table.
Upvotes: 2
Reputation: 63830
You should really try the tutorials, the one related to your issue is the second one I'd say. Or just dive into the observableArray
documentation and the foreach
documentation.
The hardest part is that your source data is not in a format well suited for presentation in HTML. There is no concept of a "matrix" in HTML, and it's not easy to build "columns" as opposed to rows. You need to transpose your data to make presenting it easy.
There are many, many ways to transpose the data. Most easy ones are close to the the point where your data is generated (e.g. in your server side controller). Without access to that code, here's a small, simple example using a "dumb" transpose client side:
var data = {"MonthlySummaries":
[
{"Name": "Jan", "BeginBalance": "1000", "Usage": "100", "EndBalance": "900"}
,{"Name": "FEB", "BeginBalance": "900", "Usage": "100", "EndBalance": "800"}
,{"Name": "MAR", "BeginBalance": "800", "Usage": "100", "EndBalance": "700"}
]
};
var transposedData = {
Headers: ["Jan", "FEB", "MAR"],
Rows: [
{
Name: "BeginBalance",
Values: [
data["MonthlySummaries"][0].BeginBalance,
data["MonthlySummaries"][5].BeginBalance,
data["MonthlySummaries"][6].BeginBalance
]
},
{
Name: "Usage",
Values: [
data["MonthlySummaries"][0].Usage,
data["MonthlySummaries"][7].Usage,
data["MonthlySummaries"][8].Usage
]
},
{
Name: "EndBalance",
Values: [
data["MonthlySummaries"][0].EndBalance,
data["MonthlySummaries"][9].EndBalance,
data["MonthlySummaries"][10].EndBalance
]
}
]
};
ko.applyBindings(transposedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<table>
<tr>
<td></td>
<!-- ko foreach: Headers -->
<td data-bind="text: $data"></td>
<!-- /ko -->
</tr>
<tbody data-bind="foreach: Rows">
<tr>
<td data-bind="text: Name"></td>
<!-- ko foreach: Values -->
<td data-bind="text: $data"></td>
<!-- /ko -->
</tr>
</tbody>
</table>
Upvotes: 0