wice_grid 3.2.0 → 3.2.1.pre1

Sign up to get free protection for your applications and to get access to all the features.
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