0

I have an array of things, things = [1, 500, 900, 0, -105, -8, 16, 4] and I want to display them in red, green or black in my view based on whether they're larger than zero, smaller than zero or equal to zero.

Right now my code looks like:

<%= @things.each do |p|%>
 <% if p > 0 %>
      <%= p  %>
    <% elsif p < 0 %>
      <%= p %>
    <% else %>
      <%= p %>
 <% end %>
<% end %>

I'm not displaying the numbers correctly to start, and I've gone through a few iterations of putting them in divs and nothing seems to work. Once I get 'em in classes, I can add colors pretty easily. (I also need to keep them in the same order they're in in the array)

Any help would be greatly appreciated.

Zack Shapiro
  • 6,648
  • 17
  • 83
  • 151

3 Answers3

3

Not sure what's the issue here

 <% @things.each do |p|
     if p < 0
       class_name = 'red'
     elsif p > 0 
       class_name = 'green'
     else 
       class_name = 'black'
     end %>
     <div class="<%=class_name%>"><%= p %></div> 
<% end %>

Then css :

.red{color:red;}
.green{color:green;}
.black{color:black;}

Edit : In your example, you were using <%= @things.each. Don't use <%= for things that are not supposed to output anything

Anthony Alberto
  • 10,325
  • 3
  • 34
  • 38
  • Thanks. No real issue, just been thinking about this for too long and my brain kind of stopped working. – Zack Shapiro Aug 02 '12 at 17:35
  • See my answer for a slightly more terse way to get over/under/equals 0 using the [spaceship operator](http://stackoverflow.com/questions/827649/ruby-spaceship-operator). – Phrogz Aug 02 '12 at 17:43
  • Also, note that using CSS class names that describe the style you wish to impart is [generally a bad idea](http://phrogz.net/css/HowToDevelopWithCSS.html#semanticselector). +1, however, for providing a working solution. – Phrogz Aug 02 '12 at 17:44
  • I agree with you, except that sometimes it can come in handy for short-straight-forward declarations. For example, I like to declare a class called `clear` that `clear:both;` to quickly apply it on some elements – Anthony Alberto Aug 02 '12 at 17:51
  • @AnthonyAlberto My Rails app is angry - `syntax error, unexpected keyword_elsif, expecting keyword_end elsif p > 0 ` – Zack Shapiro Aug 02 '12 at 17:51
  • Note also that if you wanted the case but not the spaceship you could do `case true; when p<0 then ...; when p>0 then ...; else ...; end` – Phrogz Aug 02 '12 at 17:58
0

The first thing I can think of is build a view helper

def set_color number 
  case
    when number == 0 
       "black"
    when number > 0
       "green"
    when number < 0
       "red"
  end
end

and in the view

<% @things.each do |p|%>
<div class="<%= set_color(p)%>"> <%= p %> </div>
<% end %>

Finally do the CSS

az7ar
  • 5,187
  • 2
  • 19
  • 23
  • +1 for working, but -1 for terrible style. Remove every `return` statement from that method and you get the same result but more idiomatic code. – Phrogz Aug 02 '12 at 17:59
0

If you want them grouped by positive/negative/0

<% @things.group_by{ |n| n<=>0 }.sort.each do |sign,items|%>
  <ul class="<%= sign==-1 ? 'negative' : sign==1 ? 'positive' : 'zero'%>">
    <% items.each do |item| %>
      <li><%= item></li>
    <% end %>
  </ul>
<% end %>

If you want them in array order, just classed

<ul>
  <% @things.each do |thing|
    css = case thing <=> 0
      when -1 then "negative"
      when  0 then "zero"
      when  1 then "positive"
    end
    %>
    <li class="<%=css%>"><%= thing %></li>
  <% end %>
</ul>

Note that you incorrectly have an equals sign at the start of your each wrapper:

<%= @things

...which will cause the to_s representation of the entire array to be output (you don't want that).

Phrogz
  • 296,393
  • 112
  • 651
  • 745