问题
I am trying to build a HTML table using WebMatrix (ASP.NET Web Pages) but am having trouble due to the way the HTML tags are opened and closed.
What I am trying to achieve is to create a table from a recordset, with three columns, and then fill in any empty columns.
This is some test code I am using to work out how to do this using WebMatrix.
<table>
@{
int row = 0;
int col = 0;
for (int i = 0; i < 20; i++) //20 cells for test purposes
{
col++;
if (col == 4)
{
col = 1;
}
if (col == 1)
{
row++;
if (row != 1)
{
</tr>
}
<tr>
}
<td>@i</td>
}
for (int i = col; i <=3; i++)
{
<td>empty</td>
}
</tr>
}
</table>
Any suggestions for how best to accomplish this.
回答1:
Updated code sample based on the revised requirement:
@{
var db = Database.Open("Northwind");
var data = db.Query("SELECT * FROM Products");
var total = data.Count();
var counter = 1;
var rows = total / 3;
var spares = total % 3 > 0 ? 3 - total % 3 : 0;
if(spares > 0){
rows += 1;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<table style="border:1px solid black">
@for(var i = 1; i <= rows; i++){
if( counter % 3 == 1){
@:<tr>
}
for(var cell = 1; cell <= 3 && counter <= total; cell++){
<td style="border:1px solid black">
<div>@data.ElementAt(counter-1).ProductId</div>
<div>@data.ElementAt(counter-1).ProductName</div>
<div>@data.ElementAt(counter-1).CategoryId</div>
</td>
counter++;
}
if(counter > total && spares > 0){
for(var j = 1; j <= spares; j++){
<td style="border:1px solid black">
</td>
}
}
if(counter % 3 == 0){
@:</tr>
}
}
</table>
</body>
</html>
Hopefully, I've understood what you are after this time.
If you want to build the table from a recordset, why not do that? Here's an example using the Northwind database:
<table>
@foreach(var row in data){
<tr>
<td>@row.ProductId</td>
<td>@row.ProductName</td>
<td>@row.CategoryId</td>
</tr>
}
</table>
Or you could use the WebGrid to do this for you.
回答2:
How about grouping your dataset before printing it? It ASP.NET MVC terms this is called view model. Unfortunately in WebMatrix you don't have a controller which could do the job of preparing this view model but you could do it in the codebehind or whatever this section of the Razor page is called:
@{
// group the dataset by 3 elements
var data = Enumerable.Range(0, 20).GroupBy(x => x / 3);
}
<table>
@foreach (var group in data)
{
<tr>
@foreach (var item in group)
{
<td>@item</td>
}
@for (int i = 0; i < 3 - group.Count(); i++)
{
<td>empty</td>
}
</tr>
}
</table>
and if you had a dataset of complex objects and not just integers, here's how the grouping could be done:
var dataset = Enumerable.Range(0, 20).Select(x => new { Text = "item " + x });
var data = dataset
.Select((value, index) => new { Index = index / 3, Item = value })
.GroupBy(pair => pair.Index);
and then:
<table>
@foreach (var group in data)
{
<tr>
@foreach (var element in group)
{
<td>@element.Item.Text</td>
}
@for (int i = 0; i < 3 - group.Count(); i++)
{
<td>empty</td>
}
</tr>
}
</table>
It kind of makes the code much more readable. As you can see the usage of a view model avoids you from writing ugly spaghetti code in the views.
Every-time you have some unmatched tags and you need to do integer and modulo divisions and stuff in a view you are probably doing it wrong as you didn't pick up the correct view model.
来源:https://stackoverflow.com/questions/8639387/building-tables-with-webmatrix