wice_grid 3.2.0 → 3.2.1.pre1

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.
Files changed (35) hide show
  1. data/CHANGELOG +9 -6
  2. data/README.rdoc +29 -0
  3. data/VERSION +1 -1
  4. data/lib/active_record_column_wrapper.rb +105 -0
  5. data/lib/columns/column_action.rb +50 -0
  6. data/lib/columns/column_boolean.rb +43 -0
  7. data/lib/columns/column_custom_dropdown.rb +119 -0
  8. data/lib/columns/column_date.rb +23 -0
  9. data/lib/columns/column_datetime.rb +113 -0
  10. data/lib/columns/column_float.rb +14 -0
  11. data/lib/columns/column_integer.rb +63 -0
  12. data/lib/columns/column_processor_index.rb +19 -0
  13. data/lib/columns/column_range.rb +74 -0
  14. data/lib/columns/column_string.rb +89 -0
  15. data/lib/columns.rb +223 -0
  16. data/lib/generators/wice_grid/add_migration_for_serialized_queries_generator.rb +1 -1
  17. data/lib/generators/wice_grid/templates/create_wice_grid_serialized_queries.rb +2 -2
  18. data/lib/grid_renderer.rb +19 -9
  19. data/lib/helpers/wice_grid_view_helpers.rb +6 -10
  20. data/lib/kaminari_monkey_patching.rb +4 -4
  21. data/lib/wice_grid.rb +15 -245
  22. data/lib/wice_grid_controller.rb +4 -4
  23. data/lib/wice_grid_core_ext.rb +3 -3
  24. data/wice_grid.gemspec +15 -13
  25. metadata +17 -15
  26. data/lib/view_columns/action_view_column.rb +0 -45
  27. data/lib/view_columns/column_processor_index.rb +0 -16
  28. data/lib/view_columns/view_column_boolean.rb +0 -23
  29. data/lib/view_columns/view_column_custom_dropdown.rb +0 -80
  30. data/lib/view_columns/view_column_date.rb +0 -17
  31. data/lib/view_columns/view_column_datetime.rb +0 -85
  32. data/lib/view_columns/view_column_float.rb +0 -7
  33. data/lib/view_columns/view_column_integer.rb +0 -38
  34. data/lib/view_columns/view_column_string.rb +0 -63
  35. data/lib/view_columns.rb +0 -177
