views:

81

answers:

2

I've got a rails app that displays a list of items called modules. I'm iterating over these, rendering a partial for each one that includes a remote_form_for call.

This all works, but fails HTML validation because my form text fields all have the same id.

Is there a :prefix option on the form (or something else) I can use to get around this?

Update:
(some code)

    //_module_form.html.erb
    <% remote_form_for app_module do |f| %>
         <%= f.label :name %>
         <%= f.text_field :name %>
         <%= submit_tag 'Save' %>
    <%end %>

    //parent page
    <% @thing.modules.each do |app_module| %>
       <%= render :partial => "module_form", :locals => { :app_module => app_module } %>
    <% end %>

So if I have more than 1 item in the collection, I render the identical form on the same page, and the form id and textbox id are duplicated.

I can customize the form id pretty easily, but what about the text_box, since the controller is looking for specific named controls?

+1  A: 

Iterate over them with collection.each_with_index do |item, i| then on the render partial pass in a local variable:

render :partial => "some_partial", :locals => {:form_id => "form_id_#{i}"}

Then in the partial you can access <%= form_id %>

That would be one way to do it.

I'm assuming in the remote_form_for you can pass in :id => form_id or :html_options => {:id => form_id}

Looks like you can, see: http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html#M001649

tsdbrown
that addresses my duplicate form id, but what about the textbox ids?
Ben Scheirman
You can set the id in the text_field in a similar fashion, by passing in :id to the text_field helper. The name attribute on the input fields should be taken care of by the form helper anyway. Why not do use something like :id => "app_module_#{app_module.id}_name"
tsdbrown
If I do that, my controller no longer functions correctly, because it doesn't understand the params that are posted in.
Ben Scheirman
You will need to make sure the controller knows how to deal with the params being posted in. You can also set the :name on the text boxes too in the same way as the id. So you could ask which module is it and make sure the name is set accordingly.
tsdbrown
+1  A: 

Add the :index => object.id to the options hash when creating your form. This should generate ids in the form of object_id_attribute without interfering with the controller.

Edit

The documentation regarding :index is is ambiguously misleading. :index does have an effect on the form submission. The solution is to specify the :id attribute for each field. This will change the id property, leaving name unharmed (which is what counts for the submission).

Here is the code I use in a generic helper for generating these fields:

def create_field( f, field_type, object, field_name )
    field_id = "#{object.class.name.downcase}_#{object.id.to_s}_#{field_name.to_s}"
    f.send( field_type, field_name, :id => field_id )
end
shmichael