Class: Nitro::Pager

Inherits:
Object
  • Object
show all
Defined in:
lib/nitro/helper/pager.rb

Overview

Displays a collection of entitities in multiple pages.

Design

This pager is carefully designed for scaleability. It stores only the items for one page. The key parameter is needed, multiple pagers can coexist in a single page. The pager leverages the SQL LIMIT option to optimize database interaction.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request, per_page, total_count, key = Pager.key) ⇒ Pager

Returns a new instance of Pager.



42
43
44
45
46
47
48
49
50
# File 'lib/nitro/helper/pager.rb', line 42

def initialize(request, per_page, total_count, key = Pager.key)
  raise 'per_page should be > 0' unless per_page > 0

  @request, @key = request, key
  @page = request.query.fetch(key, 1).to_i
  @per_page = per_page
  set_count(total_count)
  @start_idx = (@page - 1) * per_page    
end

Instance Attribute Details

#pageObject

The current page.



28
29
30
# File 'lib/nitro/helper/pager.rb', line 28

def page
  @page
end

#page_countObject

The total number of pages.



36
37
38
# File 'lib/nitro/helper/pager.rb', line 36

def page_count
  @page_count
end

#per_pageObject

Items per page.



32
33
34
# File 'lib/nitro/helper/pager.rb', line 32

def per_page
  @per_page
end

#total_countObject

Total count of items.



40
41
42
# File 'lib/nitro/helper/pager.rb', line 40

def total_count
  @total_count
end

Instance Method Details

#each(&block) ⇒ Object

Iterator



107
108
109
# File 'lib/nitro/helper/pager.rb', line 107

def each(&block)
  @page_items.each(&block)
end

#each_with_indexObject

Iterator Returns 1-based index.



114
115
116
117
118
119
120
# File 'lib/nitro/helper/pager.rb', line 114

def each_with_index
  idx = @start_idx
  for item in @page_items
    yield(idx + 1, item)
    idx += 1
  end
end

#empty?Boolean

Is the pager empty, ie has one page only?

Returns:

  • (Boolean)


124
125
126
# File 'lib/nitro/helper/pager.rb', line 124

def empty?
  return @page_count < 1
end

#first_pageObject

Return the first page index.



59
60
61
# File 'lib/nitro/helper/pager.rb', line 59

def first_page
  return 1
end

#first_page?Boolean

Is the first page displayed?

Returns:

  • (Boolean)


65
66
67
# File 'lib/nitro/helper/pager.rb', line 65

def first_page?
  @page == 1
end

#last_pageObject

Return the last page index.



71
72
73
# File 'lib/nitro/helper/pager.rb', line 71

def last_page 
  return @page_count
end

#last_page?Boolean

Is the last page displayed?

Returns:

  • (Boolean)


77
78
79
# File 'lib/nitro/helper/pager.rb', line 77

def last_page?
  @page == @page_count
end

#limitObject

To be used with Og queries.



158
159
160
161
162
163
164
# File 'lib/nitro/helper/pager.rb', line 158

def limit
  if @start_idx > 0
    { :limit => @per_page, :offset => @start_idx }
  else
    { :limit => @per_page }
  end
end

Override if needed.



145
146
147
148
149
150
151
152
153
154
# File 'lib/nitro/helper/pager.rb', line 145

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

Override this method in your application if needed. – TODO: better markup. ++



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/nitro/helper/pager.rb', line 187

def navigation
  nav = ""
  
  unless first_page?
    nav << %{
      <div class="first"><a href="#{first_page_href}">First</a></div>
      <div class="previous"><a href="#{previous_page_href}">Previous</a></div>
    }
  end
  
  unless last_page?
    nav << %{
      <div class="last"><a href="#{last_page_href}">Last</a></div>
      <div class="next"><a href="#{next_page_href}">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

Returns:

  • (Boolean)


224
225
226
# File 'lib/nitro/helper/pager.rb', line 224

def navigation_needed?
  @page_count > 1
end

#next_pageObject

Return the index of the next page.



89
90
91
# File 'lib/nitro/helper/pager.rb', line 89

def next_page
  return [@page + 1, @page_count].min()
end

#offsetObject



166
167
168
# File 'lib/nitro/helper/pager.rb', line 166

def offset 
  @start_idx
end

#page_rangeObject

Returns the range of the current page.



136
137
138
139
140
141
# File 'lib/nitro/helper/pager.rb', line 136

def page_range
  s = @idx
  e = [@idx + @items_per_page - 1, all_total_count].min
  
  return [s, e]
end

#previous_pageObject

Return the index of the previous page.



83
84
85
# File 'lib/nitro/helper/pager.rb', line 83

def previous_page
  return [@page - 1, 1].max()
end

#set_count(total_count) ⇒ Object



52
53
54
55
# File 'lib/nitro/helper/pager.rb', line 52

def set_count(total_count)
  @total_count = total_count
  @page_count = (@total_count.to_f / @per_page).ceil
end

#sizeObject

The items count.



130
131
132
# File 'lib/nitro/helper/pager.rb', line 130

def size
  return @total_count
end

#to_sqlObject

Create an appropriate SQL limit clause. Returns postgres/mysql compatible limit.



173
174
175
176
177
178
179
180
# File 'lib/nitro/helper/pager.rb', line 173

def to_sql
  if @start_idx > 0
    return "LIMIT #{@per_page} OFFSET #{@start_idx}"
  else
    # gmosx: perhaps this is optimized ? naaaaaah...
    return "LIMIT #{@per_page}"
  end
end