@@ -0,0 +1,74 @@
1
+ # encoding: UTF-8
2
+ module Wice
3
+
4
+ module Columns #:nodoc:
5
+
6
+ class ViewColumnRange < ViewColumn #:nodoc:
7
+
8
+ def render_filter_internal(params) #:nodoc:
9
+ @contains_a_text_input = true
10
+
11
+ @query, _, parameter_name, @dom_id = form_parameter_name_id_and_query(:fr => '')
12
+ @query2, _, parameter_name2, @dom_id2 = form_parameter_name_id_and_query(:to => '')
13
+
14
+ opts1 = {:size => 3, :id => @dom_id, :class => 'range-start'}
15
+ opts2 = {:size => 3, :id => @dom_id2, :class => 'range-end'}
16
+
17
+ if auto_reload
18
+ opts1[:class] += ' auto-reload'
19
+ opts2[:class] += ' auto-reload'
20
+ end
21
+
22
+ text_field_tag(parameter_name, params[:fr], opts1) + text_field_tag(parameter_name2, params[:to], opts2)
23
+ end
24
+
25
+ def yield_declaration_of_column_filter #:nodoc:
26
+ {
27
+ :templates => [@query, @query2],
28
+ :ids => [@dom_id, @dom_id2]
29
+ }
30
+ end
31
+
32
+ def has_auto_reloading_input? #:nodoc:
33
+ auto_reload
34
+ end
35
+ end
36
+
37
+
38
+ class ConditionsGeneratorColumnRange < ConditionsGeneratorColumn #:nodoc:
39
+
40
+ def generate_conditions(table_alias, opts) #:nodoc:
41
+ unless opts.kind_of? Hash
42
+ Wice.log "invalid parameters for the grid integer filter - must be a hash"
43
+ return false
44
+ end
45
+ conditions = [[]]
46
+ if opts[:fr]
47
+ if opts[:fr] =~ /\d/
48
+ conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} >= ? "
49
+ conditions << opts[:fr]
50
+ else
51
+ opts.delete(:fr)
52
+ end
53
+ end
54
+
55
+ if opts[:to]
56
+ if opts[:to] =~ /\d/
57
+ conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} <= ? "
58
+ conditions << opts[:to]
59
+ else
60
+ opts.delete(:to)
61
+ end
62
+ end
63
+
64
+ if conditions.size == 1
65
+ return false
66
+ end
67
+
68
+ conditions[0] = conditions[0].join(' and ')
69
+
70
+ conditions
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,89 @@
1
+ # encoding: UTF-8
2
+ module Wice
3
+
4
+ module Columns #:nodoc:
5
+
6
+ class ViewColumnString < ViewColumn #:nodoc:
7
+
8
+ attr_accessor :negation, :auto_reloading_input_with_negation_checkbox
9
+
10
+ def render_filter_internal(params) #:nodoc:
11
+ @contains_a_text_input = true
12
+ css_class = auto_reload ? 'auto-reload' : nil
13
+
14
+ if negation
15
+ self.auto_reloading_input_with_negation_checkbox = true if auto_reload
16
+
17
+ @query, _, parameter_name, @dom_id = form_parameter_name_id_and_query(:v => '')
18
+ @query2, _, parameter_name2, @dom_id2 = form_parameter_name_id_and_query(:n => '')
19
+
20
+ '<div class="text-filter-container">' +
21
+ text_field_tag(parameter_name, params[:v], :size => 8, :id => @dom_id, :class => css_class) +
22
+ if defined?(Wice::Defaults::NEGATION_CHECKBOX_LABEL) && ! Wice::ConfigurationProvider.value_for(:NEGATION_CHECKBOX_LABEL).blank?
23
+ Wice::ConfigurationProvider.value_for(:NEGATION_CHECKBOX_LABEL)
24
+ else
25
+ ''
26
+ end +
27
+ check_box_tag(parameter_name2, '1', (params[:n] == '1'),
28
+ :id => @dom_id2,
29
+ :title => NlMessage['negation_checkbox_title'],
30
+ :class => "negation-checkbox #{css_class}") +
31
+ '</div>'
32
+ else
33
+ @query, _, parameter_name, @dom_id = form_parameter_name_id_and_query('')
34
+ text_field_tag(parameter_name, (params.blank? ? '' : params), :size => 8, :id => @dom_id, :class => css_class)
35
+ end
36
+ end
37
+
38
+
39
+ def yield_declaration_of_column_filter #:nodoc:
40
+ if negation
41
+ {
42
+ :templates => [@query, @query2],
43
+ :ids => [@dom_id, @dom_id2]
44
+ }
45
+ else
46
+ {
47
+ :templates => [@query],
48
+ :ids => [@dom_id]
49
+ }
50
+ end
51
+ end
52
+
53
+
54
+ def has_auto_reloading_input? #:nodoc:
55
+ auto_reload
56
+ end
57
+
58
+ def auto_reloading_input_with_negation_checkbox? #:nodoc:
59
+ self.auto_reloading_input_with_negation_checkbox
60
+ end
61
+
62
+ end
63
+
64
+
65
+ class ConditionsGeneratorColumnString < ConditionsGeneratorColumn #:nodoc:
66
+
67
+ def generate_conditions(table_alias, opts) #:nodoc:
68
+ if opts.kind_of? String
69
+ string_fragment = opts
70
+ negation = ''
71
+ elsif (opts.kind_of? Hash) && opts.has_key?(:v)
72
+ string_fragment = opts[:v]
73
+ negation = opts[:n] == '1' ? 'NOT' : ''
74
+ else
75
+ Wice.log "invalid parameters for the grid string filter - must be a string: #{opts.inspect} or a Hash with keys :v and :n"
76
+ return false
77
+ end
78
+ if string_fragment.empty?
79
+ return false
80
+ end
81
+ [
82
+ " #{negation} #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} #{::Wice.get_string_matching_operators(@column_wrapper.model)} ?",
83
+ '%' + string_fragment + '%'
84
+ ]
85
+ end
86
+
87
+ end
88
+ end
89
+ end
data/lib/columns.rb ADDED
@@ -0,0 +1,223 @@
1
+ # encoding: UTF-8
2
+ module Wice #:nodoc:
3
+
4
+ module Columns #:nodoc:
5
+
6
+ class << self #:nodoc:
7
+ def load_column_processors #:nodoc:
8
+
9
+ require_columns
10
+
11
+ loaded_view_column_processors = Hash.new
12
+
13
+ @@handled_type_view = build_table_of_processors 'view'
14
+ @@handled_type_conditions_generator = build_table_of_processors 'conditions_generator'
15
+ end
16
+
17
+ def get_view_column_processor(column_type) #:nodoc:
18
+ @@handled_type_view[column_type] || ViewColumn
19
+ end
20
+
21
+ def get_conditions_generator_column_processor(column_type) #:nodoc:
22
+ column_type = column_type.intern if column_type.is_a? String
23
+ @@handled_type_conditions_generator[column_type] || raise("Could not find conditions generator processor for column_type #{column_type}")
24
+ end
25
+
26
+
27
+ private
28
+
29
+ def build_table_of_processors(prefix)
30
+ Hash.new.tap do |processor_table|
31
+ loaded_processors = Hash.new
32
+
33
+ Wice::Columns::COLUMN_PROCESSOR_INDEX.each do |column_type, column_source_file|
34
+ unless loaded_processors[column_source_file]
35
+ processor_class_name = "#{prefix}_#{column_source_file}".classify
36
+
37
+ unless Wice::Columns.const_defined?(processor_class_name.intern)
38
+ raise "#{column_source_file}.rb is expected to define #{processor_class_name}!"
39
+ end
40
+ processor_class = eval("Wice::Columns::#{processor_class_name}")
41
+
42
+ loaded_processors[column_source_file] = processor_class
43
+ end
44
+
45
+ processor_table[column_type] = loaded_processors[column_source_file]
46
+ end
47
+ end
48
+ end
49
+
50
+ def require_columns
51
+ Wice::Columns::COLUMN_PROCESSOR_INDEX.values.uniq do |column_source_file|
52
+ require "columns/#{column_source_file}.rb"
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ class ViewColumn #:nodoc:
59
+
60
+
61
+ include ActionView::Helpers::FormTagHelper
62
+ include ActionView::Helpers::TagHelper
63
+ include ActionView::Helpers::JavaScriptHelper
64
+ include ActionView::Helpers::AssetTagHelper
65
+
66
+ # fields defined from the options parameter
67
+ FIELDS = [:attribute, :name, :html, :filter, :model, :allow_multiple_selection,
68
+ :in_html, :in_csv, :helper_style, :table_alias, :custom_order, :detach_with_id, :ordering, :auto_reload]
69
+
70
+ attr_accessor *FIELDS
71
+
72
+ attr_accessor :cell_rendering_block, :grid, :table_name, :main_table, :model, :custom_filter
73
+
74
+ attr_reader :contains_a_text_input
75
+
76
+ def initialize(block, options, grid_obj, tname, mtable, cfilter, view) #:nodoc:
77
+ self.cell_rendering_block = block
78
+ self.grid = grid_obj
79
+ self.table_name = tname
80
+ self.main_table = mtable
81
+ self.custom_filter = cfilter
82
+ @view = view
83
+
84
+ FIELDS.each do |field|
85
+ self.send(field.to_s + '=', options[field])
86
+ end
87
+ end
88
+
89
+
90
+ def add_css_class(klass_value)
91
+ if html[:class].nil?
92
+ html[:class] = klass_value
93
+ else
94
+ html[:class] << ' ' unless html[:class].empty?
95
+ html[:class] << klass_value
96
+ end
97
+ end
98
+
99
+ def css_class #:nodoc:
100
+ html[:class] || ''
101
+ end
102
+
103
+ def yield_declaration_of_column_filter #:nodoc:
104
+ nil
105
+ end
106
+
107
+ def detachness #:nodoc:
108
+ (! detach_with_id.blank?).to_s
109
+ end
110
+
111
+ def yield_declaration #:nodoc:
112
+ declaration = yield_declaration_of_column_filter
113
+ if declaration
114
+ {
115
+ :filterName => self.name,
116
+ :detached => detachness,
117
+ :declaration => declaration
118
+ }
119
+ end
120
+ end
121
+
122
+
123
+ def config #:nodoc:
124
+ @view.config
125
+ end
126
+
127
+ def controller #:nodoc:
128
+ @view.controller
129
+ end
130
+
131
+
132
+ def render_filter #:nodoc:
133
+ params = @grid.filter_params(self)
134
+ render_filter_internal(params)
135
+ end
136
+
137
+ def render_filter_internal(params) #:nodoc:
138
+ '<!-- implement me! -->'
139
+ end
140
+
141
+ def form_parameter_name_id_and_query(v) #:nodoc:
142
+ query = form_parameter_template(v)
143
+ query_without_equals_sign = query.sub(/=$/,'')
144
+ parameter_name = CGI.unescape(query_without_equals_sign)
145
+ dom_id = id_out_of_name(parameter_name)
146
+ return query, query_without_equals_sign, parameter_name, dom_id.tr('.', '_')
147
+ end
148
+
149
+ # bad name, because for the main table the name is not really 'fully_qualified'
150
+ def attribute_name_fully_qualified_for_all_but_main_table_columns #:nodoc:
151
+ self.main_table ? attribute : table_alias_or_table_name + '.' + attribute
152
+ end
153
+
154
+ def fully_qualified_attribute_name #:nodoc:
155
+ table_alias_or_table_name + '.' + attribute
156
+ end
157
+
158
+
159
+ def filter_shown? #:nodoc:
160
+ self.attribute && self.filter
161
+ end
162
+
163
+ def filter_shown_in_main_table? #:nodoc:
164
+ filter_shown? && ! self.detach_with_id
165
+ end
166
+
167
+
168
+ def table_alias_or_table_name #:nodoc:
169
+ table_alias || table_name
170
+ end
171
+
172
+ def capable_of_hosting_filter_related_icons? #:nodoc:
173
+ self.attribute.blank? && self.name.blank? && ! self.filter_shown?
174
+ end
175
+
176
+ def has_auto_reloading_input? #:nodoc:
177
+ false
178
+ end
179
+
180
+ def auto_reloading_input_with_negation_checkbox? #:nodoc:
181
+ false
182
+ end
183
+
184
+ def has_auto_reloading_select? #:nodoc:
185
+ false
186
+ end
187
+
188
+ def has_auto_reloading_calendar? #:nodoc:
189
+ false
190
+ end
191
+
192
+ protected
193
+
194
+ def form_parameter_template(v) #:nodoc:
195
+ {@grid.name => {:f => {self.attribute_name_fully_qualified_for_all_but_main_table_columns => v}}}.to_query
196
+ end
197
+
198
+ def form_parameter_name(v) #:nodoc:
199
+ form_parameter_template_hash(v).to_query
200
+ end
201
+
202
+ def name_out_of_template(s) #:nodoc:
203
+ CGI.unescape(s).sub(/=$/,'')
204
+ end
205
+
206
+ def id_out_of_name(s) #:nodoc:
207
+ s.gsub(/[\[\]]+/,'_').sub(/_+$/, '')
208
+ end
209
+
210
+ end
211
+
212
+
213
+ class ConditionsGeneratorColumn #:nodoc:
214
+
215
+ def initialize(column_wrapper) #:nodoc:
216
+ @column_wrapper = column_wrapper
217
+ end
218
+ end
219
+
220
+ end
221
+
222
+
223
+ end
@@ -1,7 +1,7 @@
1
1
  module WiceGrid #:nodoc:
