Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't seem to conditionally create a new table row using Razor's foreach and if statements?

I want a loop to dynamically create a table up to 2 columns wide, and then increase the number of rows until there are no entries left in the list. Sounds easy, and I came up with this:

<table>
                    <tr>
                        @{ var i = 0; }
                        @foreach (var tm in Model.TeamMembers)
                        {
                            <td>@tm.FirstName @tm.LastName @tm.Role</td>

                            if(++i % 2 == 0)
                            {
                                </tr>
                                <tr>
                            }
                        }
                    </tr>
                </table>

But I get errors stating } expected both for the for loop and the if statement. If I change the tags to something else (like for instance) it works fine.

My guess is it's trying to validate the end of the row, sees it and decides the loop must be over? How can I make it NOT do that, or do I need to put the entire table inside the loop with a bunch of messy conditionals? :(

like image 573
CodeRedick Avatar asked Apr 20 '11 16:04

CodeRedick


3 Answers

Try like this:

@{ var i = 0; }
@foreach (var tm in Model.TeamMembers)
{
    <td>@tm.FirstName @tm.LastName @tm.Role</td>
    if(++i % 2 == 0)
    {
        <text></tr><tr></text>
    }
}

or:

@{ var i = 0; }
@foreach (var tm in Model.TeamMembers)
{
    <td>@tm.FirstName @tm.LastName @tm.Role</td>
    if(++i % 2 == 0)
    {
        @:</tr><tr>
    }
}
like image 94
Darin Dimitrov Avatar answered Sep 22 '22 23:09

Darin Dimitrov


Razor expects the HTML code following your C# code to be enclosed in a pair of html tags. Here you've got the ending tag first, and the starting tag later, that's why razor had trouble parsing the text.

Enclosing your html code block in solves this issue as pointed out by Darin.

You could read this quick guide by Phil Haacked http://haacked.com/archive/2011/01/06/razor-syntax-quick-reference.aspx

like image 23
Cyril Gupta Avatar answered Sep 19 '22 23:09

Cyril Gupta


In Razor syntax you can use the @: To insert literal text.

@:This allows literal text & arbitrary html 

You can see how this is implemented in my solution posted below. It properly closes the table with the right number of table cells per row.

I needed a tabular radio button list with the ability to bind a selected value.

@{
   int iSelectedId = (int)ViewData["SelectedMember"];
   long iCols = 3;
   long iCount = Model.TeamMembers.Count();
   long iRemainder = iCount % iCols;                    
   decimal iDiv = iCount / repeatCols;                    
   var iRows = Math.Ceiling(iDiv);
}
<table>
  <tr>
    @for (int i = 0; i < iCount; i++)
    {
      var tm = Model.TeamMembers[i];
      <td><input type="radio" name="item" value="@(tm.Id)" @(tm.Id == iSelectedId) ? "checked=checked" : "") /> @(tm.FirstName) @(tm.LastName)) - @(tm.Role) </td> 

      if (i % iCols == iCols -1 && i < iCount - 1) 
      { 
        //The alternate syntax for adding arbitrary text/html @: 
        //was crucial in getting this to work correctly.
        @:</tr><tr>
      }
    }
    if (iRem > 0) 
    {
      <td colspan="@(iCols - iRem)">&nbsp;</td>
    }
  </tr>
</table>
like image 2
uberianmaan Avatar answered Sep 18 '22 23:09

uberianmaan