magic_grid 0.12.4 → 0.12.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,128 +1,131 @@
1
1
  require 'magic_grid/definition'
2
+ require 'magic_grid/order'
2
3
 
3
4
  module MagicGrid
4
5
  class HtmlGrid
6
+ attr_reader :view, :grid
7
+ private :view, :grid
5
8
 
6
9
  def initialize(grid_definition, view, controller = nil)
7
10
  @grid = grid_definition
11
+ @spinner_drawn = false
8
12
  @view ||= view
9
- if controller
10
- @current_url = controller.request.fullpath
11
- else
12
- @current_url = nil
13
- end
13
+ @current_url = controller && controller.request.fullpath
14
14
  end
15
15
 
16
16
  def render(&row_renderer)
17
- @spinner_drawn = false
18
- grid_data = {
19
- :searcher => @grid.searcher,
20
- :current => @current_url,
21
- :live_search => @grid.options[:live_search],
22
- :listeners => @grid.options[:listeners],
23
- :remote => @grid.options[:remote],
24
- :default_ajax_handler => @grid.options[:default_ajax_handler],
25
- :params => @grid.base_params,
26
- }
17
+ @row_renderer = row_renderer || method(:grid_row)
27
18
  table_options = {
28
- :class => (['magic_grid'] << @grid.options[:class]).join(' '),
29
- :id => @grid.magic_id,
30
- :data => grid_data.select {|_,v| v }
19
+ :class => "magic_grid #{grid.options[:class]}",
20
+ :id => grid.magic_id,
21
+ :data => {
22
+ :searcher => grid.searcher,
23
+ :current => @current_url,
24
+ :live_search => grid.options[:live_search],
25
+ :listeners => grid.options[:listeners],
26
+ :remote => grid.options[:remote],
27
+ :default_ajax_handler => grid.options[:default_ajax_handler],
28
+ :params => grid.base_params,
29
+ }.reject {|_,v| v.nil? }
31
30
  }
32
- @view.content_tag('table', table_options) do
33
- thead + tbody(&row_renderer) + tfoot
34
- end
35
- end
36
-
37
- def thead
38
- @view.content_tag('thead', :data => {:params => @grid.base_params}) do
39
- magic_grid_head
40
- end
41
- end
42
-
43
- def tbody(&row_renderer)
44
- @view.content_tag('tbody', :class => "ui-widget-content") do
45
- magic_rows &row_renderer
46
- end
31
+ table(table_options)
47
32
  end
48
33
 
49
- def tfoot
50
- @view.content_tag('tfoot') do
51
- magic_grid_foot
34
+ def table(options)
35
+ view.content_tag('table', options) do
36
+ view.content_tag('thead',
37
+ :data => {:params => grid.base_params},
38
+ &method(:magic_grid_head)) <<
39
+ view.content_tag('tbody',
40
+ :class => "ui-widget-content",
41
+ &method(:magic_rows)) <<
42
+ view.content_tag('tfoot',
43
+ &method(:magic_grid_foot))
52
44
  end
53
45
  end
54
46
 
55
- def spinner_generator
47
+ def render_spinner
56
48
  unless @spinner_drawn
57
49
  @spinner_drawn = true
