我目前在我的models/listing.rb
中有一个方法,其方法如下:
def self.lookup_info(val)
# Fetch some data from the internet
return{ price: value1, title: value2, isbn: val }
end
当用户在创建新商家信息时将val
插入views/listings/_form.html.erb
时,我想调用lookup_info
并填写表单的其余部分(如果结果)(不是nil)归还。
控制器/ listings_controller.rb
def new
@listing = Listing.new
end
视图/列表/ new.html.erb
<%= render 'form', listing: @listing %>
views / listings / _form.html.erb(我在实际代码中使用div标签,但为简单起见,请不要包含以下内容)
<%= form_for(@listing, :html => {class: "form-horizontal" , role: "form"}) do |f| %>
<%= f.label :isbn, "ISBN" %>
<%= f.text_field :isbn , class: "form-control" , id: "isbn_field", placeholder: "ISBN (10 or 13 digits - no dashes)", autofocus: true %>
<%= f.label :price, "Price" %>
<%= f.text_field :price , class: "form-control" , id: "price_field", placeholder: "Price" %>
<%= f.label :title, "URL" %>
<%= f.text_field :title , class: "form-control" , id: "title_field", placeholder: "Title" %>
<%= f.submit class: "btn btn-primary btn-lg" %>
<% end %>
当用户输入users_isbn
时,我需要使用哪些javascript和rails来更新_form.html.erb,我调用lookup_info(users_isbn)
然后获取更新的部分,以便字段的值设置为结果。
回复示例:
<%= form_for(@listing, :html => {class: "form-horizontal" , role: "form"}) do |f| %>
<%= f.label :isbn, "ISBN" %>
<%= f.text_field :isbn , class: "form-control" , id: "isbn_field", placeholder: "ISBN (10 or 13 digits - no dashes)", value: lookup_info(users_isbn)[:isbn] autofocus: true %>
<%= f.label :price, "Price" %>
<%= f.text_field :price , class: "form-control" , id: "price_field", placeholder: "Price", value: lookup_info(users_isbn)[:price] %>
... <!-- Same idea for title -->
<% end %>
这是我到目前为止所做的:
_form.js.erb
(不确定这是否是js文件的正确名称)
var isbnField = document.getElementById('#isbn_field').value;
if (isbnField.length == (10 || 13)){
var ajaxResponse = $.ajax({
url: "listings/lookup",
type: 'GET',
data: {isbn: $('#isbn_field').val()}
});
ajaxResponse.success(function(){
alert("Success"); # I would actually want to <%= j render #name of form partial with values %>
});
ajaxResponse.error(function(){
alert("Could not find that ISBN");
});
}
答案 0 :(得分:1)
我建议按照以下方式进行。
listings_controller.rb
# your new action
# your search action
def search
@foo = lookup_info(val)
# You might have to change this line to something like
# self.lookup_info(val) since I can't see the exact application of
# your lookup_info method. But the idea is you would want to put
# the return values into your @foo.
if @foo
respond_to { |format| format.js { render listings/success }
else
respond_to { |format| format.js {render listings/failure }
end
end
控制器操作说明:
您的表单将提交给控制器操作search
。如果@foo
有效,则意味着如果搜索成功,它将呈现我们将创建的成功部分视图,否则我们将呈现视图以处理失败的表单提交(假设您需要它)。
routes.rb
get "my-search-url", to: "listings#search", as: "my_search_url"
# you can set your own route names
# i assume your form is a get instead of post action
现在为您的表单,将其更改为form_with
<%= form_with(url: my_search_url_path) do |f| %>
如果您使用的是Rails 4而不是Rails 5,则无法使用form_with
,而是必须使用remote: true
来处理ajax请求。
最后,在您的视图中,您需要这两个组件,js.erb
和部分
success.js.erb
$("#holder-for-search").html("<%= j render partial: 'listings/success' %>");
$("#bigger-holder-for-search").fadeIn("1000");
# note that the file name has to be the same as what your respond_to is rendering in your search action
# also remember to create a failure.js.erb too to handle the failed search
_success.html.erb
# render what you want to show if search is successful
在您的new.html.erb
或显示表单的任何位置,只需让您的相关div
包含正确的ID标记(例如#holder for for search)
<div id="bigger-holder-for-search" style="display:none;">
<div id="holder-for-search">
</div>
</div>
// and you can consider fading everything else out to fade in your search response
总之,要重现AJAX响应,您需要4个组件:
1)在您的控制器操作中,您需要respond_to { |format| format.js }
2)您需要在视图中有相应的js.erb
(必须完全像控制器操作或respond_to响应一样命名)
3)您的js.erb
4)remote: true
行动。如果是链接,则将其包含在链接中,如果是表单,则将其包含在表单中。在rails 5中,form_with
隐含remote: true
,因此您无需明确键入该内容。