Можно ли просто поставить элемент формы рельсы в частичку? - PullRequest
6 голосов
/ 07 апреля 2009

Мое приложение имеет поле выбора для пользователей, чтобы выбрать "место проведения". Это поле выбора находится, как и следовало ожидать, в форме. У меня также есть действие где-то на странице, которое создает новую площадку через AJAX. После того, как новое место будет создано, я хотел бы обновить поле выбора места, чтобы отразить это.

Мое решение состояло в том, чтобы поместить поле выбора в частичное и визуализировать частичное из действия create в контроллере.

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

Частичное выглядит так:

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

где f - ссылка на форму:

<% form_for :shows do |f| %>

Проблема в том, что f не определено в частичном, поэтому я получаю ошибку. Одним из решений было бы включение всей формы, но я чувствую, что в этом нет необходимости, потому что я не обновляю всю форму. Есть идеи, как это сделать?

Ответы [ 5 ]

8 голосов
/ 07 апреля 2009

Вы можете передать переменную частичке следующим образом:

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

Для подобных вещей всегда хорошо посмотреть документацию .

РЕДАКТИРОВАТЬ: Чтобы использовать частичное с AJAX-запросом, вам нужно «воссоздать» форму в вашем шаблоне .rjs. Поэтому в вашем контроллере вам нужно будет снова найти объект.

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

Затем в вашем файле venue / venue_select.rjs:

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

Где :element - идентификатор меню выбора, которое вы хотите заменить. Обычно вы просто воссоздаете форму form_for, а затем используете ее для обновления поля выбора.

1 голос
/ 08 апреля 2009

Я согласен с Сарой Мэй в этом, если ваш AJAX-вызов вернет JSON-представление места, которое было добавлено, а затем создайте новую опцию и добавьте ее в элемент select.

Общий код JS для добавления опции выбора:

var newOption = new Option("Text", "Value");
selectElement.options[selectElement.options.length] = newOption;
1 голос
/ 07 апреля 2009

Может быть проще добавить место в поле выбора с помощью Javascript, как onComplete хук на вашем добавлении AJAX.

0 голосов
/ 20 ноября 2013

Я думаю, что ваше решение неплохое, но если вы попытаетесь использовать это частичное в другой форме, у вас возникнет проблема с именем сгенерированного поля.

Чтобы избежать этого, вы можете отправить в вызове ajax содержимое f.object_name. В вашем случае это будет «показывает», и поскольку метод: venue_id, сгенерированное имя будет «показывает [venue_id]».

0 голосов
/ 08 апреля 2009

Все это отличные варианты, но я думаю, что нашел самый простой. По сути, я просто жестко закодировал имя в collection_select, поэтому мне не нужна переменная "f":

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

Тогда мой VenueController выглядит следующим образом:

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

Если по какой-либо причине этот метод плохой, пожалуйста, дайте мне знать, и я с радостью предоставлю вам ответ.

...