使ってます will_paginate
gemをROR
プロジェクトに追加して、レコードをページで表示します。
ajax
を使用してページ全体をリロードせずに、次のページをロードしたい。
ネットでいくつかの例を見つけましたが、うまくいきません。
これを行う方法?
次の内容で新しいヘルパー(例:app/helpers/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の既存のパラメーターが含まれることに注意してください。以下に示すように、これらを除外できます。これは標準で機能をページ分割します:
<%= js_will_paginate @recipes, :params => { :my_excluded_param => nil } %>
あなたの問題が解決することを願っています。
更新1:これがどのように機能するかの説明を 元の質問 に追加しました。
アップデート2:私はそれを作成しましたRails 4リモートと互換性があります:trueリンクとヘルパーメソッドの名前をjs_will_paginate。
製品にページ番号を付けたい場合は、これを試してください。
app/controllers/products_controller.rb
def index
@products = Product.paginate(page: params[:page], per_page: 10)
end
views/products/index.html.erb
<div class = "sort_paginate_ajax"><%= render 'products' %></div>
views/products/_products.html.erb
<% @products.each do |product| %>
# your code
<% end %>
<%= will_paginate @products %>
views/products/index.js.erb
$('.sort_paginate_ajax').html("<%= escape_javascript(render("products"))%>")
assets/javascripts/application.js
$(function() {
$(".sort_paginate_ajax th a, .sort_paginate_ajax .pagination a").on("click", function(){
$.getScript(this.href);
return false;
});
});
したがって、最初にすべての製品のProductでpaginateメソッドを呼び出します。ここで、オフセットはparams[:page]
に従って設定され、制限はper_page
オプションによって設定されます。また、他のページが開かれるたびにレンダリングされるproducts
パーシャルをレンダリングしています。
必要な@products
の部分呼び出しで、will_paginate
メソッドを@products
に適用すると、コントローラーで使用されるparams[:page]
も作成されます。
Ajaxリクエストへの応答として、クラスsort_paginate_ajax
を持つdiv
のコンテンツを、作成したパーシャルでレンダリングします。
また、ajaxリクエストをリクエストするには、div.sort_paginate_ajax
内のすべてのa
タグのドキュメントロードキャプチャスクリプトでfalseを返します。
これで、ページはajaxリクエストで呼び出されます
これがお役に立てば幸いです。
以前の回答に追加。
コードの文字列:
$(".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」から子「.pagination a」にデリゲートクリックイベントが必要です。
あなただけのjQueryを使用することができます:
コントローラ:
def index
@posts = Post.paginate(:page => params[:page])
respond_to do |format|
format.html
format.js
end
end
次にindex.html.erbで:
<div id="post-content", posts: @posts >
<%= j render 'post_content' %>
</div>
部分的な '_post_content.html.erb'で:
<%= 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' %>")
必ず追加してください
$('.pagination > a').attr('data-remote', 'true');
再びJSテンプレート(index.js.erb)で、Ajaxの実行時にdata-remoteリンクを再度設定します。
ピエールの答えを詳しく説明したいと思います。
Will_paginate_materializeでmaterialize sassを使用している場合は、ページネーションリンクのスタイルを設定する初期化子が必要です。
gem 'will_paginate', '~> 3.1.0'
gem 'will_paginate-materialize', git: 'https://github.com/mldoscar/will_paginate-materialize', branch: 'master'
したがって、リモートtrueがwill_paginate_materializeイニシャライザによってレンダリングされたリンクで機能するようにするには、次のようにしました。
will_paginate_helper.rb
module WillPaginateHelper
class WillPaginateJSLinkRenderer < WillPaginate::ActionView::LinkRenderer
end
def js_will_paginate(collection, options = {})
will_paginate(collection, options.merge(:renderer =>WillPaginateHelper::WillPaginateJSLinkRenderer))
end
end
マテリアライズイニシャライザをページングする意志を次のように変更しました:
will_paginate_materialize.rb
MaterializePagination::MaterializeRenderer.module_eval do
def page_number(page)
classes = ['waves-effect', ('active' if page == current_page)].join(' ')
tag :li, link(page, page, :rel => rel_value(page)), class: classes
end
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
WillPaginate::ViewHelpers::LinkRenderer.class_eval do
def symbolized_update(target, other, blacklist = nil)
other.each_pair do |key, value|
key = key.to_sym
existing = target[key]
next if blacklist && blacklist.include?(key)
if value.respond_to?(:each_pair) and (existing.is_a?(Hash) or existing.nil?)
symbolized_update(existing || (target[key] = {}), value)
else
if value.instance_variable_defined?(:@parameters)
value = value.instance_variable_get(:@parameters)
end
target[key] = value
end
end
end
end
私の見解では、レンダラーをwill paginateリンクにそのまま残しました:
= will_paginate results, renderer: MaterializePagination::Rails
@Pierreのヘルパー作成に関する優れた回答からフォローするために、ビューの更新に関するフォローアップの質問をいくつか見ました(私が最初に抱えていた問題)。 @Pierreは、js応答を作成する必要があると述べて、その問題を追跡します。ヘルパーを作成した後の操作は次のとおりです。
私のshow.html.erbで
<div id="see-comments">
<%= render @comments %>
</div>
<div id="pagination-comments">
<%= js_will_paginate @comments %>
</div>
Show.js.erbという名前の別のファイルを作成しました(したがって、showの2つの形式)
// to update comments
$("#see-comments").html("<%= j render @comments %>");
// to update the pagination links
$("#pagination-comments").html('<%= js_will_paginate @comments %>');