2
2
  module Generators #:nodoc:
3
3
 
4
- class AddMigrationForSerializedQueriesGenerator < Rails::Generators::Base
4
+ class AddMigrationForSerializedQueriesGenerator < Rails::Generators::Base #:nodoc:
5
5
 
6
6
  include Rails::Generators::Migration
7
7
 
@@ -1,5 +1,5 @@
1
- class CreateWiceGridSerializedQueries < ::ActiveRecord::Migration
2
- def change
1
+ class CreateWiceGridSerializedQueries < ::ActiveRecord::Migration #:nodoc:
2
+ def change #:nodoc:
3
3
  create_table :wice_grid_serialized_queries do |t|
4
4
  t.column :name, :string
5
5
  t.column :grid_name, :string
data/lib/grid_renderer.rb CHANGED
@@ -127,7 +127,11 @@ module Wice
127
127
  # * <tt>:select_all_buttons</tt> - show/hide buttons 'Select All' and 'Deselect All' in the column header.
128
128
  # The default is +true+.
129
129
  # * <tt>:object_property</tt> - a method used to obtain the value for the HTTP parameter. The default is +id+.
130
- def action_column(opts = {})
130
+ #
131
+ # You can hide a certain action checkbox if you add the usual block to +g.action_column+, just like with the
132
+ # +g.column+ definition. If the block returns +nil+ or +false+ no checkbox will be rendered.
133
+
134
+ def action_column(opts = {}, &block)
131
135
 
