2012-11-29 11 views
18

RORプロジェクトでwill_paginate gemを使用して、ページにレコードを表示しています。will_paginate gemでajaxページネーションを実装する方法

ajaxを使用してページ全体を再読み込みせずに次のページをロードします。

ネットでいくつかの例が見つかりましたが、私にとってはうまくいきません。

これを行う方法?あなたが製品をページ付けする場合

答えて

26

次の内容の新しいヘルパーを(例:アプリ/ヘルパー/ will_paginate_helper.rb。)を作成します。

module WillPaginateHelper 
    class WillPaginateJSLinkRenderer < WillPaginate::ActionView::LinkRenderer 
    def prepare(collection, options, template) 
     options[:params] ||= {} 
     options[:params]['_'] = nil 
     super(collection, options, template) 
    end 

    protected 
    def link(text, target, attributes = {}) 
     if target.is_a? Fixnum 
     attributes[:rel] = rel_value(target) 
     target = url(target) 
     end 

     @template.link_to(target, attributes.merge(remote: true)) do 
     text.to_s.html_safe 
     end 
    end 
    end 

    def js_will_paginate(collection, options = {}) 
    will_paginate(collection, options.merge(:renderer => WillPaginateHelper::WillPaginateJSLinkRenderer)) 
    end 
end 

その後、あなたのビューを使用してAjaxのページ付けのために、このタグ:

<%= js_will_paginate @recipes %> 

を忘れないでくださいページネーションリンクにはURLの既存のパラメータが含まれますが、以下のように除外することができます。これは、機能性をページングする標準です。

希望が問題を解決します。

更新1:この解決策を投稿したoriginal questionに、これがどのように機能するかの説明が追加されました。

アップデート2:私はそれは、リモートとの互換性4レール作った:真のリンクとjs_will_paginateにヘルパーメソッドの名前を変更しました。

+0

私はあなたの答えをいくつか見てきました。あなたのコードを実装した後、コントローラは確実にヒットし、結果はデー​​タベースから取り出されます。しかし、ページはまったく変化していません。私は何が欠けていますか?サーバログに「Rendered jobs/_jobstable.html.erb(80.7ms)」と表示されますが、画面上の実際のページはレンダリングされません。 – notaceo

+0

ブラウザは、ビューを更新するJSレスポンスを期待しているjquery ajax(スクリプトタイプの)呼び出しを行っています。これに対応する方法の1つは、JS <%= "$ body(body)"ですが、html( '#{escape_javascript(render' some_partial ')}'); "。html_safe%>欲しいです。 –

+1

このHackはRails 3.xの魅力のように機能しますが、Rails 4.2では利用できません。 'link_to_function'は推奨されません。アップデートをお願いしますか?少し早いですがお礼を。 – BriceB

15

ねえ、この方法を試してください。

アプリ/コントローラ/ products_controller.rb

def index 
    @products = Product.paginate(page: params[:page], per_page: 10) 
end 

ビュー/製品/ index.html.erb

<div class = "sort_paginate_ajax"><%= render 'products' %></div> 

景色/products/_products.html.erb

<% @products.each do |product| %> 
# your code 
<% end %> 
<%= will_paginate @products %> 

ビュー我々はここで、すべての製品については、製品上のpaginateメソッドを呼び出すことになりますオフセットされているので、最初の

$(function() { 
    $(".sort_paginate_ajax th a, .sort_paginate_ajax .pagination a").on("click", function(){ 
    $.getScript(this.href); 
    return false; 
    }); 
}); 

をapplication.js

$('.sort_paginate_ajax').html("<%= escape_javascript(render("products"))%>") 

資産/ JavaScriptの/ /製品/ index.js.erb params[:page]に従って設定し、制限はper_pageオプションで設定されます。 また、他のページを開くたびにレンダリングされるproducts部分をレンダリングしています。あなたが欲しい@products上の部分のコールで

