views:

1471

answers:

6

What's a good, simple way to have alternate row coloring with freemarker?

Is this really the best way?

<#assign row=0>
<#list items as item>
    <#if (row % 2) == 0>
        <#assign bgcolor="green">
    <#else>
        <#assign bgcolor="red">
    </#if>
    <tr style='background-color: ${bgcolor}'><td>${item}</td></tr>
    <#assign row = row + 1>
</#list>

I tried doing this:

<#assign row=0>
<#list items as item>
    <tr style='background-color: ${(row % 2) == 0 ? "green" : "blue"}'><td>${item}</td></tr>
    <#assign row = row + 1>
</#list>

But apparently you can't user the ternary operator in there.

Note: I guess I should have mentioned it earlier, but I can't use css classes or javascript, since this HTML is going into an email message.

+2  A: 

Hmmm... OK, this is the best I've come up with:

<#assign row=0>
<#list items as item>
    <tr style='background-color: <#if (row % 2) == 0>green<#else>red</#if>'><td>${item}</td></tr>
    <#assign row = row + 1>
</#list>

From the deafening silence I deduce there's no nicer way of doing this.

itsadok
You do realize that you could use CSS or JavaScript to do the same thing: There's no need to use FreeMarker?
George Stocker
A: 

Using FreeMarker, there are limited ways of answering this question, but if you're wanting to use CSS alone (Which still allows separation of concerns), then here's one way:

Put the following in your stylesheet:

tr.linea {
    background-color: #CC9999; color: black;
}
tr.lineb {
    background-color: #9999CC; color: black;
}

Then use the following tr class to define alternate lines:

<table>
<tr class="linea"><td>One Fish</td></tr>
<tr class="lineb"><td>Two Fish</td></tr>
<tr class="linea"><td>Red Fish</td></tr>
<tr class="lineb"><td>Blue Fish</td></tr>
</table>

There are many resources to choose from as well.

Edit: If your HTML is going into an email, then you can't be sure that the client's email client will allow whatever HTML you're trying to put into it. Your best bet at that point is to use FreeMarker similiar to how you have it, except that you need to remove the style tag, and use colors for each row using bgcolor="color" in your <tr> tags.

George Stocker
Now I need a way to alternate "linea" and "lineb" - a very similar problem...
itsadok
+1 for the email tip
itsadok
+3  A: 

If you have a series of tables you might want to make a little function.

<#function zebra index>
  <#if (index % 2) == 0>
    <#return "white" />
  <#else>
    <#return "#efefef" />
  </#if>
</#function>

<#assign arr=["a","b","c","d"] />
<table>
<#list arr as n>
  <tr><td bgcolor=${zebra(n_index)}>${n}</td></tr>
</#list>
</table>

and the _index builtin when using list saves you from having to make and increment an index variable yourself.

andynu
The _index is a neat trick. Thanks!
itsadok
+1  A: 

A solution then boils down to this:

<style>
.rowon {
 background-color:#dedede;
}

.rowoff{

}
</style>

In your template:

<#list items as item>
    <tr  class="<#if item_index % 2 ==0>rowon<#else>rowoff</#if>"><td>${item}</td></tr>
</#list>

However, as stated in a previous reply, you can do this with CSS, without this freemarker solution (see http://www.w3.org/Style/Examples/007/evenodd):

<style>
.striped tr:nth-child(odd) {background: #eee}
.striped tr:nth-child(even) {background: #fefefe}
</style>

And then just use a normal table without classes on the rows:

<table class="striped">
 <tr><td>hello</td></tr>
 <tr><td>hello</td></tr>
 <tr><td>hello</td></tr>
 <tr><td>hello</td></tr>
</table>

OR with a freemarker generated table:

<table class="striped">
<#list items as item>
    <tr><td>${item}</td></tr>
</#list>
</table>

So it is all in the CSS.

prule
+2  A: 

With freemarker, you can use the string built-in:

<#list items as item>
   <tr style='background-color: ${((item_index % 2)==0)?string("green", "blue")}'><td>${item}</td></tr>
</#list>
mx
Welcome to StackOverflow! Thanks for adding this great tip!
Jeremy Stein
A: 
class='${["odd", "even"][item_index%2]}'
Dinesh Khetarpal