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!