Pager for lots o' data


/ Published in: Ruby
Save to your folder(s)

This function (intended to be an application or view helper) creates a pager bar useful for navigating many pages. It shows the first, last, current, nearby, and halfway-to-end pages. It looks like this (where the current page is 11):

< 1 ... 5 ... 10 11 12 ... 14 15 >

The pagerBar function takes two parameters: a RoR paginator, and an anchor that will be attached to all the links.


Copy this code and paste it in your HTML
  1. class ActionController::AbstractRequest
  2. def get_post_params
  3. self.parameters.reject {|k,v| k == 'controller' || k == 'action'}
  4. end
  5. end
  6.  
  7. def pagerBar(paginator, anchor)
  8. page = paginator.current_page;
  9. pageParam = 'page';
  10. firstPage = 1;
  11. lastPage = paginator.page_count;
  12. prevStr = '←';
  13. nextStr = '→';
  14. elideStr = '… '; # Include trailing space.
  15. pageSpan = 3; # How many pages to the left and right of current.
  16.  
  17. # The central group of pages.
  18. window = page.window(pageSpan);
  19. windowFirst = window.first.number;
  20. windowLast = window.last.number;
  21.  
  22. # These define the halfway pages.
  23. prevHalfway = (windowFirst / 2.0).floor;
  24. prevHalfway = 2 if prevHalfway == 1;
  25. nextHalfway = ((windowLast + lastPage) / 2.0).ceil;
  26. nextHalfway = lastPage - 1 if nextHalfway == lastPage;
  27.  
  28. # Need to show first/last pages separate from range?
  29. showFirst = (windowFirst > 1);
  30. showLast = (windowLast < lastPage);
  31.  
  32. # Need to show half-way pages?
  33. showPrevHalfway = (prevHalfway > 1 && prevHalfway < windowFirst);
  34. showNextHalfway = (nextHalfway < lastPage && nextHalfway > windowLast);
  35.  
  36. # Pages missing before/after half-way pages?
  37. elideBeforePrevHalf = (showPrevHalfway && (prevHalfway - firstPage) > 1);
  38. elideAfterPrevHalf = (showPrevHalfway && (windowFirst - prevHalfway) > 1);
  39. elideBeforeNextHalf = (showNextHalfway && (nextHalfway - windowLast) > 1);
  40. elideAfterNextHalf = (showNextHalfway && (lastPage - nextHalfway) > 1);
  41.  
  42. # No half-way pages, but pages missing before/after range?
  43. elideBeforeRange = (!showPrevHalfway && (windowFirst - firstPage) > 1);
  44. elideAfterRange = (!showNextHalfway && (lastPage - windowLast) > 1);
  45.  
  46. # Do prev arrow.
  47. html = link_to_unless(page.first?, prevStr,
  48. request.get_post_params.merge(
  49. { pageParam => page.previous, :anchor => anchor }));
  50. html += ' ';
  51.  
  52. # Do first page.
  53. if (showFirst)
  54. html += link_to(paginator.first_page.number.to_s,
  55. request.get_post_params.merge(
  56. { pageParam => paginator.first_page.number, :anchor => anchor }));
  57. html += ' ';
  58. end
  59.  
  60. # Do prev halfway point.
  61. html += elideStr if elideBeforePrevHalf;
  62. if (showPrevHalfway)
  63. html += link_to(paginator[prevHalfway].number.to_s,
  64. request.get_post_params.merge(
  65. { pageParam => paginator[prevHalfway].number, :anchor => anchor }));
  66. html += ' ';
  67. end
  68. html += elideStr if elideAfterPrevHalf;
  69.  
  70. # Do range.
  71. html += elideStr if elideBeforeRange;
  72. window.pages.each do |windowPage|
  73. html += link_to_unless (page == windowPage, windowPage.number.to_s,
  74. request.get_post_params.merge(
  75. { pageParam => windowPage.number, :anchor => anchor }));
  76. html += ' ';
  77. end
  78. html += elideStr if elideAfterRange;
  79.  
  80. # Do next halfway point.
  81. html += elideStr if elideBeforeNextHalf;
  82. if (showNextHalfway)
  83. html += link_to(paginator[nextHalfway].number.to_s,
  84. request.get_post_params.merge(
  85. { pageParam => paginator[nextHalfway].number, :anchor => anchor }));
  86. html += ' ';
  87. end
  88. html += elideStr if elideAfterNextHalf;
  89.  
  90. # Do last page.
  91. if (showLast)
  92. html += link_to(paginator.last_page.number.to_s,
  93. request.get_post_params.merge(
  94. { pageParam => paginator.last_page.number, :anchor => anchor }));
  95. html += ' ';
  96. end
  97.  
  98. # Do next arrow.
  99. html += link_to_unless(page.last?, nextStr,
  100. request.get_post_params.merge(
  101. { pageParam => page.next, :anchor => anchor }));
  102.  
  103. # Return
  104. html
  105. end

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.