Reputation: 54117
When using an ASP.NET WebForms ListView control to display data in an HTML table I use the following technique in to "stripe" the table rows:
<ItemTemplate>
<tr class="<%# Container.DisplayIndex % 2 == 0 ? "" : "alternate" %>">
<!-- table cells in here -->
</tr>
</ItemTemplate>
With the following CSS:
tr.alternate
{
background-color: #EFF5FB;
}
I have just gone through the ASP.NET MVC Movie Database Application tutorial and learnt that in MVC-land table rows can be (must be?) constructed as follows:
<% foreach (var item in Model) { %>
<tr>
<td>
<%= Html.Encode(item.Title) %>
</td>
<!-- and so on for the rest of the table cells... -->
</tr>
<% } %>
What can I add to this code to stripe the rows of my table?
Note: I know that this can be done using jQuery, I want to know if it can be done another way.
If jQuery (or equivalent) is in your opinion the best or most appropriate post, I'd be interested in knowing why.
Upvotes: 10
Views: 9555
Reputation: 1875
If you use Razor in for example .NET Core, this code works:
@for (int i = 0; i < Model.Stuff.Count; i++)
{
<tr style="background: @(i % 2 == 0 ? "#f5f5f5" : string.Empty)">
<td>
@Model.Stuff[i].Name
</td>
</tr>
}
Upvotes: 0
Reputation: 5385
How about this:
<% foreach (var item in Model.Alternating("alternate","") { %>
<tr class="<%= item.ClassName %>">
<td>
<%= Html.Encode(item.Model.Title) %>
</td>
<!-- and so on for the rest of the table cells... -->
</tr>
<% } %>
Which uses this extension method:
public class AlternatingItem<T>
{
public string ClassName { get; set; }
public T Model { get; set; }
}
public static IEnumerable<AlternatingItem<T>> Alternating<T>(this IEnumerable<T> model, string oddString, string evenString)
{
int i = 0;
var query = from x in model
let c = i++ % 2 == 0 ? oddString : evenString
select new AlternatingItem<T>() { ClassName = c, Model = x };
return query;
}
Upvotes: 0
Reputation: 28765
Another option that doesn't involve lambdas and is a bit cleaner than what you got working might be this...
<% int i=0; foreach (var item in Model) { %>
<tr class="<%= i++ % 2 == 0 ? "alternate" : "" %>">
<td>
<%= Html.Encode(item.Title) %>
</td>
<!-- and so on for the rest of the table cells... -->
</tr>
<% } %>
Upvotes: 31
Reputation: 17317
What about an extension method?
public static void Alternate<T>(this IEnumerable<T> items, Action<T, bool> action)
{
bool state = false;
foreach (T item in items)
action(item, state = !state);
}
This way you could say:
<% movies.Alternate((movie, alt) => { %>
<tr class="<%= alt ? "alternate" : "" %>">
<td>
<%= Html.Encode(movie.Title) %>
</td>
<!-- and so on for the rest of the table cells... -->
</tr>
<% }); %>
Edit, additionally if you want the index, you can use an extension method like this:
public static void Each<T>(this IEnumerable<T> items, Action<T, int> action)
{
int state = 0;
foreach (T item in items)
action(item, state++);
}
Upvotes: 7