возникли проблемы при передаче formbuilder с использованием функции remote_function с nested_attributes_for - PullRequest
0 голосов
/ 04 октября 2010

У меня проблемы с обновлением части, содержащей форму nested_attributes_for, с помощью AJAX.

Моему приложению необходимо загрузить новый раздел формы на основе типа события, выбранного в основной форме. Поля, связанные с каждым типом, хранятся в таблице базы данных.

В тот момент, когда я выбираю тип события, идентификатор типа события передается в контроллер событий через удаленную функцию. (код ниже)

<%= event_form.collection_select :type_id, Type.find(:all, :order => "event_type"), :id, :event_type, { :prompt => 'Select Event Type' }, { :onchange => 
  remote_function(
     :url => event_specifics_events_path,
     :with => "'type=' + encodeURIComponent(value)" ), } %>

Это успешно отправляет мой идентификатор контроллеру, который затем ищет все поля, связанные с идентификатором типа события, а затем заменяет пустой div (идентификатор "specics") частичным, который будет содержать дополнительные поля. (код ниже)

    def event_specifics
    # Catch passed variable and search for event fields by event type id
    selected_type = params[:type]

    @event_fields = EventField.type_id_equals(type)

    if @event_fields
        render :update do |fields|
            fields.replace_html 'specifics', :partial => 'event_specifics', :locals => { :event_form => event_form, :event_fields => @event_fields }
        end
    end
end

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

<% if @event_fields %>
<hr 100%>

<% event_form.fields_for :event_specifics do |specifics| %>
    <% for field in @event_fields %>
        <% if field.field_type == "check_box" %>
            <%=h eval "#{@specifics}.#{field.field_type} 'value', {}, '#{field.field_value}', ''" %><strong><span class="pipe"><label><%=h field.field_label %></label></strong>
        <% elsif  field.field_type == "radio_button"  %>
            <%=h eval "#{@specifics}.#{field.field_type} 'value', '#{field.field_value}'" %><strong><span class="pipe"><label><%=h field.field_label %></label></strong>
        <% else %>
            <p>
                <br /><strong><span class="pipe"><label><%=h field.field_label %></label></span><span style="color:#E81E57;">*</span></strong><br />
                <%=h eval "#{@specifics}.#{field.field_type} 'value'" %>
            </p>
        <% end %>
    <% end %>
<% end %>
<% end %>

Когда я пытаюсь запустить это, я получаю сообщение об ошибке

undefined local variable or method `event_form' for #<ActionView::Base:0x431b2d8>

Я попытался передать построитель event_form в URL и обработать его как параметр, а затем пожаловался, что не может вызвать fields_for для строки.

строитель 'event_form' - это конструктор в родительской форме:

<% remote_form_for @event, :url => { :controller => "events", :action => "create" } do |event_form| %>

У кого-нибудь есть идеи или решения, которые могли бы решить эту проблему? Заранее спасибо!

На случай, если это кому-нибудь поможет, я использую Ruby 1.8.7 и Rails 2.3.8 с Prototype 1.6.0.3.

1 Ответ

1 голос
/ 06 октября 2010

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

Получить все поля событий в контроллерах. Новое действие:

@event_fields ||= EventField.all

В частичном цикле переберите все поля и сгруппируйте их по идентификатору типа события, а затем переберите сгруппированные записи, чтобы создать элементы div (идентификаторы которых являются только идентификаторами типов событий, с которыми связаны поля), содержащие поля. *

    <% event_form.fields_for :event_specifics do |specifics| %>
    <% test = @event_fields %>
    <% for field in @event_fields %>
        <div id="<%=h field.type_id %>", style="display:none;", class="specifics_fields">
            <hr 100%>
            <% type_fields = test.select { |t| t.type_id == field.type_id } %>
            <% for type in type_fields %>
                <% if type.field_type == "check_box" %>
                    <%=h eval "specifics.#{type.field_type} 'value', { }, '#{type.field_value}', nil" %><strong><span class="pipe"><label><%=h type.field_label %></label></strong>
                <% elsif  type.field_type == "radio_button"  %>
                    <%=h eval "specifics.#{type.field_type} 'value', '#{type.field_value}'" %><strong><span class="pipe"><label><%=h type.field_label %></label></strong>
                <% else %>
                    <p>
                        <br /><strong><span class="pipe"><label><%=h type.field_label %></label></span><span style="color:#E81E57;">*</span></strong><br />
                        <%=h eval "specifics.#{type.field_type} 'value'" %>
                    </p>
                <% end %>
            <% end %>
        </div>
    <% end %>
<% end %>

Выберите поле:

<%= event_form.collection_select :type_id, Type.find(:all, :order => "event_type"), :id, :event_type, { :prompt => 'Select Event Type' }, { :onchange => "myFunction(this.value);", } %>

Функция JS:

function myFunction(value) {
$$('.specifics_fields').each(function(e){
    e.hide();
});
$(value).show();
}

Evenything тогда функционирует как задумано и довольно эффективно. Все, что на самом деле здесь требуется, - это небольшая настройка для проверки правильности идентификаторов div (идентификаторы div не должны начинаться с цифры - это легко исправить), и мне, вероятно, следует удалить тестовую переменную и вместо этого переместить все в помощник для очистки вид.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...