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

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

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).

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.

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

Alright, shall i give it a go then? I think it would really help a lot in DRY’ing things up.

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.

I believe you can open the pull request, after all the core team only says yes or no after seeing the code :confused:

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?