Automatically populating list box items using Ajax

I have page where I have 2 list box , one for countries and one for states.

and I have tables for country and state.

What I want is when I click on any country name , in the next list box it should display all the states in that particular country. I have an idea but dont know how to do with Ajax. Would be great if any one can come up with some example.

Thanks in advance


can you read Portuguese? I can't

no, i cant read .

Babelfish to the rescue! Good luck reading its output!

Rails: Modifying the OPTIONs of the SELECTs

Publicado/atualizado in 09/03/2007 12:37

Yesterday she was giving a hand to the night for my wife, who is to webdesigner and is learning to program now, guess, with Rails (and they guess who is the support-technician-officer-24-hours-VIP of it, tô ferrado) and yesterday it had one probleminha to fill some SELECTs. I go to describe a situation similar to the one that it had:

  • I have 3 SELECTs, one for country, another one for state and another one for city;

  • The logical sequência is all there: the country is selected, the SELECT of the state is filled, the state is selected, and the cities are filled;

  • I used observe_field for country and state, indicating the corresponding controllers and actions; Until there, all good, but probleminhas had appeared ones:

  • I gave a good one searched and I did not find a way to only modify the OPTIONs of the SELECT, what the group walks recommending is or to use replace_html and to change to everything of the element where the SELECT if finds, (in this in case that I found that the layout went to complicate a little) or to use replace to change the proper element, or either, to create a new SELECT with this method.

  • With any one of the options above, observe_field was maluco. He is not for less, we remove and we insert the element that it was “watching”, and it stops to look the cities of the state at the moment that we remove and we insert the element of state with the values returned for the consultation for country. I go to try to illustrate a little the problem and the solution with code (where I only joined everything in a place only for didactic ends, they separate to its controllers certinho). I generated a controller general pool ``with the actions (methods, dã) states, cities and new, and a mount of hashes and arrays to make a simulation of data come of the data base.

The play that I made was to use the method call, that called a function Javascript in the page that requested call AJAX. This function (nastily inserted there inside of the action, for effect of the example - they will be to use place it in an archive js) receives id from the SELECT that we want to bring up to date and the Array with the data to be inserted, makes a “clean one” in the bred new SELECT and adds the OPTIONs from the values of the sent Array. The controller is thus:

  class GeralController < ApplicationController
def estados
@paises_estados = {1=>[ [ ' SP', 1], ['mg', 2]], 2=>[['j1', 3], ['j2', 4 ] ], 3=>[['C1', 5], ['c2', 6 ] ]} to relieve:update of |page| ' fill ', ' states ', @paises_estados[params[:id].to_i ] ' fill ', ' cities ', [ ]
end end def cities @estados_cidades = {1=>[['Mirassol', 1], ['Rio Preto', 2 ] ], 2=>[['Belo Horizonte', 3], ['Divinópolis', 4]], 3=>[['Tokio', 5 ] ], 4=>[['Osaka', 6]], 5=>[['Alberta', 5]], 6=>[['Vancouver', 6 ] ]} to relieve:update of |page| ' fill ', ' cities ', @estados_cidades[params[:id].to_i ] end end def new @paises = [ [ ' Brasil', 1], ['Japão', 2], ['Canadá', 3 ] ] end end

There in the controller all time has a play to send an empty Array of cities that are returned new states, preventing the inconsistency to be with the selected cities previously filled. E view new, already with the function fill, is thus:

< script type="text/javascript" > function fill(id, val){to var select = $(id); to var length = select.length; to for(var i=0; i<length; i++) select.remove(0); if(val.lenght<=0) return; select.appendChild(document.createElement("option")); val.each(function(opt){to var option = document.createElement("option"); option.text = opt[0 ]; option.value = opt[1 ]; select.appendChild(option); })} </script > < form > < p > < label for="paises">Países</label > < select id="paises" > < option></option
> < % = options_for_select(@paises) % > </select > </p > < p > < label
for="estados">Estados</label > < select id="estados" > </select > </p > < p > < label for="cidades">Cidades</label > < select id="cidades" >
</select > </p > < p id="status"></p > < % = observe_field ' paises ',:url=>{:action=>'estados '},:with=>'id ' % > < % = observe_field ' states ',:url=>{:action=>'cidades '},:with=>'id ' % > </form >

I looked for in Prototype and vi much thing not to deal myself with SELECTs, there therefore I made some things half “in the nail” in the function, as to erase the elements and to create the OPTIONs, if somebody to know a direct skill in the Prototype sends me an email that I bring up to date the code. He was very late yesterday and I was not with bag to be fuçando excessively in the API of the Prototype not (although to have sufficiently improved, still he is having a search, he has much thing there).

With this solution I prevented to be removing and inserting the SELECT that I want popular and preventing any problems related to the this.

Huh, that's pretty comprehensible, actually. OK, here's some in Ingrish, the only language i can speak/writ