interacting select_tags using onchange

my view:

  <td>     <div id="event_category_select">       <%= render :partial => "event_category_select" %>     </div>     <br/>     <div id="event_category_text_field">       <%= render :partial => "event_category_text_field" %>     </div>   </td>   <td>     <div id="event_description_select">       <%= render :partial => "event_description_select" %>     </div>     <br/>     <div id="event_description_text_field">       <%= render :partial => "event_description_text_field" %>     </div>   </td>

_event_category_select.html.erb: <%= select_tag :select_category, options_for_select(@categories, selected = @selected_category),       {:onchange => remote_function(:url => {:action => :select_category}, :with => "select_category")} %>

_event_category_text_field.html.erb: <%= text_field_tag :category, @selected_category, :size => 30 %>

_event_description_select.html.erb: <%= select_tag :select_description, options_for_select(@descriptions, selected = @selected_description),       {:onchange => remote_function(:url => {:action => :select_description}, :with => "select_description")} %>

_event_description_text_field.html.erb: <%= text_field_tag :description, @selected_description, :size => 60 %>

controller:

  def select_category     @selected_category = params[:value]     search_hash = {:select => "DISTINCT description"}     search_hash[:conditions] = ["category = ?", @selected_category] if @selected_category != ""     @descriptions = ["", *Event.find(:all, search_hash).map(&:description)]     @selected_description = ""     render :update do |page|       page.replace_html "event_category_text_field", :partial => "event_category_text_field"       page.replace_html "event_description_select", :partial => "event_description_select"     end   end

  def select_description     @selected_description = params[:value]     @categories = ["", *Event.find(:all, :select => "DISTINCT category").map(&:category)]     if @selected_description != ""       selected_event = Event.find(:first, :conditions => ["description = ?", @selected_description])       @selected_category = selected_event.category if selected_event     else       @selected_category = ""     end     render :update do |page|       page.replace_html "event_category_select", :partial => "event_category_select"       page.replace_html "event_description_text_field", :partial => "event_description_text_field"     end   end

With ie 7.0 everything's fine, but with firefox 3.0:

When I select a category, the two ids are replaced. After that, I want to select a description, but it doesn't send a request. However, selecting another category does. The same the other way round, i.e. when I begin with selecting a description.

The source code is of no avail, because with both browsers it never changes whatever I select.

Any idea?

Thanks Luma

Hey, do you solved your problem or found a work-around?

If so I'm interested in it because I do have a similar problem.

Thanks. Flo.

sorry, I still didn't find a solution. I don't have much experience with javascript. Luma

From what I can see, the most likely cause of this is that there is an issue with the dom, such that when you do the update, the browser is not seeing the fields or ids correctly

A couple of suggstions:

Use firebug to carefully inspect the dom before and after the updates and make sure the ids are ok and that the elements are structured correctly.

If you cannot see anything obvious, strip the view code down so that the only things being rendered are the actual select fields. Then you should be able to see why the onchange is not firing.

If you get it down to very simple/minimal example that still demonstrates a problem, post it here and i will see if i can repeat it.

Tonypm

ps.

Looking again at the code, I suspect the problem may be that you are updating table cells. I think i have seen something similar with ff. In general, I tend to always update a whole row.

Tonypm

Very nice tool, I didn't know firebug.

I think I've found the reason of the problem: When you update fields of a form, they forget to which form_tag they belong. (Why do we need a form_tag for these select_tags, as they are only used for setting other fields by onchange?)

Updating another partial containing the form_tag doesn't work, so you've got to update the whole form. But I didn't find a way to update a table row: A <div> can't be between a <table> and a <tr> element, and a form_tag can't be between <tr> and <td>. A simple example:

<table cellpadding=10>   <div id='test'>     <%= render :partial => 'test' %>   </div> </table>

_test.html.erb:

<% form_tag do %>   <tr>     <td>       number: <%= select_tag :select_number, options_for_select(['','1','2'], selected = @number),         {:onchange => remote_function(:url => {:action => :select_number}, :with => "select_number")} %>     </td>     <td>       letter: <%= select_tag :select_letter, options_for_select(['','a','b'], selected = @letter),         {:onchange => remote_function(:url => {:action => :select_letter}, :with => "select_letter")} %>     </td>     <td>       additional: <%= text_field_tag :additional, @additional %>     </td>   </tr> <% end %>

  def select_number     @number = params[:value]     index = ['','1','2'].index(@number) || 0     @letter = ['','a','b'][index]     render :update do |page|       page.replace_html "test", :partial => "test"     end   end

  def select_letter     @letter = params[:value]     index = ['','a','b'].index(@letter) || 0     @number = ['','1','2'][index]     render :update do |page|       page.replace_html "test", :partial => "test"     end   end

I also included a field 'additional' which will also be updated with the whole form. How can I keep the values of such fields?

Thanks, Luma

1. You don't need the form tag if you are only updating by ajax. Html purists might argue the point!

2. You can use any element to update from a partial. For example, give the tr an id as in: <tr id='update_me'> then in the controller, page.replace_html :update_me etc.....

3. Sometime I find it easier to include the <tr> tag in the partial itself, so that the whole row, not just the inner html gets replaced. In this case use page.replace :update_me in the controller.

4. You may find if you get rid of the form tags, that updating individual <td>s may work, but I would be wary of it.

hth Tonypm

Without the form_tag, everything's fine with IE 7.0. But with firefox 3.0.3, I don't even get a request. (javascript completely enabled)

<table cellpadding=10>   <tr id='test'>     <%= render :partial => 'test' %>   </tr> </table>

_test.html.erb:

    <td>       <%= select_tag :select_number, options_for_select(['','1','2'], selected = params[:value]),         {:onchange => remote_function(:url => {:action => :select_number}, :with => "select_number")} %>     </td>     <td>       selected: <%= params[:value] %>     </td>

  def select_number     render :update do |page|       page.replace_html "test", :partial => "test"     end   end

And using page.replace with <tr id='test'> in the partial leads to something like http://railsforum.com/viewtopic.php?id=21678

Luma

You're right, the problem was just :with => "select_number"

Using :with => "'value='+value" works.

Thanks!