Select item based on previous select list selection?


#1

So I have a select list with a list of items. When a user selects an
item, another select list should have its default selected item set to a
specific item (the default associated with the first select list).

This is in a form to create a new task. The first select list is a list
of parent tasks. When one selects the parent task, the clients select
list must default to the same client as its parent task.

I’ve come across several part examples using remote_function or rjs, but
my rails newbieness is preventing me from understanding those
completely. Does anyone have complete code or a suggestion as to how to
accomplish this.

This is my existing code:
<%= select (‘task’, ‘parent_id’, @parents.collect {|p| [ p.title, p.id ]
}, { :include_blank => true }) %>
<%= select (‘task’, ‘client_id’, @clients.collect {|c| [ c.name, c.id ]
}) %>

Thx
N.


#2

On Apr 27, 2006, at 7:26 AM, Nick C. wrote:

I’ve come across several part examples using remote_function or
<%= select (‘task’, ‘client_id’, @clients.collect {|c| [ c.name,
c.id ]
}) %>

Nick-

Here is an example of how you can get started doing this:

— In the view file ----

<%= select (‘task’, ‘parent_id’, @parents.collect {|p| [ p.title,
p.id ]},
{ :include_blank => true,
:onchange => remote_function( :with =>
“‘parent_id=’+value”,
:loading => “Element.show(‘loading-
indicator’)”,
:url => { :action
=> :select_with_ajax } )) %>}) %>
<%= image_tag(‘indicator.gif’,
:id => ‘loading-indicator’,
:style => ‘display:none;’ ) -%>

— In the controller action----

def select_with_ajax
@clients = Client.find(:all, :conditions => [“parent_id = ?”,
params[:parent_id])
render :update do |page|
page.replace_html(‘next_select’, :partial =>
‘second_select’, :collection => @clients
page.hide(‘loading-indicator’)
end
end

The loading indicator gif is one of those little spinner animated gif
files. You might need to change the @client=Client.find line to fetch
whatever it is you want to populate the next select box with. And you
will need a partial called _second_select.rhtml that has the code for
the second select box.

Hope that gets you over the hump.

Cheers
-Ezra


#3

Hi Ezra

The code makes sense, but its not working as expected. While I do get
the indicator image showing, the select box never updates. This is the
code:

In the view:-
<%= select (‘task’, ‘parent_id’, @parents.collect {|p| [ p.title, p.id
]},
{ :include_blank => true},
:onchange => remote_function ( :with =>
“‘parent_id=’+value”,
:loading =>
“Element.show(‘loading-indicator’)”,
:url => { :action =>
:select_with_ajax } )) %>
<%= image_tag(‘indicator.gif’,
:id => ‘loading-indicator’,
:style => ‘display:none;’ ) -%>

<%= render :partial => 'client_list' %>

In the controller:-
def select_with_ajax
@clients = Client.find(:all,
:conditions => [“parent_id = ?”,
params[:parent_id]],
:joins => [:tasks])
render :update do |page|
page.replace_html(‘task_client’, :partial => ‘parent_client_list’,
:collection => @clients)
page.hide(‘loading-indicator’)
end
end

And the partial _parent_client_list.rhtml looks like:
<%= select (‘task’, ‘client_id’, @clients.collect {|c| [ c.name, c.id ]
}, { :include_blank => false }) %>

What am I missing?

thx
n.

Ezra Z. wrote:

On Apr 27, 2006, at 7:26 AM, Nick C. wrote:

I’ve come across several part examples using remote_function or
<%= select (‘task’, ‘client_id’, @clients.collect {|c| [ c.name,
c.id ]
}) %>

Nick-

Here is an example of how you can get started doing this:

— In the view file ----

<%= select (‘task’, ‘parent_id’, @parents.collect {|p| [ p.title,
p.id ]},
{ :include_blank => true,
:onchange => remote_function( :with =>
“‘parent_id=’+value”,
:loading => “Element.show(‘loading-
indicator’)”,
:url => { :action
=> :select_with_ajax } )) %>}) %>
<%= image_tag(‘indicator.gif’,
:id => ‘loading-indicator’,
:style => ‘display:none;’ ) -%>

— In the controller action----

def select_with_ajax
@clients = Client.find(:all, :conditions => [“parent_id = ?”,
params[:parent_id])
render :update do |page|
page.replace_html(‘next_select’, :partial =>
‘second_select’, :collection => @clients
page.hide(‘loading-indicator’)
end
end

The loading indicator gif is one of those little spinner animated gif
files. You might need to change the @client=Client.find line to fetch
whatever it is you want to populate the next select box with. And you
will need a partial called _second_select.rhtml that has the code for
the second select box.

Hope that gets you over the hump.

Cheers
-Ezra


#4

On Apr 29, 2006, at 11:39 PM, Nick C. wrote:

the indicator image showing, the select box never updates. This is
the
code:

Nick -

The best way to debug these ajax pages is with firefox and the

firebug plugin. It lets you examine the ajax calls and returns from
the server so you can see exactly what the browser is getting back
from your ajax call. The thing is when you use rjs, the text returned
from the ajax action is eval’ed as javascript. If its not valid
javascript then it won’t appear to do anything.

SO go get that plugin and see whats coming back when it seems like

its not returning. Also you can look at your development.log and you
can see the ajax requests. Check there to see if the select_with_ajax
is getting called or not.

-Ezra


#5

I don’t think “select_with_ajax” is ever getting called, because no
matter what I put inside that function, it never happens.

n.

Nick C. wrote:

Hi Ezra

The code makes sense, but its not working as expected. While I do get
the indicator image showing, the select box never updates. This is the
code: