Class: N::UI::Pager
Overview
Displays a collection of entitities in multiple pages.
Design
The new version is carefully designed for scaleability. It stores only the items for one page. The name parameter is needed, multiple pagers can coexist in a single page. Unlike older pagers this pager leverages the SQL LIMIT option to optimize database interaction.
Example
@pager.set(N::BlogEntry.count)
default navigation (customize with css): <div class=“pager”>#@[email protected]</div>
custom navigation:
<table cellspacing=“0” width=“100%” border=“1”> <tr> <td width=“64”><x:pager-prev>Previous</x:pager-prev></td> <td width=“100%”></td> <td width=“64”><x:pager-next>Next</x:pager-next></td> </tr> </table> – INVESTIGATE: mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS(); ++
Instance Attribute Summary collapse
-
#idx ⇒ Object
Returns the value of attribute idx.
-
#name ⇒ Object
Returns the value of attribute name.
-
#page ⇒ Object
Returns the value of attribute page.
-
#page_count ⇒ Object
Returns the value of attribute page_count.
-
#page_items ⇒ Object
Page items.
-
#request ⇒ Object
Read needed variables from the request.
-
#total_count ⇒ Object
Total count of items.
Instance Method Summary collapse
-
#each(&block) ⇒ Object
Iterator.
-
#each_with_index ⇒ Object
Iterator Returns 1-based index.
- #empty? ⇒ Boolean
- #first_page ⇒ Object
-
#initialize(name, request, items_per_page = 10, items = nil) ⇒ Pager
constructor
A new instance of Pager.
- #last_page ⇒ Object
-
#nav_range ⇒ Object
Override if needed.
-
#navigation ⇒ Object
Override this method in your application if needed.
- #next_page ⇒ Object
-
#offset ⇒ Object
Returns the current offset.
-
#page_range ⇒ Object
Returns the range of the current page.
- #previous_page ⇒ Object
- #set(total_count) ⇒ Object
- #size ⇒ Object
-
#sql_limit ⇒ Object
Create an appropriate SQL limit clause.
-
#target_uri(page) ⇒ Object
Generate the target URI.
Constructor Details
#initialize(name, request, items_per_page = 10, items = nil) ⇒ Pager
Returns a new instance of Pager.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/nitro/ui/pager.rb', line 56 def initialize(name, request, items_per_page = 10, items = nil) raise "items_per_page should be > 0" unless items_per_page > 0 @request, @name = request, name @page = request.query.fetch("__pg#{@name}", 1).to_i @items_per_page = items_per_page @start_idx = (@page - 1) * items_per_page if items set(items.size()) # gmosx, FIXME: not exactly what i want! items.slice!(@start_idx, @items_per_page) end end |
Instance Attribute Details
#idx ⇒ Object
Returns the value of attribute idx.
45 46 47 |
# File 'lib/nitro/ui/pager.rb', line 45 def idx @idx end |
#name ⇒ Object
Returns the value of attribute name.
45 46 47 |
# File 'lib/nitro/ui/pager.rb', line 45 def name @name end |
#page ⇒ Object
Returns the value of attribute page.
45 46 47 |
# File 'lib/nitro/ui/pager.rb', line 45 def page @page end |
#page_count ⇒ Object
Returns the value of attribute page_count.
45 46 47 |
# File 'lib/nitro/ui/pager.rb', line 45 def page_count @page_count end |
#page_items ⇒ Object
Page items
51 52 53 |
# File 'lib/nitro/ui/pager.rb', line 51 def page_items @page_items end |
#request ⇒ Object
Read needed variables from the request.
54 55 56 |
# File 'lib/nitro/ui/pager.rb', line 54 def request @request end |
#total_count ⇒ Object
Total count of items
48 49 50 |
# File 'lib/nitro/ui/pager.rb', line 48 def total_count @total_count end |
Instance Method Details
#each(&block) ⇒ Object
Iterator
94 95 96 |
# File 'lib/nitro/ui/pager.rb', line 94 def each(&block) @page_items.each(&block) end |
#each_with_index ⇒ Object
Iterator Returns 1-based index.
101 102 103 104 105 106 107 |
# File 'lib/nitro/ui/pager.rb', line 101 def each_with_index idx = @start_idx for item in @page_items yield(idx + 1, item) idx += 1 end end |
#empty? ⇒ Boolean
109 110 111 |
# File 'lib/nitro/ui/pager.rb', line 109 def empty? return @items.empty? end |
#first_page ⇒ Object
76 77 78 |
# File 'lib/nitro/ui/pager.rb', line 76 def first_page return 1 end |
#last_page ⇒ Object
80 81 82 |
# File 'lib/nitro/ui/pager.rb', line 80 def last_page return @page_count end |
#nav_range ⇒ Object
Override if needed.
128 129 130 131 132 133 134 135 136 137 |
# File 'lib/nitro/ui/pager.rb', line 128 def nav_range # effective range = 10 pages. s = [@page - 5, 1].max() e = [@page + 9, @page_count].min() d = 9 - (e - s) e += d if d < 0 return (s..e) end |
#navigation ⇒ Object
Override this method in your application if needed. TODO: better markup.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/nitro/ui/pager.rb', line 143 def nav = "" unless @page == first_page() nav << %{ <div class="first"><a href="#{target_uri(first_page())}">First</a></div> <div class="previous"><a href="#{target_uri(previous_page())}">Previous</a></div> } end unless @page == last_page() nav << %{ <div class="last"><a href="#{target_uri(last_page())}">Last</a></div> <div class="next"><a href="#{target_uri(next_page())}">Next</a></div> } end nav << %{<ul>} for i in nav_range() if i == @page nav << %{ <li class="active">#{i}</li> } else nav << %{ <li><a href="#{target_uri(i)}">#{i}</a></li> } end end nav << %{</ul>} return nav end |
#next_page ⇒ Object
88 89 90 |
# File 'lib/nitro/ui/pager.rb', line 88 def next_page return [@page + 1, @page_count].min() end |
#offset ⇒ Object
Returns the current offset. The offset is zero-based.
193 194 195 |
# File 'lib/nitro/ui/pager.rb', line 193 def offset (@page-1) * @items_per_page end |
#page_range ⇒ Object
Returns the range of the current page.
119 120 121 122 123 124 |
# File 'lib/nitro/ui/pager.rb', line 119 def page_range s = @idx e = [@idx + @items_per_page - 1, all_total_count].min return [s, e] end |
#previous_page ⇒ Object
84 85 86 |
# File 'lib/nitro/ui/pager.rb', line 84 def previous_page return [@page - 1, 1].max() end |
#set(total_count) ⇒ Object
71 72 73 74 |
# File 'lib/nitro/ui/pager.rb', line 71 def set(total_count) @total_count = total_count @page_count = (@total_count.to_f() / @items_per_page).ceil() end |
#size ⇒ Object
113 114 115 |
# File 'lib/nitro/ui/pager.rb', line 113 def size return @items.size() end |
#sql_limit ⇒ Object
Create an appropriate SQL limit clause. Returns postgres/mysql compatible limit.
182 183 184 185 186 187 188 189 |
# File 'lib/nitro/ui/pager.rb', line 182 def sql_limit if @start_idx > 0 return "LIMIT #{@items_per_page} OFFSET #{@start_idx}" else # gmosx: perhaps this is optimized ? naaaaaah... return "LIMIT #{@items_per_page}" end end |
#target_uri(page) ⇒ Object
Generate the target URI.
199 200 201 202 |
# File 'lib/nitro/ui/pager.rb', line 199 def target_uri(page) params = {"__pg#{@name}" => page} return N::UriUtils.update_query_string(@request.uri.to_s, params) end |