Can a dropdown be used to select additional form fields?

For the last week and a half I've really struggled trying to do something I assumed would be pretty straight forward. However I continue to find road blocks regardless of the approach I take. No one on the web seems to have covered this or run into this problem...

Basically I want a drop down field to offer a certain sets of form_for fields I have stored in different partials. Each partial contain certains fields for the form. Based on the selection in the drop down, teh approparaiet partial/fields will be displayed on the page.

Initially, I tried using the observe_field and an RJS file. This approach failed because I couldn't pass the form_builder object through the observe_field method sending to an action and then RJS file.

I then tried to use pure javascript in the observe_field method using the :function parameter. The problem with this approach is that there doesn't seem to be any way to pass the getElementById(field_name).value into the ruby call within the #{}. See below...

<%#= observe_field("trial_npi_org_id", :function => $('section_two').innerHTML = '#{escape_javascript(render 'section_two', :f => f, :selected_org => 1 )}'" ) %>

I was able to build a string with the correct form and then tried to use eval() to execute, but this fails with a JS error claiming "illegal character". I think this is the the eval() function choking on the ruby call with #{}.

I'm somewhat new to rails but this seems like it should be doable.

If anyone can help, I would truly appreciate it. Thanks,

Steve Russo wrote:

For the last week and a half I've really struggled trying to do something I assumed would be pretty straight forward. However I continue to find road blocks regardless of the approach I take. No one on the web seems to have covered this or run into this problem...

Basically I want a drop down field to offer a certain sets of form_for fields I have stored in different partials. Each partial contain certains fields for the form. Based on the selection in the drop down, teh approparaiet partial/fields will be displayed on the page.

Build all the forms in advance, inside hidden divs. Then show one div or another based on dropdown selection. Very simple, and will work better for users without JS.

Best,

I'm missing something, I'm sure. How would the hidden divs get toggled if the user doesn't have javascript?

Hi Marnen,    Thanks for the advice. I had actually started off with that approach but thought it would be more economical to just render the desired partial to one div. Unfortunately, due to the headaches I mentioned in previous comments, I think I will give that approach another shot. Doesn't seem I have many other choices. I'll keep you posted...

Thanks again for your continued help Marnen!

Bill Walton wrote:

Hi Steve,

Steve Russo wrote:

For the last week and a half I've really struggled trying to do something I assumed would be pretty straight forward. However I continue to find road blocks regardless of the approach I take. No one on the web seems to have covered this or run into this problem...

Didn't see your origiinal post. Sorry. This is straight forward.

Basically I want a drop down field to offer a certain sets of form_for fields I have stored in different partials. Each partial contain certains fields for the form. Based on the selection in the drop down, teh approparaiet partial/fields will be displayed on the page.

Put an observe field on the select input that calls a method in your controller that renders the desired partial. Easiest thing to do is put the (set of) empty div(s) in the form so you can use page.replace_html. If you want to get rid of the select when the partial is displayed, put it inside the div that will have its inner_html replaced. You'll need to add named routes to your UI-manipulating methods.

Some, like Marnen, will tell you not to use RJS because it puts inline js in the page source. Do as you like. I'm a Rails developer. I work primarily in Rails code, not in page source, so it matters not one bit to me what Rails generates as long as it validates. When I need to write custom js, I do and I do it unobtrusively, but I use Rails helpers whenever they'll do. YMMV.

Best regards, Bill

Bill Walton wrote:

Build all the forms in advance, inside hidden divs. �Then show one div or another based on dropdown selection. �Very simple, and will work better for users without JS.

I'm missing something, I'm sure.

Yes, you are.

How would the hidden divs get toggled if the user doesn't have javascript?

They wouldn't, obviously. If I were doing something like this, I'd probably have the JS hide the divs in the first place, so that without JS, the forms would still be available.

Best,

It seems I have this working using the approach of rendering all of the partials and then hiding/displaying the div as needed. I was able to get this to partially work in the past with an RJS file using Marnen's suggestion of using a separate form builder within each of the partials. This was done to address the fact that I couldn't pass the form object through the observe_field method.

Unfortunately, with this current approach I have the same issue I had when I got it working with the RJS file. This remaining issue is that when a validation error occurs, teh partial is getting cleared. I'm not sure why. If I do a simple reload/refresh on the browser, the values within the partials are preserved, but not when a validation error occurs.

Any thoughts on what the validation may be doing that clears the dynamic partial? Do you think the validation errors cause a re-rendering of the partials even though a page reload/refresh does not?

here is some of the code...

==============Form the main form page .html.erb ============= . . .     <div id="partial1" style="display: none;">       <%= render "partial1" %>     </div>     <div id="partial2" style="display: none;">       <%= render "partial2" %>     </div>     <div id="partial3" style="display: none;">       <%= render 'partial3', :w => f %>     </div>

    <%= javascript_tag "set_section_two();" %>

===== application .js file ================

