Search code examples
cssruby-on-railscycle

Rails 4 -how to write a view that displays instances in alternating format


I am trying to figure out how to present data in alternating format.

Below are two list items. The first one is just "li". The second has class="timeline-inverted" attached. This CSS styles a timeline down the centre of a page and I want to display instances on each side (in alternating order).

FIRST LIST ITEM:

<li>
  <div class="timeline-badge primary"><i class="flaticon-clocks18"></i></div>
  <div class="timeline-panel wow fadeInLeft" data-wow-delay="0.3s" data-wow-offset="10">
    <p class="timeline-time fontcolor-invert"><i class="glyphicon glyphicon-time"></i> Aug 2010 - Nov 2012</p>
    <div class="timeline-photo timeline-bg01-01"></div>
    <div class="timeline-heading">
      <h3 class="font-accident-two-normal uppercase">Bluepixel LLC, London</h3>
      <h6 class="uppercase">Junior Designer</h6>
    </div>
  </div>
</li>

SECOND LIST ITEM:

<li class="timeline-inverted">
  <div class="timeline-badge success"><i class="flaticon-graduation61"></i></div>
  <div class="timeline-panel wow fadeInRight" data-wow-delay="0.3s" data-wow-offset="10">
    <p class="timeline-time fontcolor-invert"><i class="glyphicon glyphicon-time"></i> March 2013 - Jan 2014</p>
    <div class="timeline-photo timeline-bg02-01"></div>
    <div class="timeline-heading">
      <h3 class="font-accident-two-normal uppercase">Rocket Media, Berlin</h3>
      <h6 class="uppercase">Senior Designer</h6>
    </div>
  </div>
</li>

In my view, I currently have:

<div class="dividewhite4"></div>
<% profile.jobs.order(start_date: :desc).each do |job| %>
<ul class="timeline-vert timeline-light">
  <li>
    <div class="timeline-badge primary"><i class="flaticon-clocks18"></i></div>
    <div class="timeline-panel wow fadeInLeft" data-wow-delay="0.3s" data-wow-offset="10">
      <p class="timeline-time fontcolor-invert"><i class="glyphicon glyphicon-time"></i> 
      </p>
      <div class="timeline-photo timeline-bg01-01"></div>
      <div class="timeline-heading">
        <h3 class="font-accident-two-normal uppercase"><%= job.company %></h3>
        <h6 class="uppercase"><%= job.title %></h6>
        <p><%= job.description %></p>
      </div>
    </div>
  </li>
</ul>
<% end %>
<div class="dividewhite6"></div>

But what I want is to say that every first/third/fifth instance should in in that list format and the 2nd/4th/6th should be in the "li" format that has a class method attached to put it on the other side of the page.

Does anyone know how to do that?

CYCLE SUGGESTION

Having tried the cycle suggestion below, it puts each attribute into each of the two list items. How can I adjust it so it only displays each attribute once, but in chronological order so they go in alternating list item styles?

<% profile.jobs.order(start_date: :desc).each do |job| %>
<ul class="timeline-vert timeline-light" class="<% cycle("odd", "even") %>">
  <li>
    <div class="timeline-badge primary"><i class="flaticon-clocks18"></i></div>
    <div class="timeline-panel wow fadeInLeft" data-wow-delay="0.3s" data-wow-offset="10">
      <p class="timeline-time fontcolor-invert"><i class="glyphicon glyphicon-time"></i> 
        <% if job.current_job == true %> 
        <%= job.start_date.strftime('%B %Y') %>, continuing
        <% else %>   
        <%= job.period %>
        <% end %>   
      </p>
      <div class="timeline-photo timeline-bg01-01"></div>
      <div class="timeline-heading">
        <h3 class="font-accident-two-normal uppercase"><%= job.company %></h3>
        <h6 class="uppercase"><%= job.title %></h6>
        <p><%= job.description %></p>
      </div>
    </div>
  </li>
  <li class="timeline-inverted">
    <div class="timeline-badge success"><i class="flaticon-graduation61"></i></div>
    <div class="timeline-panel wow fadeInRight" data-wow-delay="0.3s" data-wow-offset="10">
      <p class="timeline-time fontcolor-invert"><i class="glyphicon glyphicon-time"></i> 
        <% if job.current_job == true %> 
        <%= job.start_date.strftime('%B %Y') %>, continuing
        <% else %>   
        <%= job.period %>
        <% end %> 
      </p>
      <div class="timeline-photo timeline-bg02-01"></div>
      <div class="timeline-heading">
        <h3 class="font-accident-two-normal uppercase"><%= job.company %></h3>
        <h6 class="uppercase"><%= job.title %></h6>
        <p><%= job.description %></p>
      </div>
    </div>
  </li>
</ul>
<% reset_cycle%>
<% end %>

EDIT. Updated answer

<ul class="timeline-vert timeline-light">
  <% profile.jobs.order(start_date: :desc).each do |job| %>
  <li class="<%= cycle("", "timeline-inverted") %>">
    <div class="timeline-badge primary"><i class="flaticon-clocks18"></i></div>
    <div class="timeline-panel wow fadeInLeft" data-wow-delay="0.3s" data-wow-offset="10">
      <p class="timeline-time fontcolor-invert"><i class="glyphicon glyphicon-time"></i> 
        <% if job.current_job == true %> 
        <%= job.start_date.strftime('%B %Y') %>, continuing
        <% else %>   
        <%= job.period %>
        <% end %>   
      </p>
      <div class="timeline-photo timeline-bg01-01"></div>
      <div class="timeline-heading">
        <h3 class="font-accident-two-normal uppercase"><%= job.company %></h3>
        <h6 class="uppercase"><%= job.title %></h6>
        <p><%= job.description %></p>
      </div>
    </div>
  </li>
  <% end %>
</ul>

Solution

  • You can achieve this in two ways:

    One is using the cycle helper (http://apidock.com/rails/ActionView/Helpers/TextHelper/cycle).

     # Alternate CSS classes for even and odd numbers...
     @items = [1,2,3,4]
     <table>
     <% @items.each do |item| %>
       <tr class="<%= cycle("odd", "even") -%>">
         <td>item</td>
       </tr>
     <% end %>
     </table>
    

    and another is via CSS (https://www.w3.org/Style/Examples/007/evenodd.en.html).

    tr:nth-child(even) {background: #CCC}
    tr:nth-child(odd) {background: #FFF}
    

    Cheers!