javascript - 无法 AJAXify 功能搜索

标签 javascript ruby-on-rails ajax ruby-on-rails-3

改编this Railscast在我的应用程序中的显示页面上工作,搜索工作正常,但它不是即时的(奇怪的是,它也不是在 keyup 上,尽管它在提交时工作,我认为我没有编码)。

正如我在下面的更新中提到的,当我尝试通过将“remote: true”添加到 form_tag(与 RailsCast 不同)来解决问题时,搜索完全停止运行。知道发生了什么事吗?

index.html.erb

<%= form_tag @post, :method => 'get', :id => "posts_search", class: "search_form squeeze form-inline" do %>
  <p>
    <%= text_field_tag :search, params[:search], 
    placeholder: "Search titles:", id: "search_field" %>
    <%= submit_tag "Search", name: nil, class: "btn squeeze search" %>
  </p>
  <div id="list"><%= render 'search' %></div>
<% end %>

_search.html.erb

<ul class="blog_links">
<% @posts.first(@link_num).each do |p| %>
    <li class="total_hover">
        <%= p.name %>
    </li>
<% end %>
</ul>

index.js.erb

$("#list").html("<%= escape_javascript(render("search")) %>");

posts_controller.rb

  def index
    @posts = Post.search(params[:search]).reverse

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end



 def search
    @posts = Post.search(params[:search]).reverse
    render json: { results: @posts }
 end

post.rb

  def self.search(search)
    if search
      where('name LIKE ?', "%#{search}%")
    else
      scoped
    end
  end

javascripts/posts.js.coffee

$ -> 
  $("#posts_search input").keyup ->
    $.get $("#posts_search").attr("action"), $("#posts_search").serialize(), null, "script"
    false

routes.rb

match '/search', to: 'posts#search'

编辑 -- 当我将“remote: true”添加到我的 form_tag 时,搜索完全停止工作。就像,它既不搜索 keyup 也不搜索提交。

不过,有趣的是,我的网络(在检查器中)似乎在我按下提交时(且仅当)发出 GET 请求。该请求包括我的搜索词,因此,例如,当我在名为“这是一个很长的帖子名称”(带有 slugged url)的帖子页面上搜索“long”时,请求是这样的:

http://localhost:3000/posts/this-is-a-really-long-post-title?utf8=%E2%9C%93&search=long

该 URL 实际上并未显示在 URL 栏中,但它存在于网络请求中。

编辑 -- 按照 Paulo 的建议将 remote:true 移动到我的 form_tag 中的正确位置。所以:

<%= form_tag @post, remote: true, method: 'get', id: "posts_search", class: "search_form squeeze form-inline" do %>

再一次,让 remote:true 停止一般的搜索功能。当我检查那个元素时,我得到了这个:

<form accept-charset="UTF-8" action="/posts/this-is-a-really-long-post-title" class="search_form squeeze form-inline" data-remote="true" id="posts_search" method="get">

“this-is-a-really-long-post-title”是我进行搜索的页面上的帖子标题。它也是 url 中的 slug。因此,我认为问题可能出在我在此标记中调用的操作上。建议使用“/posts”,但是 a) 我在节目中进行搜索,而不是在索引页上进行搜索,并且 b) 当我尝试使用“/posts”时,它会生成以下表单标签:

<form accept-charset="UTF-8" action="/posts" class="search_form squeeze form-inline" data-remote="true" id="posts_search" method="get">

当我按下搜索键时(在控制台检查器中)出现此错误(每当我在搜索框中键入时都会出现类似的错误,因此 keyup 正在运行)。

GET http://localhost:3000/posts?utf8=%E2%9C%93&search= 404 (Not Found) jquery.js:8476
 send jquery.js:8476
 jQuery.extend.ajax jquery.js:7931
 $.rails.rails.ajax jquery_ujs.js:110
 $.rails.rails.handleRemote jquery_ujs.js:175
 (anonymous function) jquery_ujs.js:392
 jQuery.event.dispatch jquery.js:3046
 elemData.handle jquery.js:2722

编辑——如果我删除 remote:true,就像在 Railscast 中一样,并在路径中使用 @post,我会得到这种奇怪的行为组合:

  • 虽然我的 javascript 不再具有与表单的提交相关的任何操作,但当我提交搜索时,页面会完全重新加载并正确执行和显示搜索。
  • 当我只是键入时,Firebug 控制台显示每次按键都会触发一个请求(考虑到我的 JS,这是有道理的),但实际页面上没有任何反应。

同样,当我添加 remote:true 时,页面上什么也没有发生。

编辑 -- 如果我删除 posts.js.coffee 的内容,搜索执行完全相同。就像在 form_tag 中没有 remote:true 时它会起作用,但只有在按下提交时才会起作用。为什么它会忽略 .js.coffee 文件中发生的事情?

编辑以回应 JVNILL 的回答

