3

how i can translate this code into razor syntax:

<% for (int i = 0; i < items.Length; i++)  %>
<%{
    if (i % 3 == 0)
    { %>
      <tr>
 <% } %>
    <td><a href="<%: url[i] %>"><%: title[i] %></a></td>           
 <% if (i % 3 == 2)
    { %>
      </tr>        
 <% } %>
<%} %>

i'm try, but not success:

@for (int i = 0; i < items.Length; i++) 
{
    if (i % 3 == 0) 
    { 
        <tr>
    }
    <td><a href="@(url[i])">@(title[i])</a></td>
    if (i % 3 == 2) 
    {
        </tr>
    }
}

4 Answers 4

5

i have find solution:

    @for (int i = 0; i < items.Length; i++)
{
    if (i % 3 == 0)
    {
@:<tr>
    }
    <td><a href="@url[i]"><img height="@(48 * Scale.Value)" width="@(48 * Scale.Value)" src="/i@(Scale.Value)/@(items[i]).png"/><span>@text[i]</span></a></td>
    if (i % 3 == 2)
    {
@:</tr>
    }
}

here is introduction to razor syntax, but:

Use the @: operator or the <text> element. The @: outputs a single line of content containing plain text or unmatched HTML tags; the element encloses multiple lines to output. These options are useful when you don’t want to render an HTML element as part of the output.

i don't know, why <text> now working. maybe because razor still RC, not release

Sign up to request clarification or add additional context in comments.

2 Comments

I've been reading that document, but must have seen over it. Now I also know.
Note that your solution does not actually work when the number of items is not divisible by 3. In that case your final TR tag is not going to be printed.
4

Some of the other answers don't work correctly with lists that have a count not divisible by 3. Here's what I think is a better solution

@for(int i=0 ; i < items.Length ; ) {
    <tr>
        @for(int maxInRow = i+3 ; i < items.Length && i<maxInRow ; i++) {
            <td><a href="@url[i]">@title[i]</a></td>
        }
    </tr>
}

2 Comments

i have 9 elements and i should generate table 3x3 and put them my items, there is no labels or column names, it's generally grid
And my solution does that. And it will also work correctly in the future if you only want to have 8 elements in a 3x3 grid.
1

You can use the <text> tag, or IHtmlString like this:

@for (int i = 0; i < items.Length; i++) 
{
    if (i % 3 == 0) 
    { 
        <text><tr></text>
    }
    <td><a href="@(url[i])">@(title[i])</a></td>
    if (i % 3 == 2) 
    {
        @MvcHtmlString.Create("</tr>")        
    }
}

Edit

In my site I solved it something like this:

Create a function, that takes a template as parameter:

@functions {
    public IHtmlString conditionalTag(bool condition, string tag, Func<object, HelperResult> template) {
        var startTag = condition ? string.Format("<{0}>", tag) : "";
        var endTag = condition ? string.Format("</{0}>", tag) : "";
        return new HtmlString(string.Format("{0}{1}{2}", startTag, template(null).ToString(), endTag));
    }
}

You can call this function like this:

@for (int i = 0; i < items.Length; i++) 
{
    @conditionalTag(i % 3 == 0, "tr", @<text>
       <td><a href="@(url[i])">@(title[i])</a></td>
    </text>)
 }

3 Comments

Mmm, now looking at how I solved this. Updated answer using MvcHtmlString, but I don't like it.
imho, your solution too complicated
I know. But a nice example of how to use a Razor template.
0

I have not worked with Razor yet, but I'm pretty sure you could simplify the code a lot by filtering out the elements of the list where you only output the row tags. One way of doing that is to just increment past them. You could also use Linq with a Where clause. It would look more like this:

@for (int i = 1; i < items.Length; i+=3) 
{ 
<tr> 
    <td><a href="@url[i]"><img height="@(48 * Scale.Value)" width="@(48 * Scale.Value)" src="/i@(Scale.Value)/@(items[i]).png"/><span>@text[i]</span></a></td> 
</tr> 
} 

I'm guessing the view engine might be better with this too, because it can see that every opening tag is matched with a closing tag.

1 Comment

thanks for advice, but i'm using if-states because i want get table with three rows and three columns.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.