Evan
Evan

Reputation: 7416

How do I add a class to a form in ruby on rails without setting / overriding the existing default helper class?

Adding a class for form_for through the html: {class: "form-horizontal"} option overrides the default new_model or edit_model class. How do I add my class while keeping the existing form_helper class?

I want:

<form class="edit_model form-horizontal"> or

<form class="new_model form-horizontal">

Instead of:

<form class="form-horizontal">

Upvotes: 14

Views: 9151

Answers (6)

Steve
Steve

Reputation: 7108

Defining classes via the :html => {:class => '...'} option overrides any classes added by the default builder. However, you can append CSS classes within the block without overriding those classes.

With the form_for helper, the :class will be a string if not otherwise set. Note the leading space when appending. (Update: also note that the string will be frozen in recent versions of Rails, so += must be used instead of << to avoid a "can't modify frozen String" error.)

<%= form_for @model do |f| %>
  <% f.options[:html][:class] += ' form-horizontal' %>
  <%# ... %>
<% end %>

<form class="edit_model form-horizontal">

If you're using the simple_form_for helper, options[:html][:class] will be an array, and you don't need the extra leading space (although it doesn't hurt).

<%= simple_form_for @model do |f| %>
  <% f.options[:html][:class] << 'form-horizontal' %>
  <%# ... %>
<% end %>

<form class="simple_form edit_model form-horizontal">

If you're using a symbol instead of a model, form_for will not set the class, and options[:html][:class] will be nil in the block. But if you're doing this you don't have a model to be new or persisted anyway.

<%= form_for :model do |f| %>
  <% f.options[:html][:class] << ' form-horizontal' %>
  <%# ... %>
<% end %>

NoMethodError: undefined method `<<' for nil:NilClass

Upvotes: 4

Steve
Steve

Reputation: 7108

You can use the view helper dom_class(object, prefix = nil) to generate class names like form_for does.

It's not very clean doing it directly in the form, but incorporating it into a helper might be just the ticket. For example:

# app/helpers/application_helper.rb
def class_for object, *additional_classes
  additional_classes.unshift dom_class(object, object.persisted? ? 'edit' : 'new')
end

# app/views/models/_form.html.erb
<%= form_for @model, :html => {:class => class_for(@model, 'form-horizontal')} do |f| %>
  <%# ... %>
<% end %>

<form class="new_model form-horizontal" ...>

Upvotes: 1

nonsenseless
nonsenseless

Reputation: 36

Have you tried using the merge method? [http://ruby-doc.org/core-1.9.3/Hash.html#method-i-merge] Something like html = html.merge(new) { |key, value1, value2| value1 + " " + value2 } would let you feed the new value into the class value. [Quick edit: Be careful to configure and test the implementation so you don't completely overwrite html)

Upvotes: 0

sjobe
sjobe

Reputation: 2837

I ran into exactly the same issue. Eventually, I came up with this solution

form_for @foo, :html => {:class => "form-horizontal #{controller.action_name}_model_name"}

It might be a little too late for this to be of much use to you, but maybe someone else will find it useful.

Upvotes: 8

abhir
abhir

Reputation: 1069

Maybe not an ideal solution, but have you considered doing it with JS/Jquery?

For example:

$(document).ready(function(){
    $('form.edit_model').addClass('form-horizontal')
});

Upvotes: 1

carpamon
carpamon

Reputation: 6633

html: {class: "edit_model form-horizontal"}

Upvotes: 0

Related Questions