132
136
  if @action_column_present
133
137
  raise Wice::WiceGridException.new('There can be only one action column in a WiceGrid')
@@ -143,10 +147,10 @@ module Wice
143
147
  opts.assert_valid_keys(options.keys)
144
148
  options.merge!(opts)
145
149
  @action_column_present = true
146
- column_processor_klass = ViewColumn.get_column_processor(:action)
150
+ column_processor_klass = Columns.get_view_column_processor(:action)
147
151
 
148
152
  @columns << column_processor_klass.new(@grid, options[:html], options[:param_name],
149
- options[:select_all_buttons], options[:object_property], @view)
153
+ options[:select_all_buttons], options[:object_property], @view, block)
150
154
  end
151
155
 
152
156
  # Defines everything related to a column in a grid - column name, filtering, rendering cells, etc.
@@ -176,6 +180,9 @@ module Wice
176
180
  # is far from being user-friendly due to the number of dropdown lists.
177
181
  # * <tt>:filter</tt> - Disables filters when set to false.
178
182
  # This is needed if sorting is required while filters are not.
183
+ # * <tt>:filter_type</tt> - Using a column filter different from the default filter chosen automatically based on the
184
+ # data type or the <tt>:custom_filter</tt> argument. See <tt>lib/columns/column_processor_index.rb</tt> for the
185
+ # list of available filters.
179
186
  # * <tt>:ordering</tt> - Enable/disable ordering links in the column titles. The default is +true+