58
- @view.tag('span',
59
- :id => (@grid.magic_id.to_s + "_spinner"),
50
+ view.tag('span',
51
+ :id => (grid.magic_id.to_s + "_spinner"),
60
52
  :class => "magic_grid_spinner")
61
53
  end
62
54
  end
63
55
 
64
56
  def magic_grid_head
65
- spinner = self.method(:spinner_generator)
66
57
  thead = []
67
- if @grid.needs_searcher?
68
- thead << searcher_block(&spinner)
58
+ if grid.has_title?
59
+ thead << render_title(grid.title)
69
60
  end
70
- if @grid.options[:per_page] and @grid.options[:top_pager]
71
- thead << magic_pager_block(&spinner)
61
+ if grid.needs_searcher?
62
+ thead << searcher_block
72
63
  end
73
- if thead.empty? and not @grid.options[:collapse_emtpy_header]
74
- thead << filler_block(&spinner)
64
+ if grid.options[:per_page] and grid.options[:top_pager]
65
+ thead << magic_pager_block(true)
66
+ end
67
+ if thead.empty? and not grid.options[:collapse_emtpy_header]
68
+ thead << filler_block(&method(:render_spinner))
75
69
  end
76
70
  thead << magic_column_headers
77
71
  thead.join.html_safe
78
72
  end
79
73
 
74
+ def render_title(title)
75
+ view.content_tag 'tr' do
76
+ view.content_tag('th', title,
77
+ :class => 'full-width ui-widget-header',
78
+ :colspan => grid.columns.count)
79
+ end
80
+ end
81
+
80
82
  def magic_grid_foot
81
- if @grid.options[:per_page] and @grid.options[:bottom_pager]
83
+ if grid.options[:per_page] and grid.options[:bottom_pager]
82
84
  magic_pager_block
83
- elsif not @grid.options[:collapse_emtpy_footer]
85
+ elsif not grid.options[:collapse_emtpy_footer]
84
86
  filler_block
85
87
  end
86
88
  end
87
89
 
88
- def filler_block(content = nil, &block)
89
- @view.content_tag 'tr' do
90
- @view.content_tag('td', content,
90
+ def filler_block(&block)
91
+ view.content_tag 'tr' do
92
+ view.content_tag('td', nil,
91
93
  :class => 'full-width ui-widget-header',
92
- :colspan => @grid.columns.count,
94
+ :colspan => grid.columns.count,
93
95
  &block)
94
96
  end
95
97
  end
96
98
 
97
99
  def magic_column_headers
98
- @view.content_tag 'tr' do
99
- @grid.columns.reduce(''.html_safe) do |acc, col|
100
+ view.content_tag 'tr' do
101
+ grid.columns.reduce(''.html_safe) do |acc, col|
100
102
  classes = ['ui-state-default'] << col.html_classes
101
103
  acc <<
102
104
  if col.sortable?
103
105
  sortable_header(col)
104
106
  else
105
- @view.content_tag 'th', col.label.html_safe, :class => classes.join(' ')
107
+ view.content_tag 'th', col.label.html_safe, :class => classes.join(' ')
106
108
  end
107
109
  end
108
110
  end
109
111
  end
110
112
 
111
- def magic_rows(&row_renderer)
112
- rows = @grid.collection.map { |row| grid_row(row, &row_renderer) }
113
+ def magic_rows
114
+ rows = grid.collection.map(&@row_renderer)
113
115
  if rows.empty?
114
- rows << render_empty_collection(@grid.options[:if_empty])
116
+ render_empty_collection(grid.options[:if_empty]).html_safe
117
+ else
118
+ rows.join.html_safe
115
119
  end
116
- rows.join.html_safe
117
120
  end
118
121
 
119
122
  def render_empty_collection(fallback)
120
123
  if fallback
121
- @view.content_tag 'tr' do
122
- @view.content_tag('td', :colspan => @grid.columns.count,
124
+ view.content_tag 'tr' do
125
+ view.content_tag('td', :colspan => grid.columns.count,
123
126
  :class => 'if-empty') do
124
127
  if fallback.respond_to? :call
125
- fallback.call(@grid).to_s
128
+ fallback.call(grid).to_s
126
129
  else
127
130
  fallback
128
131
  end
@@ -131,18 +134,14 @@ module MagicGrid
131
134
  end
132
135
  end
133
136
 
134
- def grid_row(record, &row_renderer)
135
- if row_renderer
136
- @view.capture(record, &row_renderer)
137
- else
138
- @view.content_tag 'tr', :class => @view.cycle('odd', 'even') do
139
- @grid.columns.map { |c| grid_cell(c, record) }.join.html_safe
140
- end
137
+ def grid_row(record)
138
+ view.content_tag 'tr', :class => view.cycle('odd', 'even') do
139
+ grid.columns.map { |c| grid_cell(c, record) }.join.html_safe
141
140
  end
142
141
  end
143
142
 
144
143
  def grid_cell(column, record)
145
- @view.content_tag('td', :class => column.html_classes) do
144
+ view.content_tag('td', :class => column.html_classes) do
146
145
  method = column.reader
147
146
  if method.respond_to? :call
148
147
  method.call(record).to_s
@@ -154,114 +153,86 @@ module MagicGrid
154
153
  end
155
154
  end
156
155
 
157
- def unordered
158
- -1
159
- end
160
-
161
- def reverse_order(order)
162
- order.to_i == 0 ? 1 : 0
163
- end
164
-
165
- def order_icon(order = -1)
166
- @view.content_tag 'span', '', :class => "ui-icon #{order_icon_class(order)}"
156
+ def order_icon(order = Order::Unordered)
157
+ view.content_tag 'span', '', :class => "ui-icon #{order.icon_class}"
167
158
  end
168
159
 
169
- def order_icon_class(order = -1)
170
- case order.to_i
171
- when 0 then 'ui-icon-triangle-1-n'
172
- when 1 then 'ui-icon-triangle-1-s'
173
- else 'ui-icon-carat-2-n-s'
174
- end
175
- end
176
-
177
- def order_class(order = -1)
178
- case order.to_i
179
- when 0 then 'sort-asc'
180
- when 1 then 'sort-desc'
181
- else 'sort-none'
160
+ def column_link_params(col)
161
+ id = col.id
162
+ my_params = grid.base_params.merge(grid.param_key(:col) => id)
163
+ params = HashWithIndifferentAccess.new(my_params)
164
+ if id.to_s == grid.current_sort_col.to_s
165
+ params[grid.param_key(:order)] = grid.current_order.reverse.to_param
166
+ else
167
+ params.delete(grid.param_key(:order))
182
168
  end
169
+ params
183
170
  end
184
171
 
185
172
  def sortable_header(col)
186
173
  id = col.id
187
174
  label = col.label || id.titleize
188
- default_sort_order = @grid.order(@grid.default_order)
189
- my_params = @grid.base_params.merge({
190
- @grid.param_key(:col) => id,
191
- })
192
- column_link_params = HashWithIndifferentAccess.new(my_params)
193
- order = unordered
194
- classes = ['sorter ui-state-default'] << col.html_classes
195
- if id.to_s == @grid.current_sort_col.to_s
196
- order = @grid.current_order
197
- classes << "sort-current" << order_class(order)
198
- column_link_params[@grid.param_key(:order)] = reverse_order(order)
199
- else
200
- column_link_params.delete @grid.param_key(:order)
201
- end
202
- if column_link_params[@grid.param_key(:order)].to_i == default_sort_order.to_i
203
- column_link_params.delete(@grid.param_key(:order))
204
- end
205
- @view.content_tag 'th', :class => classes.join(' ') do
206
- @view.link_to column_link_params, :remote => @grid.options[:remote] do
207
- label.html_safe << order_icon(order)
175
+ params = column_link_params(col)
176
+ classes = %w{sorter ui-state-default} << col.html_classes
177
+ classes << 'sort-current' if col.order.sorted?
178
+ view.content_tag 'th', :class => classes.join(' ') do
179
+ view.link_to params, :remote => grid.options[:remote] do
180
+ label.html_safe << order_icon(col.order)
208
181
  end
209
182
  end
210
183
  end
211
184
 
212
- def searcher_block(&spinner)
213
- @view.content_tag('tr') do
214
- @view.content_tag('td', :class => 'searcher full-width ui-widget-header',
215
- :colspan => @grid.columns.count) do
216
- searcher_input(&spinner)
185
+ def searcher_block
186
+ view.content_tag('tr') do
187
+ view.content_tag('td', :class => 'searcher full-width ui-widget-header',
188
+ :colspan => grid.columns.count) do
189
+ searcher_input
217
190
  end
218
191
  end
219
192
  end
220
193
 
221
- def searcher_input(&spinner)
194
+ def searcher_input
222
195
  searcher_data = {
223
- :min_length => @grid.options[:min_search_length],
224
- :current => @grid.current_search || "",
196
+ :min_length => grid.options[:min_search_length],
197
+ :current => grid.current_search,
225
198
  }
226
- searcher = @view.label_tag(@grid.searcher.to_sym,
227
- @grid.options[:searcher_label])
228
- searcher << @view.search_field_tag(@grid.searcher.to_sym,
229
- @grid.param(:q),
230
- :placeholder => @grid.options[:searcher_tooltip],
231
- :size => @grid.options[:searcher_size],
232
- :data => searcher_data,
233
- :form => "a form that doesn't exist")
234
- if @grid.options[:search_button]
235
- searcher << @view.button_tag(@grid.options[:searcher_button],
236
- :class => 'magic-grid-search-button')
199
+ searcher = view.label_tag(grid.searcher.to_sym,
200
+ grid.options[:searcher_label])
201
+ searcher << view.search_field_tag(grid.searcher.to_sym,
202
+ grid.param(:q),
203
+ :placeholder => grid.options[:searcher_tooltip],
204
+ :size => grid.options[:searcher_size],
205
+ :data => searcher_data,
206
+ :form => "a form that doesn't exist")
207
+ if grid.options[:search_button]
208
+ searcher << view.button_tag(grid.options[:searcher_button],
209
+ :class => 'magic-grid-search-button')
237
210
  end
238
- searcher << yield if block_given?
239
- searcher
211
+ searcher << render_spinner
240
212
  end
241
213
 
242
214
  def magic_pager(collection, opts={})
243
- if @view.respond_to? :will_paginate
215
+ if view.respond_to? :will_paginate
244
216
  # WillPaginate
245
- @view.will_paginate collection.collection, opts
246
- elsif @view.respond_to? :paginate
217
+ view.will_paginate collection.collection, opts
218
+ elsif view.respond_to? :paginate
247
219
  #Kaminari, or something else..
248
- @view.paginate collection.collection, opts
220
+ view.paginate collection.collection, opts
249
221
  else
250
222
  ("<!-- page #{collection.current_page} of #{collection.total_pages} -->" +
251
223
  '<!-- INSTALL WillPaginate or Kaminari for a pager! -->').html_safe
252
224
  end
253
225
  end
254
226
 
255
- def magic_pager_block(&spinner)
256
- @view.content_tag('tr') do
257
- @view.content_tag('td', :class => 'full-width ui-widget-header magic-pager',
258
- :colspan => @grid.columns.count) do
259
- pager = magic_pager(@grid.magic_collection,
260
- :param_name => @grid.param_key(:page),
261
- :params => @grid.base_params
262
- )
227
+ def magic_pager_block(spinner = false)
228
+ view.content_tag('tr') do
229
+ view.content_tag('td', :class => 'full-width ui-widget-header magic-pager',
230
+ :colspan => grid.columns.count) do
231
+ pager = magic_pager(grid.magic_collection,
232
+ :param_name => grid.param_key(:page),
233
+ :params => grid.base_params)
263
234
  if spinner
264
- pager << @view.capture(&spinner)
235
+ pager << render_spinner
265
236
  end
266
237
  pager
267
238
  end
@@ -0,0 +1,69 @@
1
+ module MagicGrid
2
+ module Order
3
+ class Unordered
4
+ def self.css_class
5
+ 'sort-none'
6
+ end
7
+ def self.icon_class
8
+ 'ui-icon-carat-2-n-s'
9
+ end
10
+ def self.to_sql
11
+ 'ASC'
12
+ end
13
+ def self.to_param
14
+ 0
15
+ end
16
+ def self.sorted?
17
+ false
18
+ end
19
+ def self.reverse
20
+ Descending
21
+ end
22
+ end
23
+ class Unsortable < Unordered; end
24
+ class Ascending < Unordered
25
+ def self.css_class
26
+ 'sort-asc'
27
+ end
28
+ def self.icon_class
29
+ 'ui-icon-triangle-1-n'
30
+ end
31
+ def self.sorted?
32
+ true
33
+ end
34
+ def self.reverse
35
+ Descending
36
+ end
37
+ end
38
+ class Descending < Unordered
39
+ def self.css_class
40
+ 'sort-desc'
41
+ end
42
+ def self.icon_class
43
+ 'ui-icon-triangle-1-s'
44
+ end
45
+ def self.to_sql
46
+ 'DESC'
47
+ end
48
+ def self.to_param
49
+ 1
50
+ end
51
+ def self.sorted?
52
+ true
53
+ end
54
+ def self.reverse
55
+ Ascending
56
+ end
57
+ end
58
+ def self.from_param(something)
59
+ case something
60
+ when 1, "1", :desc, :DESC, "desc", "DESC", Descending
61
+ Descending
62
+ #when 0, "0", :asc, :ASC, "asc", "ASC", Ascending
63
+ # Ascending
64
+ else
65
+ Ascending
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,3 +1,3 @@
1
1
  module MagicGrid
2
- VERSION = "0.12.4"
2
+ VERSION = "0.12.5"
3
3
  end