Flickrのようなページ切り替えメニューをRubyやJavaScriptで生成する
デザイン的にカッコイイページ送りを組み込みたいと思って、以下のページを参考にしたのだけど、プログラムで利用したいので、RubyやJavaScriptで汎用的に使えるように作ってみました。
DiggとかFlickrのようなページ切り替えメニュー(Pagination)を実現するCSS | IDEA*IDEA
Ruby
PaginationはRails2.0では無くなるらしいが、まだ使われていると思うので有用じゃないかな。
@foo_pages, @foos = paginate(...)
なんかで取得できる@foo_pagesを引数に渡します。
def paginate_flickr(pages) i = 0 result = '<ul id="pagination-flickr">' if (pages.current.previous) result << '<li class="previous">' result << link_to('«Previous', { :page => pages.current.previous }) else result << '<li class="previous-off">' result << '«Previous' end result << '</li>' pages.last.to_i.times { i = i+1 if (i == pages.current.number) result << '<li class="active">' result << i.to_s else result << '<li>'; result << link_to(i, :page => i) end result << '</li>' } if (pages.current.next) result << '<li class="next">' result << link_to('Next »', { :page => pages.current.next }) else result << '<li class="next-off">' result << 'Next »' end result << '</li>' result << '</ul>' return result end
JavaScript
不要な箇所が入っちゃってるかもだけど、基本は実データを配列やオブジェクトとしてdataで渡します。
/** @param data 実データの配列 @param items 1ページに表示する項目数 @param pages 前後に表示させるページネーション数 @param now_page 現在のページ番号 */ function make_pagination(data, items, pages, now_page) { //最後のページ var last_page = parseInt(data.length / items); if ((data.length % items) != 0) { last_page++; } var ulObj = document.getElementById('pagination-flickr'); //前へ var prevLiObj = document.createElement("li"); if (now_page == 1) { prevLiObj.className = 'previous-off'; prevLiObj.innerHTML = 'Previous'; } else { prevLiObj.className = 'previous'; var aObj = document.createElement("a"); var prev_page = now_page - 1; aObj.href = "?page=" + prev_page; aObj.innerHTML = '«Previous'; prevLiObj.appendChild(aObj); } ulObj.appendChild(prevLiObj); //次へ nextLiObj = document.createElement("li"); if (now_page < last_page) { nextLiObj.className = 'next'; var aObj = document.createElement("a"); var next_page = now_page + 1; aObj.href = "?page=" + next_page; aObj.innerHTML = 'Next »'; nextLiObj.appendChild(aObj); } else { nextLiObj.className = 'next-off'; nextLiObj.innerHTML = 'Next »'; } for (var i=1; i < last_page + 1; i++) { if (now_page - pages > i && last_page - ((pages * 2)) > i ) { continue; } if (now_page + pages < i && (pages * 2) +1 < i) { continue; } var liObj = document.createElement("li"); var aObj = document.createElement("a"); aObj.href = "?page=" + i; aObj.innerHTML = i; if (now_page == i) { aObj.className = 'active'; } liObj.appendChild(aObj); ulObj.appendChild(liObj); } ulObj.appendChild(nextLiObj); }
ここではa hrefとしてリンクしてるけど、ページ遷移でなく、DHTML/Ajax的に処理したいなら、
aObj.href = "javascript:void(0);"; addEventListener(aObj, 'click', change_page);
などとして、イベントを付加してあげればOKです。なお、イベントの追加はブラウザによって違うので、
function addEventListener(target, type, func) { if(target.attachEvent) { target.attachEvent("on" + type, func); } else if(target.addEventListener) { target.addEventListener(type, func, false); } else { target["on" + type] = func; } }
でラッピングしてます。