提问人:FuzzyJulz 提问时间:6/18/2014 最后编辑:FuzzyJulz 更新时间:9/9/2014 访问量:995
在 Rails 中使用不显眼的 javascript 的父子选择下拉关系
Parent-child select dropdown relationships using unobtrusive javascript in Rails
问:
我有一个应用程序,它在场馆和大厅之间有一个非常简单的父>子关系(所以一个活动有一个场地,一个场地有很多大厅),在管理屏幕中,我希望能够选择一个场地(通过选择框中的关联)并让它自动填充(最好是 AJAX JSON 请求)该场地的大厅(在另一个选择框中)。
在我看来,这种东西要么是标准的,要么是在某个地方的宝石中,有没有更好的选择?
我已经附上了我当前的解决方案
答:
-1赞
FuzzyJulz
6/18/2014
#1
我仔细研究了一下,发现: 如何使用不显眼的jQuery脚本在Rails 4中实现依赖下拉列表
我已经接受了这个并对其进行了一点混蛋,以使其正常工作并使其更简单,并纠正了一些错误:chosen
_form.haml:
= simple_form_for(@event, ... ) do |f|
= f.association :hall, collection: @event.venue.halls.order(:name), include_blank: false, input_html: {class: "chosen",
data: {linked: "select",
linked_parent_id: "event_venue_id",
linked_collection_path: venue_halls_path(":venue_id:")}}
= f.association :venue, include_blank: false , :input_html => {class: "chosen"}
请注意,value 和 label 是可选的,以下方法也有效:
data: {linked: "select",
linked_parent_id: "event_venue_id",
linked_collection_path: venue_halls_path(":venue_id:"),
linked_collection_value: "id",
linked_collection_label: "name"}
routes.rb 包含以下映射(通过资源):
venue_halls_path GET /venues/:venue_id/halls(.:format) halls#index
即
...
resources :venues, shallow: true do
resources :halls
end
...
halls_controller.rb:
...
def index
@halls = Venue.find(params[:venue_id]).halls.order(:name)
respond_to do |format|
format.html {}
format.json { render json: @halls.to_json }
end
end
...
应用程序.js:
...
$('select[data-linked=select]').each(function (i) {
var child_dom_id = $(this).attr('id');
var parent_dom_id = $(this).data('linked-parent-id');
var path_mask = $(this).data('linked-collection-path');
var path_regexp = /:[0-9a-zA-Z_]+:/g;
var option_value = $(this).data('linked-collection-value');
var option_label = $(this).data('linked-collection-label');
var child = $('select#' + child_dom_id);
var parent = $('#' + parent_dom_id);
var loading_prompt = $('<option value=\"\">').text('Loading options...');
var no_items_prompt = $('<option value=\"\">').text('No options available');
option_value = (option_value === undefined ? "id" : option_value);
option_label = (option_label === undefined ? "name" : option_label);
parent.on('change', function () {
child.attr('disabled', true);
child.empty().append(loading_prompt);
child.trigger("chosen:updated")
if (parent.val()) {
var path = path_mask.replace(path_regexp, parent.val());
$.getJSON(path, function (data) {
child.empty();
var itemsChanged = false;
$.each(data, function (i, object) {
if (object[option_value] === undefined) {
$.each(object, function (i, subobject) {
child.append($('<option>').attr('value', subobject[option_value]).text(subobject[option_label]));
itemsChanged = true;
});
} else {
child.append($('<option>').attr('value', object[option_value]).text(object[option_label]));
itemsChanged = true;
}
});
child.attr('disabled', !itemsChanged);
if (!itemsChanged) {
child.append(no_items_prompt);
}
child.trigger("chosen:updated")
});
}
});
});
上一个:ng-click 是否突兀
评论