2009-04-07 26 views
6

Ứng dụng của tôi có một hộp chọn để người dùng chọn "địa điểm". Hộp chọn này, như bạn mong đợi, trong một biểu mẫu. Tôi cũng có một hành động ở đâu đó trên trang tạo địa điểm mới thông qua AJAX. Sau khi địa điểm mới được tạo, tôi muốn cập nhật hộp chọn địa điểm để phản ánh điều này.Có thể đặt một phần tử dạng đường ray chỉ trong một phần không?

Giải pháp của tôi là đặt hộp chọn một phần và hiển thị một phần từ hành động tạo trong bộ điều khiển.

<div id="venue_select" style="clear: both;"> 
    <%= render :partial => 'venue/venue_select_box' %> 
</div> 

Các chàng một phần như thế này:

<%= f.collection_select :venue_id, @user_venues, :id, :name, :prompt => 'Select a venue' %> 

trong đó f là tài liệu tham khảo dạng:

<% form_for :shows do |f| %> 

Vấn đề là f là undefined trong một phần, vì vậy tôi nhận được một lỗi . Một giải pháp sẽ bao gồm toàn bộ biểu mẫu, nhưng tôi cảm thấy như vậy không cần thiết vì tôi không cập nhật toàn bộ biểu mẫu. Bất kỳ ý tưởng về cách đi về điều này?

Trả lời

0

Đây là tất cả lựa chọn tuyệt vời nhưng tôi nghĩ rằng tôi thấy dễ dàng nhất. Về cơ bản, tôi chỉ cứng mã hóa tên trong collection_select vì vậy tôi sẽ không cần "f" biến:

<%= collection_select 'shows[venue_id]', :venue_id, @user_venues, :id, :name, { :prompt => 'Select one of your previous venues' } %> 

Sau đó VenueController của tôi là như sau:

class VenueController < ApplicationController 
    layout 'main' 
    before_filter :login_required, :get_user 

    def create 
    begin 
     venue = @user.venues.create(params[:venue]) 
     @user_venues = @user.venues 
     render :partial => 'venue_select_box', :success => true, :status => :ok 
    rescue ActiveRecord::RecordInvalid => invalid 
     flash[:errors] = invalid.record.errors 
     render :text => '', :success => false, :status => :unprocessable_entity 
    end 
    end 

end 

Nếu phương pháp này là xấu thực hành cho bất kỳ lý do gì, xin vui lòng cho tôi biết và tôi sẽ vui lòng trả cho bạn câu trả lời.

8

Bạn có thể vượt qua một biến với một phần như thế này:

<%= render :partial => 'venue/venue_select_box', :locals => { :f => f } %> 

Đối với công cụ như thế này nó luôn luôn là tốt để nhìn vào documentation.

EDIT: Để sử dụng một phần với yêu cầu AJAX, bạn sẽ cần phải "tạo lại" biểu mẫu trong mẫu .rjs của bạn. Vì vậy, trong bộ điều khiển của bạn, bạn sẽ cần phải tìm đối tượng một lần nữa.

def venue_select 
    @venue = Venue.find(params[:id]) 
    respond_to do |format| 
     format.html 
     format.js 
    end 
end 

Sau đó, trong địa điểm của bạn/venue_select.rjs file:

form_for @venue do |f| 
    page[:element].replace_html :partial => 'venue/venue_select_box', :locals => { :f => f } 
end 

đâu :element là id của menu chọn bạn muốn thay thế. Về cơ bản bạn chỉ cần tạo lại form_for và sau đó sử dụng nó để cập nhật trường chọn.

+0

Điều này hoạt động từ chế độ xem, nhưng tôi cũng sẽ cần hiển thị từ bộ điều khiển. Hộp chọn sẽ lấy dữ liệu có thể được cập nhật qua AJAX, và do đó yêu cầu cập nhật đó sẽ yêu cầu bộ điều khiển hiển thị lại phần ... và sau đó "f" lại không xác định – Tony

+0

Ah, xin lỗi, tôi không thấy nhu cầu AJAX trong câu hỏi của bạn. Có lẽ tôi nên đọc kỹ hơn một chút vào lần sau ... Tôi vừa cập nhật câu trả lời của tôi với một thứ có thể giúp bạn. – vrish88

+0

Bạn sẽ làm như thế nào với Rails 3/4 và UJS? Vấn đề tôi đang gặp phải là bạn không thể lấy bất kỳ phần nào của biểu mẫu mà không đặt form_for bên trong một thẻ in, sau đó in toàn bộ biểu mẫu. –

1

Có thể dễ dàng thêm địa điểm vào hộp chọn với Javascript, dưới dạng móc nối onComplete trên AJAX của bạn.

1

Tôi đồng ý với Sarah Mei về điều này, nếu có bất cứ điều gì có cuộc gọi AJAX của bạn trả về một đại diện JSON của địa điểm đã được thêm vào và sau đó tạo tùy chọn mới và thêm nó vào phần tử chọn.

Một số mã JS chung của thêm một sự lựa chọn,:

var newOption = new Option("Text", "Value"); 
selectElement.options[selectElement.options.length] = newOption; 
0

Tôi nghĩ rằng giải pháp của bạn không phải là xấu, nhưng nếu bạn cố gắng sử dụng phần này trong biểu mẫu khác, bạn gặp sự cố với tên của trường được tạo.

Để tránh điều này, bạn có thể gửi trong ajax gọi nội dung của f.object_name. Trong trường hợp của bạn, nó sẽ là "show" và vì phương thức là: venue_id tên được tạo sẽ là "shows [venue_id]".

Các vấn đề liên quan