views:

794

answers:

3

Hi;

I would like to change the class attribute of an li after each 4 elements (that means 5th, 9th, 13th li element classes should be changed).

I have tried something like below but it gave me an syntax error: Could not parse the remainder: '%4' from 'forloop.counter%4'

{% for p in plist %}
{% ifequal forloop.counter%4 1 %}
 <li class="clear"> {{p.title}} </li>
{% else %}
 <li> {{p.title}} </li>
{% endifequal %}
{% endfor %}

I will appreciate if somebody will suggest me a working solution.

A: 

The logic would be complex, but the divisibleby filter might help.

cpharmston
With that the trick would be doable, but as you state the complexity would be such that it's probably better to move it out of the view. Adding a simple attribute is much more readable and should give a lot less headaches.
Agos
I have tried divisibleby, unfortunately it does not give the result I need. With the divisibleby; I can change the attribute for 4th, 8th, not the 5th, 9th..
Tolga
So you could use the `add` filter as well: `{% ifequal forloop.counter|add:"-1"|divisibleby:4 %}` Horrible, but does what you want.
Daniel Roseman
+1  A: 

You don't want to do it like that - that's what cycle is for.

{% for p in plist %}
        <li{% ifnotequal forloop.counter 1 %}{% cycle ' class="clear"' '' '' '' %}{% endifnotequal %}>{{p.title}</li>
{% endfor %}

That example clears the 5th, 9th, 13th etc.

Edit: hat tip @cpharmston.

Dominic Rodger
What about {% ifnotequal forloop.counter 1 %}{% cycle '' '' '' ' class="clear"' %}{% endifnotequal %}?
cpharmston
Edited in, thanks.
Dominic Rodger
I have just saw your edited solution. I am sure it will also provide the same required result.
Tolga
+3  A: 

You can't do evaluations like that in the django template. The ifequal tag expects only two parameters, and compares them. You would need some type of filter.

However, you could use the cycle tag instead:

{% for p in plist %} 
    {% if forloop.first %} 
        <li> {{p.title}} </li>
    {% else %}
        <li{% cycle '' '' '' ' class="clear"' %}> {{p.title}} </li> 
    {% endif %}
{% endfor %}

EDIT: As pointed out, the original solution cleared the 4, 8th, etc, instead of from the 5th onwards. I have updated the answer to include the changes by Tolga.

Andre Miller
That clears the 4th, 8th, 12th... rather than 5th, 9th, 13th.
Dominic Rodger
I have changed your suggested solution which worked as I needed to.{% for p in plist %} {% if forloop.first %} <li> {{p.title}} </li> {% else %} <li{% cycle '' '' '' ' class="clear"' %}> {{p.title}} </li> {% endif %}{% endfor %}This will clear the 5the 9th and so on..Thanks for all of you for your valuable answers and comments.
Tolga
Thanks Tolga, I have updated the answer with the modification.
Andre Miller