2013-02-23 144 views
1

改编this Railscast在我的应用我的节目页面上工作,搜索工作正常,但它不是瞬间(也没有,古怪的,是它的keyup,但它确实在提交工作,我以为我没有编码)。不能AJAXify功能搜索

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

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 

Javascript角/ 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时,搜索将完全停止工作。如在中,它既不搜索密钥也不提交。有趣的是,我的网络(在检查员中)似乎在每当(并且仅当)我按下提交时才发出GET请求。这个请求包括我的搜索词,例如,当我在帖子的页面上称为“这是一个非常长的帖子名称”(带有slu url的url)并且搜索“long”时,请求是这样的:

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

该URL实际上并不在地址栏显示出来,但它的存在在网络请求。

编辑 - 按照Paulo的建议移动遥控器:在我的form_tag中正确的位置。所以:

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

再次,有远程:真正停止搜索功能一般。当我检查该元素,我得到这个:

<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"> 

“这 - 是 - 一 - 真的 - 长后标题”是在那里我在进行搜索页面上的文章的标题。这也是网址中的slu g。因此,我认为,这个问题可能是我在这个标签中打电话的行为。“/帖”建议,但)我进行的表演,而不是索引页这个搜索,和b)当我尝试“/帖”,产生这种形式的标签:

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

我当我按搜索时会出现这个错误(在控制台检查器中)(当我在搜索框中键入时会出现类似的错误,所以键入工作正常)。

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 

编辑 - 如果我删除远程:真实,如Railscast,并在路径中使用@post,我得到这种行为怪异的组合:

  • 虽然我的javascript当我提交搜索时,不再有任何与提交相关的任何操作,该页面将完全重新加载并执行正确的搜索。
  • 当我只需键入,Firebug控制台显示了每个按键发射的请求(这是有道理的,因为我的JS),但什么也没有发生实际的页面上。

再一次,当我添加remote:true时,页面上根本没有任何反应。

编辑 - 如果我删除posts.js.coffee的内容,搜索执行完全相同。和in一样,如果在form_tag中没有remote:true,但只有在按下提交时才有效。为什么它忽略了.js.coffee文件中发生了什么?

编辑回应JVNILL的回答

我替换posts.js.coffee代码与jvnill建议什么。现在搜索功能根本不起作用,但似乎这是因为javascript中的搜索函数没有做到这一点,导致preventDefault调用似乎正在工作,并且当我搜索时(这里是“真“),浏览器似乎是送我的按键为PARAMS:

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) 

回答

3

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

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

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

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

你可以用它代替KEYUP按键或用来观察变化像delayedObserver搜索栏的插件。您还需要注意何时提交表单并使用ajax而不是正常表单提交

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

更新:编辑索引操作。您需要添加的另一件事是在respond_to块内部的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 
+0

谢谢!所以澄清,我唯一的问题是,搜索功能不是即时的AJAX。我希望用户输入时缩小帖子的字段。目前,搜索仅在提交时进行,并在URL中显示查询。我用你建议的代码替换了我的posts.js.coffee文件,但问题依然存在。如何确保表单使用AJAX提交,如你所建议的? – Sasha 2013-02-28 17:35:38

+0

对不起。我对Javascript/AJAX非常不满。试图教自己如何适应Rails程序以及如何编写它,但大多数这些函数/概念仍然是我的头。 – Sasha 2013-02-28 17:37:13

+0

编辑 - 所以实际上,当我添加你的代码时,它现在根本不搜索!我认为发生的事情是preventDefault()调用正在工作,但搜索功能没有做任何事情(或者正在返回完整的帖子列表或其他东西)。另外感兴趣的是服务器日志DOES似乎正在注册按键。当我在上面输入搜索内容时,我会粘贴其输出的几行代码。 – Sasha 2013-02-28 17:44:08

0

添加远程选项,您的form_tag。检查docs

<%= form_tag('/posts', :remote => true) %> 
# => <form action="/posts" method="post" data-remote="true"> 

使用Firebug检查,如果产生的形式有数据删除标签为真。

+0

我想知道为什么这不是在Railscast。但是,当我向表单标签添加“remote:true”时,出于某种原因,搜索没有任何作用。当我按下提交时没有任何提示,也没有提示。 – Sasha 2013-02-23 16:54:02

+1

检查更新的答案。确保将选项添加到正确的散列参数。 – 2013-02-24 10:58:36

+0

只是切换东西。它仍然像我上面的评论一样行事,但我在上面的问题中添加了inspector/firebug输出。 – Sasha 2013-02-24 17:32:55