function set_section_two() {   var team=document.getElementById("trial_org_id").value;   hide_all_dynamic_divs()   //alert('set_section_two() called');   switch(team)   {     case '1':       $('partial1').style.display = 'block';     break;     case '2':       $('partial2').style.display = 'block';     break;     case '3':       $('partial3').style.display = 'block';     break;     default: // alert('other');     break;   }

} function hide_all_dynamic_divs(){   $('partial1').style.display = 'none';   $('partial2').style.display = 'none';   $('partial3').style.display = 'none'; }

It seems I have this working using the approach of rendering all of the partials and then hiding/displaying the div as needed. I was able to get this to partially work in the past with an RJS file using Marnen's suggestion of using a separate form builder within each of the partials. This was done to address the fact that I couldn't pass the form object through the observe_field method.

Unfortunately, with this current approach I have the same issue I had when I got it working with the RJS file. This remaining issue is that when a validation error occurs, teh partial is getting cleared. I'm not sure why. If I do a simple reload/refresh on the browser, the values within the partials are preserved, but not when a validation error occurs.

Any thoughts on what the validation may be doing that clears the dynamic partial? Do you think the validation errors cause a re-rendering of the partials even though a page reload/refresh does not?

When a validation error occurs and you re-display the page, are you setting whatever data is needed so that the correct div shows? Remember that as far as the browser is concerned this is a new page not a re-draw of the existing one. Only you know that.

Colin

Colin Law wrote:

sure why. �If I do a simple reload/refresh on the browser, the values within the partials are preserved, but not when a validation error occurs.

Any thoughts on what the validation may be doing that clears the dynamic partial? Do you think the validation errors cause a re-rendering of the partials even though a page reload/refresh does not?

When a validation error occurs and you re-display the page, are you setting whatever data is needed so that the correct div shows?

It seems that the correct div is being displayed after the error is reported. Although the values are blank. However, the code used to set the div visibility isn't called though, based on the break point I set not breaking on that line whenever a validation error occurs. It seems as though the page just re-displays what divs are already present. Even so, if the code block above did run, all it does is show or hide the div. The partials are only rendered when the page is first loaded. Also, all of the other static form fields preserve their values after the error detection. Not sure why these rendered partials would be any different. The JS code only shows or hides their respective DIVs.

What do you think?

Colin Law wrote:

sure why. �If I do a simple reload/refresh on the browser, the values within the partials are preserved, but not when a validation error occurs.

Any thoughts on what the validation may be doing that clears the dynamic partial? Do you think the validation errors cause a re-rendering of the partials even though a page reload/refresh does not?

When a validation error occurs and you re-display the page, are you setting whatever data is needed so that the correct div shows?

It seems that the correct div is being displayed after the error is reported. Although the values are blank. However, the code used to set the div visibility isn't called though, based on the break point I set not breaking on that line whenever a validation error occurs. It seems as though the page just re-displays what divs are already present. Even so, if the code block above did run, all it does is show or hide the div. The partials are only rendered when the page is first loaded.

When you re-render after a validation error that is a 'first loading' of that page. The fact that you happen to be rendering the same page again is irrelevant. Are you saying that the divs are empty? If so have a look at the code you use to generate the view in the first place, presumably this is from controller new or edit or something. Now look at where the validation failure is, in create or update possibly, when save fails. Are you setting everything up properly in that case?

Also, all of the other static form fields preserve their values after the error detection.

That is because the object you are displaying is loaded into @something in create or update, and will be passed on to the view.

Not sure why these rendered partials would be any different. The JS code only shows or hides their respective DIVs.

I guess that the partials are not being rendered following save failure in create or update, as I suggested earlier.

If you still can't work it out use ruby debug to break into the code where the partials should be called and find out why they are not.

Colin

Steve,

When you reload/refresh the page, the browser remembers some of the current state of the page, so that a browser refresh is not the same as loading the page again - ie by resubmitting the url (which best simulates the effect you see after a validation error). It is easy to get fooled with this especially if you have js functions on the page.

In order to make sure the correct form/partial is redisplayed, you will need to make sure that information about which partial is currently displayed is available to the server in some way. In your case, that is going to be the value of the select control returned in the params hash which will need to control the creation of the page by setting the right partial to be displayed.

Because you are showing/hiding the partials, then a way to do this is to not use a js function to set them to not display, but to do it using css styles which you can set up when the page is displayed. A little bit of logic in the page redisplay can then determine which partial should be displayed based on the params value of your select box.

My personal preference to meet your needs would be to use the solution suggested by Bill, to use an observer on the select which would cause the required partial to be displayed. Using this approach keeps the server in control of what is being displayed.

Tonypm

Collin, Bill, Marnen, Tony,   I think I understand why the values within the partials were being blanked out. As Collin mentioned, when stepping through the "create" method, I saw that the passed values were blank, which they definitely should not have been. I realized that I was calling the partial twice, as designed since this partial is also part of another dynamically displayed DIV. However, the div I was populating with data was then getting wiped out by the second empty instance of that partial in a DIV that wasn't even being displayed. Silly mistake on my part... It has been fixed.

I think I can take it from here. I truly appreciate everyone's help though.

Thank you all so much!