10

This is a simple question that I'm kinda ashamed to ask, but I've been banging my head against the wall and navigating through the rails 3 documentation without any success :/

So, here is the thing:

When I use the fields_for helper it wraps the generated fields in a <div class="fields"> ... </div> tag.

so, my code is

<ul class="block-grid two-up">
  <%= f.fields_for :images do |image_builder| %>
    <%= render "images/form", :f => image_builder %>
  <% end %>
</ul>

and the generated html is:

<ul class="block-grid two-up">
  <div class="fields">
    <div>
      <label for="company_images_attributes_0_image"> Image</label>
      <input id="company_images_attributes_0_image" 
             name="company[images_attributes][0][image]" type="file">
    </div>
  </div>
  <div class="fields">
    <div>
      <label for="company_images_attributes_1_image"> Image</label>
      <input id="company_images_attributes_1_image" 
             name="company[images_attributes][1][image]" type="file">
    </div>
  </div>
</ul>

What I want to do is actually change the <div class="fields"> wrapper tag to <li>.

The documentation says you can pass options to the fields_for, but its not clear about what options you can pass, maybe you can change this wrapper tag?

A possibility could be to override a function, kinda like ActionView::Base.field_error_proc when there is an error in the form.

Quick edit: I forgot to mention that I'm using simple_form to generate this form. I tried looking in the simple_form.rb config file for a way to customize this, but I didn't see any way of doing it.

Solution After further investigation, it turns out the form was using the nested_form gem as well to generate the form (not only simple_form). This generator was causing the fields_for to be wrapped in the div tag. Thanks everybody for their suggestions!

Tass
  • 1,548
  • 15
  • 27
  • The field_error_proc approach is canonical. (IIRC with the caveat that its argument is an HTML string instead of something useful, but I might be confusing it with something else.) – Dave Newton Jan 20 '12 at 03:50

3 Answers3

12

The following disables the wrapper:

f.fields_for :images, wrapper:false do |image_builder|

then you can add your own wrapper in the builder block.

lulalala
  • 15,996
  • 12
  • 101
  • 165
  • 2
    I was surprised to see that nested_form doesn't give you an options[:class] to alter this. It's hard coded to 'fields' [here](https://github.com/ryanb/nested_form/blob/master/lib/nested_form/builder_mixin.rb#L91). – Kevin Monk Jun 11 '15 at 12:37
2

A cheap solution would be just adding <li> tag into the form like:

<%= f.fields_for :images do |image_builder| %>
 <li><%= render "images/form", :f => image_builder %></li>
<% end %>

I am not sure if you can completely eliminate the div tag by passing some params to field_for. But I think you can change the name of div class or id by passing the html block, like in form_for:

<%= form_for @image, :as => :post, :url => post_image_path, 
   :html => { :class => "new_image", :id => "new_image" } do |f| %>
mu is too short
  • 396,305
  • 64
  • 779
  • 743
Marshall Shen
  • 1,173
  • 11
  • 16
  • I tried your first suggestion before posting, but the fields_for call actually wraps anything that's inside it in the aforementioned div tags. So I would get something like
    • ..
    – Hector Villarreal Jan 20 '12 at 07:38
  • Ok, I'm sorry. This is actually the answer. The problem was not simple_form... it's that the form was actually using the nested_form plugin as well... so it was simple_NESTED_form_for tag, this causes the fields to be wrapped in the div... – Hector Villarreal Jan 20 '12 at 16:11
-1

You said you're using simple_form then you should be saying <%= f.simple_fields_for... Have you tried using wrapper_html option:

<%= f.input :name, :label_html => { :class => 'upcase strong' },
  :input_html => { :class => 'medium' }, :wrapper_html => { :class => 'grid_6 alpha' } %>

Edit 1: From SimpleForm documentation:

Wrapper

SimpleForm allows you to add a wrapper which contains the label, error, hint and input. The first step is to configure a wrapper tag:

SimpleForm.wrapper_tag = :p

And now, you don't need to wrap your f.input calls anymore:

<%= simple_form_for @user do |f| %>
  <%= f.input :username %>
  <%= f.input :password %>
  <%= f.button :submit %>
<% end %>

Edit 2:

And there is this config option with which you can say what css class to use with the wrapper elements:

config/initializers/simple_form.rb

# CSS class to add to all wrapper tags.
config.wrapper_class = :input
Syed Aslam
  • 8,387
  • 5
  • 39
  • 53
  • Thanks for the answer, unfortunately, SimpleForm.wrapper_tag only affects individual inputs :/ fields_for is wrapping my entire nested form in a
    tag. The inputs in the nested form itself are alright.
    – Hector Villarreal Jan 20 '12 at 08:32
  • The problem was that the form was using the nested_form gem generator as well... this cause the fields_for call to be wrapped. thanks! – Hector Villarreal Jan 20 '12 at 16:15