我无法使用AJAX更新包含nested_attributes_for表单的partial。
我的应用程序需要根据主窗体中选择的事件类型加载窗体的新部分。与每种类型关联的字段存储在数据库表中。
目前,当我选择一个事件类型时,事件类型的id将通过远程函数传递给事件控制器。 (以下代码)
<%= 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)" ), } %>
这会成功将我的id发送到控制器,然后搜索与事件类型id相关联的所有字段,然后用包含其他字段的partial替换空div(“specifics”的id)。 (以下代码)
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。
答案 0 :(得分:1)
好的,我现在有一个有效的动态表单,我使用javascript来构建它。我想我会在这里发布我的解决方案以防万一有人偶然发现这个问题。
获取控制器中的所有事件字段新操作:
@event_fields ||= EventField.all
在partial中,循环遍历所有字段并按事件类型id对它们进行分组,然后遍历分组记录以构建包含字段的div(其id只是与字段关联的事件类型ID)。
<% 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 ids验证(div ids不应该以数字开头 - 容易修复)我应该删除测试变量并将其全部移动到帮助器而不是清理风景。
我真的不太喜欢这个解决方案,但我看不到任何其他方式,所以,如果你知道更好,请不要犹豫,建议一种新方法。