180
187
  # (i.e. if <tt>:attribute</tt> is defined, ordering is enabled)
181
188
  # * <tt>:model</tt> - Name of the model class to which <tt>:attribute</tt> belongs to if this is not the main table.
@@ -275,6 +282,7 @@ module Wice
275
282
  :model => nil,
276
283
  :negation => Defaults::NEGATION_IN_STRING_FILTERS,
277
284
  :filter => true,
285
+ :filter_type => nil,
278
286
  :table_alias => nil,
279
287
  :html => {}
280
288
  }
@@ -309,10 +317,10 @@ module Wice
309
317
  end
310
318
  end
311
319
 
312
- klass = ViewColumn
320
+ klass = Columns::ViewColumn
313
321
  if options[:attribute] &&
314
322
  col_type_and_table_name = @grid.declare_column(options[:attribute], options[:model],
315
- options[:custom_filter], options[:table_alias])
323
+ options[:custom_filter], options[:table_alias], options[:filter_type])
316
324
 
317
325
  db_column, table_name, main_table = col_type_and_table_name
318
326
  col_type = db_column.type
@@ -352,9 +360,11 @@ module Wice
352
360
  end
353
361
  end
354
362
 
355
- klass = ViewColumn.get_column_processor(:custom)
363
+ klass = Columns.get_view_column_processor(:custom)
364
+ elsif options[:filter_type]
365
+ klass = Columns.get_view_column_processor(options[:filter_type])
356
366
  else
