2009-06-10 37 views
6

Tôi đang cố gắng thực hiện một cái gì đó dường như rất đơn giản, và tôi đã đánh đầu mình chống lại nó trong nhiều ngày tại thời điểm này.Ruby on Rails Quốc gia/Tiểu bang Chọn Enigma

Kết quả cuối cùng mong muốn của tôi là menu thả xuống Chọn quốc gia, được gắn với menu thả xuống chọn trạng thái, theo cách mà khi một quốc gia cụ thể được chọn, NẾU các trạng thái được hiển thị trong một lựa chọn thả và nếu NO được biết đến với quốc gia đó, thì trường văn bản sẽ được hiển thị thay thế.

Tôi cảm thấy mình gần như ở đó. Tại thời điểm này, giao diện sẽ thực sự tạo danh sách các trạng thái dựa trên quốc gia của người đó, ngoại trừ việc từ chối cập nhật thả xuống động.

Các phần của quan điểm của tôi nơi đất nước và tình trạng vị trí được tập hợp trông giống như:

# _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>  

Các phúc phần tham chiếu trong DIV được như sau:

# _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 %> 

Cuối cùng, các mã điều khiển mà nhằm cập nhật danh sách các trạng thái động:

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 

Bây giờ , mã này đang được gọi vào đúng thời điểm và tạo danh sách các trạng thái thích hợp. Ví dụ: khi người dùng nhấp vào Úc, "Đang cố gắng cập nhật tiểu bang ... Quốc gia = Úc, tiểu bang = Lãnh thổ Thủ đô Úc, New South Wales, Lãnh thổ phía Bắc, Queensland, Nam Úc, Tasmania, Victoria, Tây Úc" sẽ hiển thị trong quá trình máy chủ. Tuy nhiên nó không cập nhật trang và sẽ không in "OK" ở cuối. Nói tóm lại dòng đó là không chắc chắn là

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

Lưu ý rằng việc thay thế dòng này với

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

đúng thay thế div, nhưng tất nhiên không phải với bất cứ điều gì hữu ích.

Ai đó có thể giúp tôi hiểu điều gì đang xảy ra ở đây không?

Trả lời

1

Dường như bạn đang giả định rằng biến @person vẫn có sẵn từ hành động ban đầu của bạn. Điều này có thể được thiết lập bởi bộ lọc cho người hiện tại nhưng bạn không thể hiện điều đó trong câu hỏi của mình.

Nếu bạn cần tìm kiếm lại @person, bạn sẽ phải chuyển id qua trong remote_function của mình.

+0

OK, tôi chuyển id vào hàm update_states và tìm kiếm người đó một lần nữa. Nhưng nó vẫn không tự động cập nhật biểu mẫu. Có phải vấn đề mà tôi đang cố tạo biến cho biểu mẫu không? Nói cách khác, là "f = form_form (@object)" hợp lệ trong bộ điều khiển, và bạn có thể chuyển biến này thành một phần không? –

+0

Đó là nghĩa vụ phải là "f = form_for (@object)", tất nhiên. –

+1

Bạn có thực sự nhận lại bất kỳ lỗi nào hoặc trong nhật ký không? Có thể nó không thích form_for trong kết xuất trong update_states. Có thể đáng để thử: "select: person,: state ..." thay vì các công cụ form_for. – Shadwell

1

Ryan Bates có Railscast hiển thị cách chọn danh mục cho sản phẩm hoặc tạo danh mục mới bằng cách nhập tên. Nó giống như một kịch bản tương tự với những gì bạn có, vì vậy bạn có thể muốn kiểm tra nó ra: Create Model Through Text Field.

+0

Cảm ơn! Nhưng không chính xác những gì tôi đang tìm kiếm. Tôi không cần tạo các quốc gia mới dựa trên dữ liệu nhập của người dùng; Tôi chỉ cần tự động điền danh sách lựa chọn. Bây giờ, # 88 gần như chính xác những gì tôi đang cố gắng làm, nhưng tôi không thể có được phương pháp của anh ấy để làm việc với Carmen. Ryan sử dụng các mô hình Nhà nước và Quốc gia, nó có vẻ lộn xộn với tôi (có lẽ ít lộn xộn hơn so với trộn mã xem trong bộ điều khiển, nhưng nếu tôi có thể làm cho nó hoạt động - tức là, với vị trí địa lý và mọi thứ - tôi định phá vỡ toàn bộ vị trí- thu thập cơ chế vào mô hình/người trợ giúp vị trí.) –

0

Điều này đã cho tôi một ngày để tìm ra điều gì đó mà ít nhất là "công việc". Tôi cũng đang sử dụng Carmen và cũng rối tung với thẻ được chọn trong một mẫu biểu mẫu form_for (thực tế, fields_for lồng trong forms_for ... thêm các biến chứng bổ sung).

Tôi nghĩ rằng có một giải pháp tốt hơn nhưng điều này có hiệu quả đối với tôi. Lựa chọn cần được tham chiếu bởi biểu mẫu nhưng các tùy chọn thì không. Vì vậy, lần đầu tiên thông qua, tôi sử dụng phương thức Carmen state_select điền vào thẻ chọn một cách chính xác và tất cả các thẻ tùy chọn lồng nhau. Lần thứ hai thông qua, tôi chỉ thay thế các tùy chọn.Hãy xem:

Trong giao diện, tôi đã chọn để sử dụng một phương pháp observe_field kể từ khi tôi làm những việc khác bên cạnh việc cập nhật các trạng thái (một số thay đổi địa hóa khác) nhưng điều này nên làm việc cho remote_function và những người khác, quá:

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

Đừng để bị nhầm lẫn bởi id (user_address_attributes_country) nó chỉ là forms_for ngớ ngẩn của tôi/thực hiệ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' %> 

Sau đó, trong bộ điều khiển của tôi, nó chỉ trông như thế này:

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 

Lưu ý: state_options_for_select cũng đến từ Carmen. Tôi không thể làm cho nó hoạt động trừ khi tôi đặt nó bên trong khối respond_to nơi tôi đoán người trợ giúp xem có sẵn. Ngoài ra, tôi mã cứng user_address_attributes_state là id lồng nhau của tôi được tạo từ form_for/fields_for address_form.state_select hiển thị cuộc gọi trong chế độ xem.

Tôi hy vọng điều này sẽ hữu ích. Nếu ai đó có thể làm tốt hơn, hãy tin tôi, tôi là tất cả tai. Tôi sẽ thay đổi thiết kế trong thời gian ... nhưng cần một cái gì đó mà chỉ cần làm việc ngày hôm nay và điều này là tốt nhất tôi có thể tìm ra trong một thời gian hạn chế.