、その後、will_paginate方法が @productsに適用され、それはまた、コントローラで使用されているparams[:page]を作成します。

ajaxリクエストの応答で、divのコンテンツが、私たちが作成した部分を持つsort_paginate_ajaxというクラスを持っています。

また、aタグのドキュメント読み込みキャプチャスクリプトで、リクエストのAjaxリクエストを行うには、div.sort_paginate_ajaxというタグを付け、falseを返します。

今のページは、私は、これはあなたを助けるでしょう願っていますAJAXリクエスト

で呼び出されます。

+2

素敵な、私が発見した問題は、ページ上の最初のクリックがうまく働いたが、次のページに移動した後、AJAX呼び出しがリンクし、それに適用されていなかったということですhtmlリクエストと呼ばれ、最初のajax呼び出しが行われ、partialが置き換えられたときにページングリンクにライブイベントが追加されなくなったので、js.erbファイルに適切なjsを追加してライブイベントを新しい部分がレンダリングされ、それがうまくいったときのリンク。 !ライブメソッドはjQuery 1.7から非推奨となっているので、適切なjsをjs.erbファイルに追加したとすると、.live()の代わりに.on()と置き換える必要があります。 – rmagnum2002

+0

@ rmagnum2002最初の次のリンクがうまくいくが、次に2番目のリクエストが/?_=1399023289230&page=3のURLにリンクを生成するという問題があります。 .live()を.on()に変更しました。 – Richlewis

+0

@Richlewis https://www.youtube.com/watch?v=UbtmSsjKn38私はこのプロジェクトをプロジェクトで数回使っています。私が話していた適切なものは何だったのでしょうか? .on()と.live()イベントに関連している可能性があります。 – rmagnum2002

3

前の回答に追加。コードの

列:

$(".sort_paginate_ajax th a, .sort_paginate_ajax .pagination a").on("click", function(){ 

文字列で置き換える:

$(".sort_paginate_ajax").on("click", ".pagination a", function(){ 

のonclickイベントが既に存在する要素にのみ適用されます。だから、新たに出現するリンクについては、親 ".sort_paginate_ajax"からchilds ".pagination a"へのdelegate clickイベントが必要です。

1

あなただけのjQueryを使用することができます。

コントローラー:

index.html.erbで次に
def index 
    @posts = Post.paginate(:page => params[:page])  

    respond_to do |format| 
    format.html 
    format.js 
    end 
end 

:一部の '_post_content.html.erb' は、

<div id="post-content", posts: @posts > 
    <%= j render 'post_content' %> 
</div> 

<%= will_paginate @posts %> 
<% @posts.each do |post| %> 
    <p><%= post.content %></p> 
<% end %> 

pagination.js:

$(document).ready(function() { 
    $('.pagination > a').attr('data-remote', 'true'); 
}); 

index.js.erb:それはリンクが設定されますので、

$('#post-content').html("<%= j render 'post_content' %>") 

は、あなたのJSテンプレート(index.js.erb)に再び

$('.pagination > a').attr('data-remote', 'true'); 

を追加してくださいAjaxが実行されているときにもう一度data-remoteを実行します。

0

@ピエールの優れた答えからヘルパーを作成して、私はビューの更新に関するいくつかのフォローアップの質問を見ました(私が最初に持っていた問題)。 @Pierreは、あなたがjsレスポンスを作成する必要があると述べることによって、その問題を追跡します。ここで私はヘルパーを作成した後にやったことだ:私のshow.html.erbで

<div id="see-comments"> 
    <%= render @comments %> 
</div> 
<div id="pagination-comments"> 
    <%= js_will_paginate @comments %> 
</div> 

私はshow.js.と呼ばれる別のファイルを作成ERB(ショーのためので、2つの形式)

// to update comments  
$("#see-comments").html("<%= j render @comments %>"); 
// to update the pagination links 
$("#pagination-comments").html('<%= js_will_paginate @comments %>'); 
関連する問題