357
- klass = ViewColumn.get_column_processor(col_type)
367
+ klass = Columns.get_view_column_processor(col_type)
358
368
  end # custom_filter
359
369
 
360
370
  end # attribute
@@ -363,8 +373,8 @@ module Wice
363
373
 
364
374
  vc.negation = options[:negation] if vc.respond_to? :negation=
365
375
 
366
- vc.filter_all_label = options[:filter_all_label] if vc.kind_of?(ViewColumn.get_column_processor(:custom))
367
- if vc.kind_of?(ViewColumn.get_column_processor(:boolean))
376
+ vc.filter_all_label = options[:filter_all_label] if vc.kind_of?(Columns.get_view_column_processor(:custom))
377
+ if vc.kind_of?(Columns.get_view_column_processor(:boolean))
368
378
  vc.boolean_filter_true_label = options[:boolean_filter_true_label]
369
379
  vc.boolean_filter_false_label = options[:boolean_filter_false_label]
370
380
  end
@@ -242,12 +242,12 @@ module Wice
242
242
 
243
243
  if column.attribute && column.ordering
244
244
 
245
- css_class = grid.filtered_by?(column) ? 'active-filter' : nil
245
+ column.add_css_class('active-filter') if grid.filtered_by?(column)
246
246
 
247
247
  direction = 'asc'
248
248
  link_style = nil
249
249
  if grid.ordered_by?(column)
250
- css_class = css_class.nil? ? 'sorted' : css_class + ' sorted'
250
+ column.add_css_class('sorted')
251
251
  link_style = grid.order_direction
252
252
  direction = 'desc' if grid.order_direction == 'asc'
253
253
  end
@@ -256,8 +256,9 @@ module Wice
256
256
  column_name,
257
257
  rendering.column_link(column, direction, params, options[:extra_request_parameters]),
258
258
  :class => link_style)
259
- grid.output_buffer << content_tag(:th, col_link, Wice::WgHash.make_hash(:class, css_class))
260
- column.css_class = css_class
259
+
260
+ grid.output_buffer << content_tag(:th, col_link, Wice::WgHash.make_hash(:class, column.css_class))
261
+
261
262
  else
262
263
  if reuse_last_column_for_filter_buttons && last
263
264
  grid.output_buffer << content_tag(:th,
@@ -324,11 +325,6 @@ module Wice
324
325
  end
325
326
  end
326
327
 
327
- rendering.each_column(:in_html) do |column|
328
- unless column.css_class.blank?
329
- Wice::WgHash.add_or_append_class_value!(column.html, column.css_class)
330
- end
331
- end
332
328
 
333
329
  grid.output_buffer << '</thead><tfoot>'
334
330
  grid.output_buffer << rendering.pagination_panel(number_of_columns, options[:hide_csv_button]) do
@@ -368,7 +364,7 @@ module Wice
368
364
 
369
365
  opts = column.html.clone
370
366
 
371
- column_block_output = if column.class == ViewColumn.get_column_processor(:action)
367
+ column_block_output = if column.class == Columns.get_view_column_processor(:action)
372
368
  cell_block.call(ar, params)
373
369
  else
374
370
  call_block(cell_block, ar)
@@ -1,9 +1,9 @@
1
1
  # encoding: UTF-8
2
2
  # It is here only until this pull request is pulled: https://github.com/amatsuda/kaminari/pull/267
3
- module Kaminari
4
- module Helpers
5
- class Tag
6
- def page_url_for(page)
3
+ module Kaminari #:nodoc:
4
+ module Helpers #:nodoc:
5
+ class Tag #:nodoc:
6
+ def page_url_for(page) #:nodoc:
7
7
  current_page_params_as_query_string = @param_name.to_s + '=' + (page <= 1 ? nil : page).to_s
8
8
  current_page_params_as_hash = Rack::Utils.parse_nested_query(current_page_params_as_query_string)
9
9
  @template.url_for Wice::WgHash.rec_merge(@params, current_page_params_as_hash).symbolize_keys