让will_paginate的分页支持ajax
关于will_paginate插件,请看这个帖子: http://mmm.javaeye.com/blog/116931。
# -----------------------------------------
# will_paginate插件的ajax分页
# -----------------------------------------
@@pagination_options = { : class => ' pagination ' ,
: prev_label => ' 上一页 ' ,
: next_label => ' 下一页 ' ,
: inner_window => 4 , # links around the current page
: outer_window => 1 , # links around beginning and end
: separator => ' ' , # single space is friendly to spiders and non-graphic browsers
: param_name => : page ,
# add by chengang
: update => nil , # ajax所要更新的html元素的id
: url_suffix => '' # url的后缀,主要是为了补全REST所需要的url
# add end
}
mattr_reader : pagination_options
def will_paginate_remote(entries = @entries , options = {})
total_pages = entries . page_count
if total_pages > 1
options = options . symbolize_keys . reverse_merge(pagination_options)
page , param = entries . current_page , options . delete( : param_name)
inner_window , outer_window = options . delete( : inner_window) . to_i , options . delete( : outer_window) . to_i
# add by chengang
update = options . delete( : update)
suffix = options . delete( : url_suffix)
url = request . env[ ' PATH_INFO ' ]
url += suffix if suffix
# add end
min = page - inner_window
max = page + inner_window
if max > total_pages then min -= max - total_pages
elsif min < 1 then max += 1 - min
end
current = min .. max
beginning = 1 .. ( 1 + outer_window)
tail = (total_pages - outer_window) .. total_pages
visible = [beginning , current , tail] . map( &: to_a) . flatten . sort . uniq
links , prev = [] , 0
visible . each do | n |
next if n < 1
break if n > total_pages
unless n - prev > 1
prev = n
# change by chengang
text = (n == page ? n : " [#{n}] " )
links << page_link_remote_or_span((n != page ? n : nil) , ' current ' , text , param , update , url)
else
prev = n - 1
links << ' '
redo
end
end
# change by chengang
links . unshift page_link_remote_or_span(entries . previous_page , ' disabled ' , options . delete( : prev_label) , param , update , url)
links . push page_link_remote_or_span(entries . next_page , ' disabled ' , options . delete( : next_label) , param , update , url)
# change end
content_tag : div , links . join (options . delete( : separator)) , options
end
end
protected
def page_link_remote_or_span(page , span_class , text , param , update , url)
unless page
content_tag : span , text , : class => span_class
else
link_to_remote text , : update => update , : url => " #{url}?#{param.to_sym}=#{page} " , : method =>: get
end
end
在view中的使用如下所示:
文/陈刚 (www.chengang.com.cn)
但一直搜不到它支持ajax分面的方法 ,于是我参考它分页方法的源代码(位于:vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb),稍微改写,变成了一个支持ajax的分页方法。以下代码复制到application_helper里即可。
# -----------------------------------------
# will_paginate插件的ajax分页
# -----------------------------------------
@@pagination_options = { : class => ' pagination ' ,
: prev_label => ' 上一页 ' ,
: next_label => ' 下一页 ' ,
: inner_window => 4 , # links around the current page
: outer_window => 1 , # links around beginning and end
: separator => ' ' , # single space is friendly to spiders and non-graphic browsers
: param_name => : page ,
# add by chengang
: update => nil , # ajax所要更新的html元素的id
: url_suffix => '' # url的后缀,主要是为了补全REST所需要的url
# add end
}
mattr_reader : pagination_options
def will_paginate_remote(entries = @entries , options = {})
total_pages = entries . page_count
if total_pages > 1
options = options . symbolize_keys . reverse_merge(pagination_options)
page , param = entries . current_page , options . delete( : param_name)
inner_window , outer_window = options . delete( : inner_window) . to_i , options . delete( : outer_window) . to_i
# add by chengang
update = options . delete( : update)
suffix = options . delete( : url_suffix)
url = request . env[ ' PATH_INFO ' ]
url += suffix if suffix
# add end
min = page - inner_window
max = page + inner_window
if max > total_pages then min -= max - total_pages
elsif min < 1 then max += 1 - min
end
current = min .. max
beginning = 1 .. ( 1 + outer_window)
tail = (total_pages - outer_window) .. total_pages
visible = [beginning , current , tail] . map( &: to_a) . flatten . sort . uniq
links , prev = [] , 0
visible . each do | n |
next if n < 1
break if n > total_pages
unless n - prev > 1
prev = n
# change by chengang
text = (n == page ? n : " [#{n}] " )
links << page_link_remote_or_span((n != page ? n : nil) , ' current ' , text , param , update , url)
else
prev = n - 1
links << ' '
redo
end
end
# change by chengang
links . unshift page_link_remote_or_span(entries . previous_page , ' disabled ' , options . delete( : prev_label) , param , update , url)
links . push page_link_remote_or_span(entries . next_page , ' disabled ' , options . delete( : next_label) , param , update , url)
# change end
content_tag : div , links . join (options . delete( : separator)) , options
end
end
protected
def page_link_remote_or_span(page , span_class , text , param , update , url)
unless page
content_tag : span , text , : class => span_class
else
link_to_remote text , : update => update , : url => " #{url}?#{param.to_sym}=#{page} " , : method =>: get
end
end
在view中的使用如下所示:
<%=
will_paginate_remote @topics
,
:
update
=>
'
topicList
'
,
:
url_suffix
=>
url_suffix
%>