Home > Software design >  How should I go about rendering an icon conditionally?
How should I go about rendering an icon conditionally?

Time:04-15

Problem Description: I want to display an icon (from Semantic UI) next to a column name that has been clicked upon. A user would click this column to sort the list by that column.

Basically, I am working with a list of movies with columns - Title, Rating, Description, and Release Date. I have made 'Title' and 'Release Date' into clickable links which, upon clicking, sort the movie list by Title/Release Date.

My routes.rb file:

Rails.application.routes.draw do
    root 'movies#index' 
           
    resources :movies 
end    

In my index.html.erb file, I have made Title and Release Date as such:

<%= link_to "Title", movies_path(sort: "title") %>
<%= link_to "Release Date", movies_path(sort: "release_date") %>

In my movies_controller.rb, I am fetching all movie entries and sorting them with the help of order - Movie.all.order(params[:sort]).

All of this is working fine.

What I want to be able to do next is display an icon (<i ></i>) next to the column name which has been clicked upon.

My idea was to leave <i ></i> empty, and then set a variable inside movies_controller#index to chevron up icon, and then conditionally set it based upon params[:sort], and then render it in the view. But I don't think this would be the right way to do it, because it wouldn't work for both Title and Release Date.

I am seeking the correct way to do this. Would I have use one of the helper files - application_helper.rb or movies_helper.rb? Somebody please explain the logic to me. I am, as you should be able to tell by now, a beginner in Rails, so pardon me for my ignorance.

Edit: Sreenshot to get a better understanding of what I am working with

CodePudding user response:

In ERB you could solve this with:

<%= link_to movies_path(sort: "title") do  %>
  Title
  <% if params[:sort] == "title" %>
    <i ></i>
  <% end %>
<% end %>

<%= link_to movies_path(sort: "release_date") do  %>
  Release Date
  <% if params[:sort] == "release_date" %>
    <i ></i>
  <% end %>
<% end %>

The link_to helper takes an optional block for the element contents which can be used instead of a string.

A cleaner solution though is to write a helper method:

# app/helpers/movies_helper.rb
module MoviesHelper
  # Gives a link for columns in a table that can be used to sort the movies
  # will add an icon if the link is "active"
  # @param name String
  # @param column [Symbol|String]
  # @example
  #   sortable_link_to_movies("Critic rating", "critic_rating")
  # @return [ActiveSupport::SafeBuffer]
  #   <a href="/movies?sort=critic_rating>Critic rating</a>
  #   <a href="/movies?sort=critic_rating>Critic rating <i ></i></a>
  def sortable_link_to_movies(name, column, **opts)
    link_to movies_path(sort: "title", **opts) do
      # concat is needed to write to the text buffer of the helper
      concat name
      if column.to_s == params[:sort]
        concat tag.i class: "chevron up icon" 
      end
    end
  end
end
<%= sortable_link_to_movies "Title", :title %>
<%= sortable_link_to_movies "Release Date", :release_date %>

This lets you test the method in isolation.

  • Related