我试图制作动态表单。我有类别,有很多主菜,有很多方面。当你选择一个主菜,我试图根据主菜类别填充两侧。
我将进行ajax调用以填充此内容,但我需要类别的ID才能执行此操作。
我已考虑将类别ID作为类别的ID /类别或甚至每个选项附加,但我不知道如何执行此操作。
这是我的groups_collection选择:
<%= f.grouped_collection_select(:food_item, restaurant.categories, :entrees, :name, :id, :name) %>
答案 0 :(得分:0)
HTML5引入了“数据”属性 - 可用于将数据附加到页面上的元素:
$('.foo').click(function(){alert($(this).data('id'))})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="foo" data-id="1" >Test</button>
使用grouped_collection_select,您可以使用html_options
参数将数据附加到元素。
有几种方法可以解决这个问题:
<强> js.erb 强>
将Rails用作“懒人”SPA。这意味着您将对/entrees/1/sides.js
之类的内容发出AJAX请求。
class SidesController
def index
@entree = Entree.join(:sides).find(params[:entree_id])
@sides = @entree.sides
respond_to do |f|
f.html
f.js
end
end
end
这将呈现如下所示的模板:
// app/views/sides.js.erb
jQuery("#some_element").html('<%=j f.grouped_collection_select(:food_item, restaurant.categories, :entrees, :name, :id, :name) %>');
然而,在过去十年中,我们在构建应用程序方面所学到的所有关于ruby,javascript和HTML的糟糕情况。
很难调试正在发生的事情 - 甚至更糟糕的是用javascript测试工具进行单元测试是不可能的。你必须依赖硒或水豚,这是非常缓慢的。
客户端模板
在这种情况下,您会要求服务器提供JSON并在客户端中对其进行转换:
让我们说/entrees/1/sides.json
返回一个对象数组:
[
{ id: 1, name: 'Mashed Potatoe' },
{ id: 22, name: 'Pickled Herring' },
{ id: 51, name: 'Grilled Veggies' }
]
您可以将其处理为选项元素列表,如下所示:
var promise = $.getJSON('/entrees/1/sides.json');
promise.pipe(function(data){
return $.map(data, function(item){
return $("<option>"+ item["name"] +"</option>").val(item[:id]);
});
}).done(function(opts){
$('#some_element').append(opts);
});
对于更复杂的示例,您将需要使用JS模板系统。
<%= content_tag :select, name: "meal[food_item]" id="meal_food_item">
<%= restaurant.categories.each do |c| %>
<% uri = category_sides_path(category_id: c, format: :json) %>
<%= content_tag(:optgroup, label: c.name, "data-uri" => uri) do %>
<%= options_from_collection_for_select(c.entrees, 'id', 'name') %>
<% end %>
<% end %>
<% end %>
不是uri
就可以在任何地方取得优势。
$(".new_meal #meal_food_item").on('change', function() {
var $selected, promise, data_uri;
$selected = $(this).find(:selected).parents('optgroup');
promise = $.getJSON($selected.data('uri'));
promise.done(function(data){
// update the sides select
});
});