我正在实施一个实时搜索,其中包含一个包含多个字段的下拉列表,以便进行过滤。它只从一个搜索字段开始,一个下拉菜单选择要搜索的内容,另一个按钮用于添加更多过滤器,当用户点击时按钮,它会生成一个新字段:
此图像样本使用JavaScript内部的html进行硬编码。问题是我将在很多视图中使用它,所以我需要它是动态的,因为我以前使用Ruby生成第一个搜索字段的代码。我试过这样做,但没有成功。
live_search.js.erb
$(function () {
function search() {
$.get(window.location.href, { object_columns: $("select#object_columns").val(), search: $("#search").val() }, null, "script");
};
$("select#object_columns").change(search);
$("input#search").keyup(search);
$('button').on('click',function(){
column = "<%= j render 'shared/search_engine' %>";
$('#search-form').after(column);
});
});
search_engine.html.erb
<div id="search-form">
<%= form_tag do %>
<% valid_column_names = target.column_names.reject{|r| r == "created_at" || r == "updated_at" || r == "slug"} %>
<%= select_tag :object_columns, options_for_select(valid_column_names) %>
<%= text_field_tag :search, '', autocomplete: :off %>
<% end %>
<%= button_tag "+" %>
</div>
我甚至试图在点击按钮时调用JavaScript中的“搜索表单”来复制代码,但我读到它是不可能的。
修改
我在@ppascualv建议时进行了一些更改,但是当我点击按钮时,我仍然无法渲染并添加另一个“search_engine”。我收到错误说未定义方法'render'。
live_search.js.erb
$(function () {
function search() {
$.get(window.location.href, { object_columns: $("select#object_columns").val(), search: $("#search").val() }, null, "script");
};
$("select#object_columns").change(search);
$("input#search").keyup(search);
$('button').on('click',function(){
$('button').append("<%= escape_javascript(render @search_engine) %>");
});
});
search_engine.html.erb
<div id="search-form">
<%= form_tag({controller: "house_activities", action: "index"}, method: "get", remote: true) do %>
<% valid_column_names = HouseActivity.column_names.reject{|r| r == "created_at" || r == "updated_at" || r == "slug"} %>
<%= select_tag :object_columns, options_for_select(valid_column_names) %>
<%= text_field_tag :search, '', autocomplete: :off %>
<% end %>
<%= button_tag "+" %>
</div>
house_activities_controller.rb
class HouseActivitiesController < ApplicationController
before_action :set_house_activity, only: [:show, :edit, :update, :destroy]
def index
@house_activities = HouseActivity.page(params[:page]).per(5).search_for(params[:object_columns], params[:search])
respond_to do |format|
format.js
format.html
end
end
end
答案 0 :(得分:1)
你应该看一下Javascript with Rails,为了实现你的建议,你需要创建一个用你的js.erb响应的控制器,这个动作应该从data-remote=true
的链接调用或者来自ajax。
答案 1 :(得分:0)
您可以执行以下操作:
<强> search_engine.html.erb 强>
<%= form_tag(target_path, method: :get) do %>
<%= text_field_tag :query, nil, placeholder: "Search by column names...", class: "form-control search-form" %>
<% end %>
<强> live_search.js 强>
$(document).on("change", ".search-form", function() {
return $(this).parents("form").submit();
});
然后在目标模型中,您可以添加search
范围以使其成为动态范围。
<强> target.rb 强>
class Target < ActiveRecord::Base
scope :search, -> (query) {
return if query.blank?;
where("target.column_name1 ILIKE :query or target.column_name2 ILIKE :query or target.column_name3 ILIKE :query", query: "%#{query}%")
}
end
在 targets_controller.rb
中class TargetsController < ApplicationController
def search_engine
@targets = Target.search(params[:query])
end
end
答案 2 :(得分:0)
我能够解决我的问题。我发现你不能在资产中渲染东西,也不能在JavaScript文件中使用ruby。我做了一些解决方法并完成了它,我使用<script> JavaScript code </script>
语法将JavaScript代码包含在 html.erb 文件中,如下所示:
<script type="text/javascript">
column =
'<%= form_tag({controller: "people", action: "index"}, method: "get", remote: true) do %>' +
'<% valid_column_names = Person.column_names.reject{|r| r == "created_at" || r == "updated_at" || r == "slug"} %>' +
'<%= j (select_tag :object_columns, options_for_select(valid_column_names)) %>' +
'<%= text_field_tag :search, '', autocomplete: :off %>' +
'<% end %>';
$('button').on('click',function(){
$('button').after(column);
});
</script>
因为 select_tag ruby行生成了一个带有大量引号的句子,所以使用的 j 与 escape_javascript 相同并且使用它格式化一个句子,以便JavaScript可以正确读取它。