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!

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

view file

Steve Russo 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 wrote:

Steve Russo 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 marnen@marnen.org

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?

Steve Russo 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 marnen@marnen.org

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, 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.

Steve Russo 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,

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,