How to use remote_form_tag?

I have a partial that gets rendered in response to a #link_to_remote
call. What I want to do is to display a select box, when the user
selects an item from that box, display a second select box, when the
user selects an item from that box, display a link (or possibly a
submit button) allowing the user to do something.

Here is my partial:

<%= select_tag “use_part”,
options_for_select(@parts, @use_part),
:onchange => “#{remote_function(:url => “select_assembly”,
:update => “disposition”,
:with => “‘use_part=’+$(‘use_part’).value”)}”
%>
<% if @use_part %>
<%= select_tag “use_lot”,
options_for_select(@lots, @use_lot),
:onchange => “#{remote_function(:url => “select_assembly”,
:update => “disposition”,
:with =>
“‘use_lot=’+$(‘use_lot’).value+’&use_part=’+$(‘use_part’).value”)}”
%>
<% end %>

<% if @use_lot %>
<%= link_to_remote “Use”,
:url => {:action => “use_in_assembly”},
:update => “disposition”,
:with =>
“‘use_lot=’+$(‘use_lot’).value+’&use_part=’+$(‘use_part’).value+’&id=’+$(‘id’).value”
%>
<% end %>

This works, but it seems pretty ugly, especially the bid where I keep
appending more and more variables to the :with clause. As I was
thinking about this last night, I started wondering if perhaps I
should have used the #remote_form_tag helper. That way, when the form
was submitted, the data contained in the form would be POSTed along
with it and I wouldn’t have to keep appending parameters to the :with
clause.

The problem is (if it isn’t obvious by now), I haven’t the foggiest
idea what I’m doing. Should I add an :onchange clause to the remote
form tag? If so, what javascript function should it call? Should it
include the :update => “disposition” option, indicating that the
result should replace the contents of the “disposition” div (BTW, this
partial is the only thing within that div). Should the select tags
(continue to) have the :update option invoking the #select_assembly
action on my controller?

I’ll keep muddling through this and will probably learn some answers
sooner or later (or possibly give up in a blue depressive funk), but I
thought I would ask what other folks do or have done.

–wpd

Here is my best idea so far, which, unfortunately, doesn’t work…

<% form_remote_tag :url => “select_assembly”, :update =>
“disposition”, :html => {:id => ‘xxx’} do %>
<%= select_tag “use_part”,
options_for_select(@parts, @use_part),
:onchange => “$(‘xxx’).submit()”
%>
<% if @use_part %>
<%= select_tag “use_lot”, options_for_select(@lots, @use_lot) %>
<% if @use_lot %>
submit somehow
<% end %>
<% end %>
<% end %>

I call it my “best” idea because it seems to make sense to me. Since
it doesn’t work, it obviously doesn’t make the correct sense to me.

The #form_remote_tag creates a form with an “onsubmit” attribute that
looks like:

onsubmit=“new Ajax.Updater(‘disposition’, ‘select_assembly’,
{asynchronous:true, evalScripts:true,
parameters:Form.serialize(this)}); return false;”

That looks an awful lot like AJAX/JavaScript code I’ve seen else where
that should update the “disposition” div when the form is submitted.
My #select_tag has an :onchange attribute that submits the form.

That makes sense to me, and it almost, sortof, kinda, works. The part
that doesn’t work is the AJAX thing – instead of updating the
“disposition” div, my browser (FF) gets directed to a new page
(http://…/select_assembly) and displays the raw HTML for 2 select
boxes. (I render that, without a layout, in my #select_assembly
action).

Why doesn’t the “disposition” div update? What am I missing?

–wpd

Just in case anybody is interested in this thread… here is what I
got to work for me:

<% form_remote_tag :url => “select_assembly”, :update => “disposition”
do %>
<%= disposition_select_tag “use_part”, @parts, @use_part %>
<% if @use_part %>
<%= disposition_select_tag “use_lot”, @lots, @use_lot %>
<% if @use_lot %>
submit somehow
<% end %>
<% end %>
<% end %>

where I defined #disposition_select_tag in my helpers file as:

def disposition_select_tag(name, container, selected)
select_tag(name,
options_for_select(container, selected),
:onchange => ‘if
(this.up(“form”).onsubmit()){this.up(“form”).submit();}’)
end

The piece that I was missing was that there seems to be a difference
between calling the submit() JavaScript function, which acted like a
normal form submit, pointing my browser to a new URL, and calling
onsubmit(), which executed the AJAX code to do the update in the
background.

If anybody has read this thread this far… thanks for the company :slight_smile:

–wpd

Hi Patrick,

if i understand correctly you want to have 2 select boxes that are
depending. So the second one changes it’s content mased on the first one

Took me some time to find out …

The trick was to put the second select into it’s own partial :

the view would look like this :

<label><%=h('1st Selectbox')%></label>
<%= @departments = Department.find(:all, :order => "name")
      collection_select('depart', 'department_id', @departments, :id, 
:name, :include_blank => true)  %>
      <br />
      <label><%=h('2nd Selectbox')%></label>
     <div id="taskselect"
       <%= render(:partial => 'taskselect') %>
    </div>

      <%= observe_field 'depart_department_id',:update => 
'taskselect',:url => {:action => 'change_taskgroup'},:with => 
'depart_department_id'%>

if the first collection_select changes it the “observe_field” will call
the controller action ‘change_taskgroup’ with parameter
‘depart_department_id’ (that’s the value of the selected item in
selectbox 1) and the re-render the div taskselect.

  def change_taskgroup
    @varDepartment = params[:depart_department_id]
    @categories = Taskcategory.by_department(@varDepartment)
    render :partial => 'taskselect', :layout => false
  end

the controller will fetch the new categories and “re-render” the div
taskselect with new values.

Hope that helped

best regards
Alex