8

i have select box where on change i need to grab the value and via remote function get some field names from db and then generate those field further down the form depwning on whatoption from the select box is chosen.

The problem is is that the fields are in a f.form_for so are using the formbuilder f that has the select box in. So when i render the partial via ajax in the controller i get an error as i dont have a reference to the local form builder f.

does anyone know how or if i can get reference to the form builder orif can pass it in a remote function call and then pass into my locals in the partial ?

thanks alot, any help will be great as been stuck on this a long time!

cheers rick

richard moss
  • 339
  • 1
  • 8
  • 13

4 Answers4

26

I had the same problem and my solution was to create another form builder for the same object and to pass it on to the partials.

remote_action.js.erb:

'<%= form_for(@object) do |ff| %>'
   $('#some_div').html("<%= j render(partial: 'some_partial', locals: {f: ff}) %>"
'<% end %>' 

It is important that the form_for tag has single quotes or else there will be javascript_escape problems.

webster
  • 3,902
  • 6
  • 37
  • 59
Uri Klar
  • 3,800
  • 3
  • 37
  • 75
  • 1
    Great, works. It was missing closing brackets on the partial render and I had to remove the "/" in line one. – Mark Kenny Mar 18 '14 at 14:05
  • This worked for me once I realized that by "@object" you referring to some instance variable in your controller (the one that's invoked for AJAX)... which in my case was @property (etc...) Mine looked like this: – veca Jul 10 '14 at 07:11
  • Hi Uri, I had a similar problem like this. The only difference is that I am working upon nested fields and using fields_for instead of form_for. So I have to do something like f.fields_for :accessories, where f is form_builder object for vehicle model. Association is like this Vehicle has_many accessories. Please help in this case. Thanks in advance. – cvibha Aug 19 '15 at 14:40
  • Really smart way to dynamically render form fields through JS. Thanks for the tip. Works great. – Goldnuggets May 09 '16 at 16:54
  • I upvoted the answer but after I tried it for nested forms, it does not work at all. – Daniel Viglione May 19 '18 at 01:08
10

I would simply rewrite your partial to not use the f. form helpers.

Do:

<%= text_field :object_name, :method_name %>

Instead of:

<%= f.text_field :method_name %>
MattMcKnight
  • 8,185
  • 28
  • 35
  • This answered my question here: http://stackoverflow.com/questions/8821613/rails-lookup-table-with-dynamic-nested-forms – Karl Jan 12 '12 at 03:19
  • Hey Karl, The question you linked to is missing. Can you remember what it was? I have the exact same problem. Thanks! – Uri Klar Nov 11 '13 at 08:29
4

I'm doing something similar to what Uri Klar suggested, but without passing the form elements as strings back to the client, since they are not needed:

# create a form helper 'f' and store it in the variable form_helper.

<% form_helper = nil %> 
<% form_for @object, url: '' do |f| %>
<%   form_helper = f %>
<% end %>

# pass form_helper to the form partial

$('#element').html('<%= j render "form_element", f: form_helper %>');

Notice that form_helper = nil on the first line is there to set the scope of the variable to be beyond that of the form's block.

I think this is a better approach because it does not expose the client to any of our inner workings, but rather keeps them solely on the server side.

Oded Davidov
  • 171
  • 2
  • 6
0

This snippet didn't fit well in the comments to a different answer... it helps illustrate the case where the partial is for a nested model, and is referenced in a remote method/action. It also illustrates that my literal interpretation of @object was incorrect:

'<%= form_for([@property.agency,@property]) do |parent_form| %> ' '<%= parent_form.fields_for :address do |f| %>' $('#property_addresses').append("<%= j render(partial: 'common_partials/address', locals: {parent_form: f}) %>") '<% end %>' '<% end %>'

Note, that this is a @property, nested under @property.agency: where we have a fields_for nested under form_for.

veca
  • 149
  • 1
  • 5