Drop-down list populating second drop-down via AJAX


#1

Hi! The documentation is sparse, and my searches have turned up nothing
yet. Perhaps someone has some insight? Is there a how-to on this? or
what am I missing? :slight_smile:

I have a web page with a drop-down list (high-level key like
Company) that once chosen, should populate another

item with a
list of matching low-order keys (like Product). I have coded something,
but it does not trigger the download of the second HTML snippet with the
new select. (nothing in http log, javascript console, etc)
  1. layout has <%= javascript_include_tag “prototype” %>

  2. controller (call) has

    def index
    @clients = Client.find(:all, :order=>“name”)
    end

    def load_contacts

    I need to get the selected client to here as well! params[?]

    @contacts = ClientContacts.find :all, :order =>“name”
    render :layout=>false
    end

  3. inital view has

    Client: <%=
    options = [[" Select Client", " "]] +
    @clients.collect {|c|[ c.name, c.id]}
    select( “call”, “client_id”, options) %>

    Contacts: <%=
    observe_field “call[client_id]”, #:call_contact_id,
    :update => :client_contact_id_div,
    :url => {:action=>:load_contacts } %>

  4. view for load_contacts is
    <%= options = [[" Select Contact", " "]]

    • @contacts.collect {|c|[ c.name, c.id]}
      select( “call”, “client_contact_id”, options) %>
  5. Versions:
    rails-0.13.1
    actionpack-1.9.1
    Prototype 1.3.1
    Firefox 1.0.7 under Linux


#2

I had to implement similar behavior and got stuck just like you did. I
did
implement a solution that is less than optimal but it works. Perhaps
someone out
there has a better solution.

The way I have solved this is in your ajax callback from the first combo
list
spew out the select html for the second based on the observer pattern.
Thus when
the user changes the selection on combo1 you can define a div in the
original
page which content will populated using the html block returned by the
ajax
callback.

In you callback you ‘compute’ something like that:

render_text “<select id='combo2> <option1…> <option2…>…”

This makes it harder to style and maintain… But it does get the job
done…

Hope this helps…


#3

The first parameter of observer_field should be the id and not the name
of
the select
So in your case it would have to be:
observe_field ‘call_client_id’

bogdan


#4

Thanks, Bogdan! That did the trick. I was trying different names, but I
had not thought about the tag id.

Also I needed to get the value selected from the first drop-down box to
build the data for the second. Here is what I determined I needed for
the controller to populate the second box.

def load_contacts
client_id = request.raw_post
@contacts = ClientContact.find :all, :order =>“privilege desc,name”,
:conditions=>[“client_id=?”,client_id]
render :layout=>false
end