仅显示所选类别的子类别
这是我目前的代码:
它所做的就是在一个下拉列表中显示所有类别,在另一个下拉列表中显示所有子类别。 像这样
问题:如何根据所选的主要类别显示特定的子类别。 使用上面的代码,它显示所有类别和所有子类别。
一切都在模型中链接,has_many和belongs_to …和category_id和subcategory_id..everything正常工作,我只是不知道如何在所选类别中显示特定的子类别。
我的尝试:
"Intro")) do |d| %>
此代码出错。 我要说,例如,如果用户选择名为“简介”的类别而不是列出所有“简介子类别”。 但它没有成功 – 我的代码显然是错误的。
谢谢。
我假设您希望在不重新加载页面的情况下发生这种情况? 那么你就不会有一点JavaScript了。 这是一般工作流程:
- 更改类别下拉列表时,发送一个Ajax请求,该请求将使用JavaScript响应并将正确的值插入子类别下拉列表中。
为了这个例子,我将假设您的表单(属于某个类别的模型)是一个post。 你似乎没有提到这个模型。
我们试试这个:
views / posts / _form :
我将subategories selct框包装在subcategories_select
div中,这使我们可以在以后替换整个内容。
<%= f.collection_select :category_id, Category.all, :id, :name, { prompt: "Choose a category" }, id: "category_id" %> <%= f.collection_select :subcategory_id, Subcategory.all, :id, :name, { prompt: "Choose a subcategory" }, { disabled: true } %>
资产/ Java脚本/ posts.js.erb
# select the element to watch for changes $('form').on('change', '#category_id'), function() { var category_id = $(this).val(); # save the category_id set in the first dropdown $.ajax({ url: "/categories/" + category_id + "/get_subcategories", # a custom route, see routes.rb further down type: "GET", dataType: "script", # we expect a response in js format data: { "category_id": category_id } # the only value we will need to get the subcategories }); });
配置/ routes.rb中
# we need a custom route for our get_subcategories action resources :categories do member do get :get_subcategories, defaults: { format: "js" } end end
控制器/ posts_controller.rb
重要提示:我假设一个类别has_many子类别和子类别具有category_id,这意味着属于一个类别。 如果不是以下则没有意义。
# our custom controller action def get_subcategories @subcategories = Subcategory.where(category_id: params[:category_id]) end
应用程序/视图/职位/ get_subcategories.js.erb
在这里,我们将替换subsategories_select div的内容,并使用适当的选项插入collection_select。
$('#subcategories_select').html("<%= j collection_select(:post, :category_id, @subcategories, :id, :title), { prompt: 'Select subcategory...' }, { disabled: false } %>");
请注意,我是从头脑中做到这一点,因此可能存在错误,但这是一种动态填充选择框的方法,或者通常在不重新加载的情况下更改页面上的任何内容。
这就解决了我的问题
在javascript文件夹中(必须安装砌体gem)
$ -> $('#gigs').imagesLoaded -> $('#gigs').masonry itemSelector: '.box' isFitWidth: true $(document).on 'change', '#gig_category_id', (evt) -> $.ajax 'update_sub_categories', type: 'GET' dataType: 'script' data: { category_id: $("#gig_category_id option:selected").val() } error: (jqXHR, textStatus, errorThrown) -> console.log("AJAX Error: #{textStatus}") success: (data, textStatus, jqXHR) -> console.log("Dynamic country select OK!")
在Gig控制器中
respond_to :html, :js, :json def update_sub_categories @cats = Subcategory.where(category_id: params[:category_id]).all respond_with(@cats) end
比我创建了一个部分的演出视图_subcategory.html.erb并放置此代码
比起另一个名为_update.html.erb的gig视图中的部分放置此代码
$("#gig_subcategory_id").empty().append("<%= escape_javascript(render(:partial => "subcategory", :collection => @cats, :as => :cat)) %>")
最后在视图中显示类别和子类别,我用过
<%= f.collection_select :category_id, Category.all, :id, :name, {prompt: "Choose a category"} %> <%= f.collection_select :subcategory_id, Subcategory.all, :id, :name, {prompt: "Choose a subcategory"} %>
使用js过滤collection_select可能非常困难。 我建议使用group_collection_select,如果关系正确,则会过滤数据。 Asumming你有一个类似于上面答案中提到的数据模型的数据模型,视图应该是这样的:
意见/职位/ _form:
<%= f.collection_select(:category_id, Category.all, :id, :name, { prompt: 'Select a category' }, { id: 'category-select' }) %> <%= f.grouped_collection_select :subcategory_id, Category.all, :subcategories, :name, :id, :name, { include_blank: 'Select a sub category' }, { id: 'subcategory-select' } %>
现在,您将能够看到两个选择表单,但groups_collection_select框显示了一些嵌套选项。 为了只显示必要的子类别,我们需要在javascript中做一些更改,在我的情况下,使用咖啡,我的文件将被命名为.coffee而不是.js.erb
应用程序/资产/ Java脚本/ posts.coffee:
jQuery -> subcat = $('#subcategory-select').html() $('#category-select').change -> cat = jQuery('#category-select').children('option').filter(':selected').text() options = $(subcat).filter("optgroup[label='#{cat}']").html() if options $('#subcategory-select').html(options) else $('#subcategory-select').empty()
我应该对这个来源的答案,你可以找到有关使用group_collection_select的更多细节
因此,您编写的嵌入式ruby在被发送到“客户端”之前会被评估。 这意味着您编写的代码将变为静态HTML并发送给用户。
你想要的是使用可以在用户的浏览器上提供逻辑操作的东西。 这意味着javascript。
结帐:AngularJS: https ://angularjs.org/