2009-06-10 16 views
6

Estoy tratando de poner en práctica algo aparentemente muy simple, y he estado golpeando mi cabeza contra ella durante días en este punto.Ruby on Rails País/Estado Seleccione Enigma

El resultado final deseado es un menú desplegable de selección de país, vinculado a un menú desplegable de selección de estado, de modo que cuando se selecciona un país determinado, se conocen los estados IF ENTONCES esos estados se muestran en una selección hacia abajo, y si NO se conocen los estados para ese país, entonces se muestra un campo de texto en su lugar.

Siento que ya casi estoy allí. En este punto, la interfaz generará realmente esa lista de estados según el país de las personas, excepto que se niega a actualizar el menú desplegable dinámicamente.

La parte de mi vista en la país y el estado de ubicación se recoge el siguiente aspecto:

# _person_setup.html.erb 
     <td> 
     <%= f.label :country, 'Select your country' %>*<br /> 
     <%= f.select :country, Carmen::country_names, {}, 
      {:style => 'width: 200px', 
      :id => 'country_select', 
      :onchange => remote_function(
      :url => {:action => 'update_states'}, 
      :with => "'country='+value")} %>    
     </td><td> 
     <p> 
     <div id="states_div"> 
      <%= render :partial => 'states', 
       :object => Carmen::states(
          Carmen::country_code(
           @person.country)), 
       :locals => {:form => f} %> 
     </div> 
     </p>    
     </td>  

El ser parcial que se hace referencia en el DIV es el siguiente:

# _states.html.erb 
<% unless states.nil? or states.empty? %> 
    <%= form.label :state, 'Select your state' %>*<br /> 
    <%= form.select :state, states.collect{|s| [s[0], s[0]]} %> 
<% else %> 
    <%= form.label :state, 'Please enter state or province' %>*<br /> 
    <%= form.text_field :state %> 
<% end %> 

Por último, el código de controlador, el cual tiene la intención de actualizar la lista de estados dinámicamente:

def update_states  
puts "Attempting to update states..."  
q = params[:country]  
states = Carmen::states(Carmen::country_code(q)) 
puts "Country = #{q}, states = #{states.collect{|s| s[0]}.join(", ")}." 
render :update do |page| 
    page.replace_html "states_div", 
     :partial => 'states', 
     :object => states, 
     :locals => {:form => form_for(@person)} 
end 
puts "OK" 
end 

Ahora , este código se está llamando en el momento apropiado y está generando las listas apropiadas de estados. Por ejemplo, cuando el usuario hace clic en Australia, "Intentar actualizar estados ... País = Australia, estados = Territorio de la Capital Australiana, Nueva Gales del Sur, Territorio del Norte, Queensland, Australia del Sur, Tasmania, Victoria, Australia Occidental" aparece en el proceso del servidor Sin embargo, no actualiza la página y no imprime el "OK" al final. En resumen la línea que está fallando es, sin duda,

page.replace_html "states_div", 
     :partial => 'states', 
     :object => states, 
     :locals => {:form => form_for(@person)} 

Nota que la sustitución de esta línea con

page.replace_html 'states_div', "<b>is it working</b>" 

reemplaza adecuadamente el div, pero por supuesto no con algo útil.

Puede alguien ayudarme a entender lo que está pasando aquí?

Respuesta

1

Parece que estamos asumiendo que la variable @person aún está disponible desde su acción original. Esto podría ser configurado por un filtro para la persona actual, pero no lo muestra en su pregunta.

Si necesita buscar de nuevo a @person, tendrá que pasar la identificación en su función remota, creo.

+0

OK, estoy pasando el id a la función update_states y buscando a la persona nuevamente. Pero todavía no está actualizando el formulario de forma dinámica. ¿El problema es que estoy tratando de crear una variable para un formulario? En otras palabras, ¿es "f = form_form (@object)" válido dentro del controlador, y puede pasar esta variable a un parcial? –

+0

Se supone que es "f = form_for (@object)", por supuesto. –

+1

¿De verdad está recibiendo errores o en los registros? Es posible que no le guste el form_for en el render en update_states. Podría valer la pena intentar con: "select: person,: state ..." en lugar de form_for stuff. – Shadwell

1

Ryan Bates tiene un Railscast que muestra cómo seleccionar una categoría para un producto o crear una nueva categoría escribiendo el nombre. Suena como un escenario similar al que tiene, por lo que es posible que desee verificarlo: Create Model Through Text Field.

+0

Gracias! Pero no es exactamente lo que estoy buscando. No necesito crear nuevos Estados en función de la entrada del usuario; Solo necesito llenar dinámicamente una lista de selección. Ahora, el # 88 es casi exactamente lo que trato de hacer, pero no pude hacer que su método funcionara con Carmen. Ryan usa modelos estatales y de país, me pareció desordenado (quizás menos desordenado que mezclar código de vista en el controlador, pero si logro hacerlo funcionar, es decir, con la geolocalización y todo lo demás, planeo romper toda la ubicación) reuniendo el mecanismo en un modelo de ubicación/ayudante.) –

0

Esto me tomó un día completo para averiguar algo que, al menos, "trabajo". También estoy usando a Carmen y también estoy jugando con la etiqueta de selección en un form_for model form (en realidad, fields_for anidado dentro de forms_for ... que agrega complicaciones adicionales).

yo creo que hay una solución mejor, pero esto funcionó para mí. La selección debe ser referenciada por el formulario pero las opciones no. Por lo tanto, por primera vez, utilizo el método Carmen state_select que rellena correctamente la etiqueta de selección y todas las etiquetas de opciones anidadas. La segunda vez, simplemente reemplazo las opciones.Echar un vistazo:

En la vista, he optado por utilizar un método observe_field como hago otras cosas además de actualizar los estados (algunos otros cambios de localización), pero esto debería funcionar para remote_function y otros, también:

<%= address_form.country_select :country, {:prompt => "--Select One--"} %> 

no se confunda por el id (user_address_attributes_country) es sólo mi forms_for tonto/aplicación fields_for)

<%= observe_field :user_address_attributes_country, :url => { :action => :changecountry }, :with => 'new_country' %> 

<%= address_form.state_select :state, @user.address.country, {:prompt => "--Select One--"}, :style => 'width: 90px' %> 

Luego, en mi regulador, que sólo se ve así:

def changecountry 
    c = params[:new_country] 

    respond_to do |format| 
    format.html 
    format.js { 
     render :update do |page| 
     page['user_address_attributes_state'].innerHTML = \ 
      "<option>--Select One--</option>" + state_options_for_select(nil, c) 
     end 
    } 
    end 
end 

Nota: state_options_for_select es también de Carmen. No pude hacer que funcione a menos que lo coloque dentro del bloque responder_al donde supongo que los ayudantes de vista están disponibles. Además, código I user_address_attributes_state que es mi id anidado generado a partir de la llamada de representación form_for/fields_for address_form.state_select en la vista.

Espero que esto ayude. Si alguien puede hacerlo mejor, créame, soy todo oídos. Cambiaré el diseño a tiempo ... pero necesitaba algo que funcionara hoy y que fuera lo mejor que pude resolver en un tiempo limitado.