Home > Software design >  How to render parent child rowspan HTML Table in Blazor Server Application?
How to render parent child rowspan HTML Table in Blazor Server Application?

Time:09-25

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>

enter image description here

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>
  • Related