I am trying to display parent-child data with rowspan in HTML table in Blazor Server application. The html table is rendered but not displaying the correct way
This is my data from JSON
"shareCapitalDetails": [
{
"currency": "BTN",
"shares": [
{
"amountOfIssuedShareCapital": "1",
"amountOfPaidUpShareCapital": "1",
"classOfShare": "CG",
"sharesHeld": "1"
}
]
},
{
"currency": "KWD",
"shares": [
{
"amountOfIssuedShareCapital": "100",
"amountOfPaidUpShareCapital": "100",
"classOfShare": "AV",
"sharesHeld": "100"
},
{
"amountOfIssuedShareCapital": "100",
"amountOfPaidUpShareCapital": "100",
"classOfShare": "C",
"sharesHeld": "100"
},
{
"amountOfIssuedShareCapital": "100",
"amountOfPaidUpShareCapital": "100",
"classOfShare": "A",
"sharesHeld": "100"
}
]
}
],
This is the Blazor Server Code
@if (TestModel == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table table-sm table-responsive table-condensed caption-top">
<thead>
<tr>
<th scope="col">S/No</th>
<th scope="col">Currency</th>
<th scope="col">Class of share</th>
<th scope="col">No.of Shares Held</th>
<th scope="col">Amount of Issued Share Capital</th>
<th scope="col">Amount of Paid Up Share Capital</th>
</tr>
</thead>
<tbody>
@{int sno = 1; }
@foreach (var shareCapital in TestModel.ShareCapitalDetails)
{
<tr>
<td rowspan="@shareCapital.Shares.Count">@sno</td>
<td rowspan="@shareCapital.Shares.Count">@shareCapital.Currency</td>
@{int j = 0; int max = shareCapital.Shares.Count - 1;}
@foreach (var share in shareCapital.Shares)
{
<td>@share.ClassOfShare</td>
<td>@share.SharesHeld</td>
<td>@share.AmountOfIssuedShareCapital</td>
<td>@share.AmountOfPaidUpShareCapital</td>
if (j < max)
{
@:</tr><tr>
}
j ;
}
</tr>
sno ;
}
</tbody>
</table>
}
The issue is HTML table rendered but not as expected, Blazor server does not work
for @:</tr><tr>
Any way of work around to solve?
CodePudding user response:
Blazor doesn't like/will not allow incorrect html to be rendered - even if subsequent code makes the html valid.
Work the logic around complete valid elements and move the conditional around the elements that span the rows:
<tbody>
@{
int sno = 1;
bool firstRow;
}
@foreach (var shareCapital in TestModel.ShareCapitalDetails)
{
firstRow = true;
foreach (var share in shareCapital.Shares)
{
<tr>
@if ( firstRow == true ) // for clarity
{
<td rowspan="@shareCapital.Shares.Count">@sno</td>
<td rowspan="@shareCapital.Shares.Count">@shareCapital.Currency</td>
}
<td>@share.ClassOfShare</td>
<td>@share.SharesHeld</td>
<td>@share.AmountOfIssuedShareCapital</td>
<td>@share.AmountOfPaidUpShareCapital</td>
</tr>
firstRow = false;
}
sno ;
}
</tbody>
CodePudding user response:
Just add the rowspan columns conditionally:
<tbody>
@{int sno = 1; }
@foreach (var shareCapital in TestModel.ShareCapitalDetails)
{
@{int j = 0; int max = shareCapital.Shares.Count - 1;}
@foreach (var share in shareCapital.Shares)
{
<tr>
@if(j == 0)
{
<td rowspan="@shareCapital.Shares.Count">@sno</td>
<td rowspan="@shareCapital.Shares.Count">@shareCapital.Currency</td>
}
<td>@share.ClassOfShare</td>
<td>@share.SharesHeld</td>
<td>@share.AmountOfIssuedShareCapital</td>
<td>@share.AmountOfPaidUpShareCapital</td>
@{ j ; }
</tr>
}
sno ;
}
</tbody>