我用 jvnill 建议的替换了 posts.js.coffee 中的代码。现在搜索根本不起作用,但似乎这是在 javascript 中调用的搜索函数没有做它的事情的结果,导致 preventDefault 调用似乎在工作,当我搜索时(这里,对于“真的”),浏览器似乎将我的按键作为参数发送:

Started GET "/archive?utf8=%E2%9C%93&search=rea&_=1362073395037" for 127.0.0.1 at 2013-02-28 09:43:17 -0800
Processing by PostsController#index as JS
  Parameters: {"utf8"=>"✓", "search"=>"rea", "_"=>"1362073395037"}
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" WHERE (name LIKE '%rea%')
  Rendered posts/_search.html.erb (0.5ms)
  Rendered posts/index.html.erb within layouts/application (1.8ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  Rendered layouts/_header.html.erb (0.5ms)
Completed 200 OK in 23ms (Views: 21.5ms | ActiveRecord: 0.2ms)


Started GET "/archive?utf8=%E2%9C%93&search=real&_=1362073395038" for 127.0.0.1 at 2013-02-28 09:43:17 -0800
Processing by PostsController#index as JS
  Parameters: {"utf8"=>"✓", "search"=>"real", "_"=>"1362073395038"}
  Post Load (0.1ms)  SELECT "posts".* FROM "posts" WHERE (name LIKE '%real%')
  Rendered posts/_search.html.erb (0.6ms)
  Rendered posts/index.html.erb within layouts/application (1.9ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  Rendered layouts/_header.html.erb (0.4ms)
Completed 200 OK in 50ms (Views: 49.2ms | ActiveRecord: 0.1ms)


Started GET "/archive?utf8=%E2%9C%93&search=real&_=1362073395039" for 127.0.0.1 at 2013-02-28 09:43:17 -0800
Processing by PostsController#index as JS
  Parameters: {"utf8"=>"✓", "search"=>"real", "_"=>"1362073395039"}
  Post Load (0.1ms)  SELECT "posts".* FROM "posts" WHERE (name LIKE '%real%')
  Rendered posts/_search.html.erb (0.6ms)
  Rendered posts/index.html.erb within layouts/application (2.0ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  Rendered layouts/_header.html.erb (0.5ms)
Completed 200 OK in 17ms (Views: 16.1ms | ActiveRecord: 0.1ms)


Started GET "/archive?utf8=%E2%9C%93&search=reall&_=1362073395040" for 127.0.0.1 at 2013-02-28 09:43:17 -0800
Processing by PostsController#index as JS
  Parameters: {"utf8"=>"✓", "search"=>"reall", "_"=>"1362073395040"}
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" WHERE (name LIKE '%reall%')
  Rendered posts/_search.html.erb (0.5ms)
  Rendered posts/index.html.erb within layouts/application (1.8ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  Rendered layouts/_header.html.erb (0.4ms)
Completed 200 OK in 16ms (Views: 15.2ms | ActiveRecord: 0.2ms)


Started GET "/archive?utf8=%E2%9C%93&search=reall&_=1362073395041" for 127.0.0.1 at 2013-02-28 09:43:17 -0800
Processing by PostsController#index as JS
  Parameters: {"utf8"=>"✓", "search"=>"reall", "_"=>"1362073395041"}
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" WHERE (name LIKE '%reall%')
  Rendered posts/_search.html.erb (0.6ms)

最佳答案

我不完全确定我是否理解正确,但使用您的原始设置,您的搜索是否有效?您只想通过ajax 提交表单?另外你有一个延迟的搜索响应?我希望下面的代码可以解决这两个问题

@search = ->
  $.get $('#posts_search').attr("action"), $("#posts_search").serialize(), null, "script"

$ ->
  $('#posts_search input').keypress -> search()

  $('#posts_search').submit (e) ->
    e.preventDefault()
    search()

您可以使用 keypress 而不是 keyup 或使用观察搜索字段变化的插件,例如 delayedObserver .您还需要观察何时提交表单并使用ajax而不是普通的表单提交

更新:刚刚注意到日志显示您将执行索引操作,它实际上正在呈现一个 html 模板,这意味着您没有 js 模板。所以将 show.js.erb 复制到 index.js.erb

更新:编辑索引操作。您需要添加的另一件事是 respond_to block 内的 format.js 行,因此它不会默认为 html。

def index
  @posts = Post.search(params[:search]).reverse

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @posts }
    format.js
  end
end

关于javascript - 无法 AJAXify 功能搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15035498/

相关文章:

javascript - 使用正则表达式解析查询参数

javascript - 图像变化取决于下拉值的变化?

javascript - 跨域页面刷新

ruby-on-rails - 如何创建自定义路由助手以供在 routes.rb 中使用

ruby-on-rails - SQL查询(Postgres)正常工作,但不能通过ActiveRecord

javascript - ES6 运行时交换模块

javascript - 在 PHP 的 URL 中使用哈希后的值

php - 使用 PDO AJAX 时 SQL SELECT 查询不起作用

ajax - 如何将 Ajax 与 Symfony2 集成

mysql - 仅删除 Rails 4 中表之间的连接记录