Link_to conditional classes with 'class:' feature request (and all the other helpers that take CSS classes)

83 views
Skip to first unread message

em...@leaplines.com

unread,
Oct 24, 2016, 8:12:25 PM10/24/16
to Ruby on Rails: Core
Heya, 

Setting condition classes is a huge pain in rails at the moment, or maybe i am missing it but i can't see to find it. borrowed from react components kind of style.

I want something like this (the class selected is only added if the value is true)

link_to("Homepage", root_path, class: {selected: selected?})

-> a href class="selected" and other

You can do the same thing to add multiple classes too

link_to("Hello", root_path, class: {class: {btn:true, selected: selected?}}

I think this would be awesome, anything reasons why we shouldn't implement this?

Cheers,

- Emile

Gabriel Sobrinho

unread,
Oct 25, 2016, 8:51:58 AM10/25/16
to Ruby on Rails: Core
This is a must, react used to have this on the core but latter they extracted it to a 3rd library.

When you have a lot of classes to be conditionally applied the code becomes a mess.


I'm not from the core but I believe you can do the code and make the pull request, it would be easier to people agree or reject (since this should be a simple code).

Rafael Mendonça França

unread,
Oct 25, 2016, 10:08:55 AM10/25/16
to rubyonra...@googlegroups.com
There is an open question here. From here those conditional methods are coming from? From helpers modules? This will add a lot of this kind of methods in the global namespace since helpers are global and will make code harder to understand.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-co...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Gabriel Sobrinho

unread,
Oct 25, 2016, 10:18:37 AM10/25/16
to rubyonra...@googlegroups.com
This shouldn't impact the implementation, it could be literally anything (helper method, object method, local variable or anything).

The specification would be { classname: true/false }.

link_to user.name, user_path(user), class: { btn: true, active: user.active? } // => object method call
link_to user.name, user_path(user), class: { btn: true, active: active_user?(user) } // => helper method call
link_to user.name, user_path(user), class: { btn: true, active: active } // => local variable call


Also, the link_to can be in the view or in a helper method.

If you want to see this working, you can implement a prototype on application helper like this (untested and not fully compatible with current link_to implementation (need to accepts blocks, string keys, etc)):

  module ApplicationHelper
    def link_to(content, path, options = {})
      klass = if Hash === options[:class]
                parse_class_hash(options[:class])
              else
                options[:class]
              end

      super(content, path, options.merge(class: klass))
    end

    def parse_class_hash(classes)
      string = []

      classes.each_pair do |name, value|
        string << name if value
      end

      string.join(' ')
    end
  end


You received this message because you are subscribed to a topic in the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rubyonrails-core/GtAQDk0SCA0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rubyonrails-co...@googlegroups.com.

em...@leaplines.com

unread,
Nov 8, 2016, 7:03:54 PM11/8/16
to Ruby on Rails: Core
Alright, shall i give it a go then? I think it would really help a lot in DRY'ing things up.

Op dinsdag 25 oktober 2016 16:18:37 UTC+2 schreef Gabriel Sobrinho:

em...@leaplines.com

unread,
Nov 8, 2016, 7:06:34 PM11/8/16
to Ruby on Rails: Core
The question im asking is only about conditions doing of classes when things are true in the hash. My `selected?` etc whatever are just examples. The logic im describing is like gabriels. below.

Op dinsdag 25 oktober 2016 16:08:55 UTC+2 schreef Rafael Mendonça França:

Gabriel Sobrinho

unread,
Nov 9, 2016, 6:26:45 AM11/9/16
to rubyonra...@googlegroups.com
I believe you can open the pull request, after all the core team only says yes or no after seeing the code :/

You received this message because you are subscribed to a topic in the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rubyonrails-core/GtAQDk0SCA0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rubyonrails-co...@googlegroups.com.

Carlos Ramirez III

unread,
Jan 12, 2017, 11:09:32 AM1/12/17
to Ruby on Rails: Core
Hi there!

I too find myself frequently needing to set and/or merge conditional classes in my Rails views. Common use cases include setting "selected" on a list of nav links to indicate the current page, "active" on a tab or carousel component, etc. It's a common pattern across almost all of my Rails projects. 

Rather than modifying all the individual helper methods which take a :class option (e.g. link_to, content_tag), why not create a separate helper method which will spit out a finalized string of classes. 

For example, 

link_to("Hello", root_path, class: class_set(btn: true, selected: selected?))

This same helper could be used wherever a set of conditional classes were needed, and no modification to the method itself would be necessary.

It turns out that there's already a gem which implements this functionality called css-class-string. You can add it to your Gemfile and use it as above (except the helper method name is class_string, not class_set).

What does everyone think? 
Reply all
Reply to author
Forward
0 new messages