Form helpers don't seem to work with RJS files

I’ve been spending a great deal of time chasing this problem. Hopefully
someone sees something obvious I’m doing wrong. Basically anytime I try
to call fields_for from an RJS file or within a partial in the RJS file,
I get the following error. My goal is simply to load a partial into a
div. The fields in this partial require fields_for though. And that’s
where the problem lies.

ActionView::TemplateError (undefined method `fields_for’ for
“#ActionView::Helpers::FormBuilder:0x944ea28”:String) on line #3 of
app/views/trials/observe.rjs:
1: page.alert(‘before’)
2: test_func = pluralize(6, ‘cat’)
3: @form.fields_for :org_detail do |w|
4: page[‘section_two’].replace_html :partial => “mypartial”,
:locals => { :f => w }
5: end
6: page.alert(‘after’)

As you can see, the pluralize method seems to work fine, but fields_for
always returns this exception. If I run the fields_for code directly in
my main view HTML file it works fine. However, calling through the RJS
file always fails.

As a work around, I tried setting the fields_for at the highest level
and passing in the fields_for object into the RJS file. However, this
results in the template error undefined method `label’. This is in
regards to the first f.label call in the partial.

Basically it seems that the RJS is choking on any/all form helpers.

My prototype version is 1.6.0.1. Rails 2.3.5. Ruby 1.8.6 or 1.8.7

Any help would be greatly appreciated!

On May 28, 3:25 pm, Steve R. [email protected] wrote:

I’ve been spending a great deal of time chasing this problem. Hopefully
someone sees something obvious I’m doing wrong. Basically anytime I try
to call fields_for from an RJS file or within a partial in the RJS file,
I get the following error. My goal is simply to load a partial into a
div. The fields in this partial require fields_for though. And that’s
where the problem lies.

ActionView::TemplateError (undefined method `fields_for’ for
“#ActionView::Helpers::FormBuilder:0x944ea28”:String) on line #3 of

This is the hint: @form is not a form builder. it’s a string
containing the text “#ActionView::Helpers::FormBuilder:0x944ea28

Fred

Ahh! That makes sense. Now… :slight_smile: Fred you’re my new hero!

So the problem seems to be I’m not correctly passing the form_builder
from my view file to the controller.

view file

<%= observe_field(“trial_org_id”, :url => {:action => :observe,
:trial_id => @trial.id, :f=> f}, :with => ‘q’) %>

controller file

@form = params[:f]

I was expecting params[:f] to return the object, but as you pointed out
it is returning a string describing the object.

How can I get observe_field to pass the object itself?

Steve R. wrote:

Ahh! That makes sense. Now… :slight_smile: Fred you’re my new hero!

So the problem seems to be I’m not correctly passing the form_builder
from my view file to the controller.

view file

<%= observe_field(“trial_org_id”, :url => {:action => :observe,
:trial_id => @trial.id, :f=> f}, :with => ‘q’) %>

controller file

@form = params[:f]

I was expecting params[:f] to return the object, but as you pointed out
it is returning a string describing the object.

How can I get observe_field to pass the object itself?

Why do you want to? Your controller shouldn’t normally be dealing with
FormBuilder objects. What are you trying to achieve?

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Steve R. wrote:
[…]

How can I get observe_field to pass the object itself?

Why do you want to? Your controller shouldn’t normally be dealing with
FormBuilder objects. What are you trying to achieve?

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Hi Marner

Please note correct spelling of my name.

I have an RJS file that is inserting a partial that has form
components in it. I use the observe_field in the view to detect select
box option. That value dictates the partial that gets rendered. Once the
observe_field fires, it runs an action in the controller. The controller
then sends the info to the rjs file. As I said, the partials rendered in
the RJS file have form elements and thus need the form builder object to
be passed from the View->controller->RJS->rendered partial.

No. The controller never needs to touch or know about the form builder.
That’s defined in the view and only in the view. The controller just
needs to pass in the dynamic data.

Is this path possible?

No. You can’t pass a FormBuilder as an HTTP parameter – HTTP
paramaters are always strings. Fortunately, you don’t need to, as I
explained above.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Marnen, my apologies on mispelling your name.

Given the flow of my code “Main html(view)->controller->RJS->rendered
partial”, the error I recieve seems to be the result of the RJS file
calling a partial with form elements like “f.text_area” for example.
When the form builder object “f” is not passed into the partial that is
rendered form the RJS file, I get the ActionView::TemplateError.

Are you saying to omit the form builder object “f” in the partial? Such
that it would read “text_area” rather than “f.text_area”?

Would it still work when the HTML is inserted back into the main view
page?

I’m sorry if I’m not explaining well. I appreciate all the help I’m
getting.

Marnen Laibow-Koser wrote:

Steve R. wrote:

Ahh! That makes sense. Now… :slight_smile: Fred you’re my new hero!

So the problem seems to be I’m not correctly passing the form_builder
from my view file to the controller.

view file

<%= observe_field(“trial_org_id”, :url => {:action => :observe,
:trial_id => @trial.id, :f=> f}, :with => ‘q’) %>

controller file

@form = params[:f]

I was expecting params[:f] to return the object, but as you pointed out
it is returning a string describing the object.

How can I get observe_field to pass the object itself?

Why do you want to? Your controller shouldn’t normally be dealing with
FormBuilder objects. What are you trying to achieve?

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Hi Marner
I have an RJS file that is inserting a partial that has form
components in it. I use the observe_field in the view to detect select
box option. That value dictates the partial that gets rendered. Once the
observe_field fires, it runs an action in the controller. The controller
then sends the info to the rjs file. As I said, the partials rendered in
the RJS file have form elements and thus need the form builder object to
be passed from the View->controller->RJS->rendered partial.

Is this path possible?

I actually tried to add form_for in the partial and it appeared to work.
The form within a form wasn’t a problem it seemed. However when a
validation error was detected, the dynamically rendered partial was
gone. When I tried to reselect the partial in the select box, the
content I added was wiped out. I’m sure there may be a way to preserve
the content after form validation, but it seems like too much work.

At this rate I’ll take your advice and seek a different approach using
pure javascript. I may also try RJS code directly in the main view via
the :function parameter in the observe_field method.

Thanks for your help Marnen,

Steve R. wrote:

Marnen, my apologies on mispelling your name.

Given the flow of my code “Main html(view)->controller->RJS->rendered
partial”, the error I recieve seems to be the result of the RJS file
calling a partial with form elements like “f.text_area” for example.

Can’t the partial instantiate the FormBuilder? In other words, why
doesn’t the partial contain the form_for call?

When the form builder object “f” is not passed into the partial that is
rendered form the RJS file, I get the ActionView::TemplateError.

Are you saying to omit the form builder object “f” in the partial? Such
that it would read “text_area” rather than “f.text_area”?

No – there’s no such method.

Would it still work when the HTML is inserted back into the main view
page?

I’m sorry if I’m not explaining well. I appreciate all the help I’m
getting.

You can’t use a FormBuilder to rebuild part of a form AFAIK. I’ll
admit, however, that I have very little use for RJS – I usually prefer
to write JavaScript directly.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]