wice_grid 3.5.0 → 3.6.0.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.
- checksums.yaml +4 -4
- data/.inch.yml +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +181 -0
- data/.travis.yml +22 -0
- data/{CHANGELOG → CHANGELOG.md} +95 -31
- data/Gemfile +4 -1
- data/README.md +1517 -0
- data/Rakefile +51 -7
- data/{SAVED_QUERIES_HOWTO.rdoc → SAVED_QUERIES_HOWTO.md} +34 -31
- data/TODO.md +16 -0
- data/lib/generators/wice_grid/add_migration_for_serialized_queries_generator.rb +4 -6
- data/lib/generators/wice_grid/install_generator.rb +2 -5
- data/lib/generators/wice_grid/templates/create_wice_grid_serialized_queries.rb +1 -0
- data/lib/generators/wice_grid/templates/wice_grid_config.rb +29 -34
- data/lib/wice/active_record_column_wrapper.rb +36 -17
- data/lib/wice/columns.rb +53 -52
- data/lib/wice/columns/column_action.rb +11 -13
- data/lib/wice/columns/column_boolean.rb +9 -11
- data/lib/wice/columns/column_bootstrap_datepicker.rb +48 -0
- data/lib/wice/columns/column_custom_dropdown.rb +22 -23
- data/lib/wice/columns/column_float.rb +2 -6
- data/lib/wice/columns/column_html5_datepicker.rb +31 -0
- data/lib/wice/columns/column_integer.rb +9 -13
- data/lib/wice/columns/column_jquery_datepicker.rb +49 -0
- data/lib/wice/columns/column_processor_index.rb +18 -13
- data/lib/wice/columns/column_rails_date_helper.rb +41 -0
- data/lib/wice/columns/column_rails_datetime_helper.rb +40 -0
- data/lib/wice/columns/column_range.rb +7 -11
- data/lib/wice/columns/column_string.rb +24 -20
- data/lib/wice/columns/common_date_datetime_mixin.rb +20 -0
- data/lib/wice/columns/common_js_date_datetime_conditions_generator_mixin.rb +39 -0
- data/lib/wice/columns/common_js_date_datetime_mixin.rb +15 -0
- data/lib/wice/columns/{column_date.rb → common_rails_date_datetime_conditions_generator_mixin.rb} +4 -22
- data/lib/wice/columns/common_standard_helper_date_datetime_mixin.rb +22 -0
- data/lib/wice/grid_output_buffer.rb +19 -10
- data/lib/wice/grid_renderer.rb +146 -85
- data/lib/wice/helpers/bs_calendar_helpers.rb +6 -7
- data/lib/wice/helpers/js_calendar_helpers.rb +19 -17
- data/lib/wice/helpers/wice_grid_misc_view_helpers.rb +18 -18
- data/lib/wice/helpers/wice_grid_serialized_queries_view_helpers.rb +44 -49
- data/lib/wice/helpers/wice_grid_view_helpers.rb +131 -134
- data/lib/wice/kaminari_monkey_patching.rb +3 -1
- data/lib/wice/table_column_matrix.rb +23 -8
- data/lib/wice/wice_grid_controller.rb +12 -16
- data/lib/wice/wice_grid_core_ext.rb +12 -20
- data/lib/wice/wice_grid_misc.rb +131 -53
- data/lib/wice/wice_grid_serialized_queries_controller.rb +10 -11
- data/lib/wice/wice_grid_serialized_query.rb +4 -3
- data/lib/wice/wice_grid_spreadsheet.rb +19 -18
- data/lib/wice_grid.rb +144 -135
- data/spec/schema.rb +9 -0
- data/spec/spec_helper.rb +75 -0
- data/spec/support/active_record.rb +11 -0
- data/spec/support/wice_grid_test_config.rb +172 -0
- data/spec/wice/grid_output_buffer_spec.rb +41 -0
- data/spec/wice/table_column_matrix_spec.rb +38 -0
- data/spec/wice/wice_grid_misc_spec.rb +159 -0
- data/spec/wice/wice_grid_spreadsheet_spec.rb +14 -0
- data/test/readme.txt +1 -1
- data/vendor/assets/javascripts/wice_grid_init.js.coffee +14 -8
- data/vendor/assets/stylesheets/wice_grid.scss +84 -0
- data/wice_grid.gemspec +32 -16
- metadata +217 -25
- data/README.rdoc +0 -1325
- data/lib/generators/wice_grid/templates/wice_grid.scss +0 -140
- data/lib/wice/columns/column_datetime.rb +0 -171
- data/vendor/assets/images/icons/grid/arrow_down.gif +0 -0
- data/vendor/assets/images/icons/grid/arrow_up.gif +0 -0
- data/vendor/assets/images/icons/grid/calendar_view_month.png +0 -0
- data/vendor/assets/images/icons/grid/collapse.gif +0 -0
- data/vendor/assets/images/icons/grid/delete.png +0 -0
- data/vendor/assets/images/icons/grid/expand.gif +0 -0
- data/vendor/assets/images/icons/grid/page_white_excel.png +0 -0
- data/vendor/assets/images/icons/grid/page_white_find.png +0 -0
- data/vendor/assets/images/icons/grid/table.png +0 -0
- data/vendor/assets/images/icons/grid/table_refresh.png +0 -0
- data/vendor/assets/images/icons/grid/tick_all.png +0 -0
- data/vendor/assets/images/icons/grid/untick_all.png +0 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Wice
|
3
|
+
module Columns #:nodoc:
|
4
|
+
module CommonJsDateDatetimeConditionsGeneratorMixin #:nodoc:
|
5
|
+
|
6
|
+
def generate_conditions(table_alias, opts) #:nodoc:
|
7
|
+
|
8
|
+
datetime = @column_type == :datetime || @column_type == :timestamp
|
9
|
+
|
10
|
+
conditions = [[]]
|
11
|
+
if opts[:fr]
|
12
|
+
conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} >= ? "
|
13
|
+
date = opts[:fr].to_date
|
14
|
+
if datetime
|
15
|
+
date = date.to_datetime
|
16
|
+
end
|
17
|
+
conditions << date
|
18
|
+
end
|
19
|
+
|
20
|
+
if opts[:to]
|
21
|
+
op = '<='
|
22
|
+
date = opts[:to].to_date
|
23
|
+
if datetime
|
24
|
+
date = (date + 1).to_datetime
|
25
|
+
op = '<'
|
26
|
+
end
|
27
|
+
conditions[0] << " #{@column_wrapper.alias_or_table_name(table_alias)}.#{@column_wrapper.name} #{op} ? "
|
28
|
+
conditions << date
|
29
|
+
end
|
30
|
+
|
31
|
+
return false if conditions.size == 1
|
32
|
+
|
33
|
+
conditions[0] = conditions[0].join(' and ')
|
34
|
+
conditions
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Wice
|
3
|
+
module Columns #:nodoc:
|
4
|
+
module CommonJsDateDatetimeMixin #:nodoc:
|
5
|
+
|
6
|
+
def prepare #:nodoc:
|
7
|
+
query, _, @name1, @dom_id = form_parameter_name_id_and_query(fr: '')
|
8
|
+
query2, _, @name2, @dom_id2 = form_parameter_name_id_and_query(to: '')
|
9
|
+
|
10
|
+
@queris_ids = [[query, @dom_id], [query2, @dom_id2]]
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/wice/columns/{column_date.rb → common_rails_date_datetime_conditions_generator_mixin.rb}
RENAMED
@@ -1,24 +1,7 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
module Wice
|
2
|
-
|
3
3
|
module Columns #:nodoc:
|
4
|
-
|
5
|
-
class ViewColumnDate < ViewColumnDatetime #:nodoc:
|
6
|
-
|
7
|
-
def chunk_names
|
8
|
-
%w(year month day)
|
9
|
-
end
|
10
|
-
|
11
|
-
def render_standard_filter_internal(params) #:nodoc:
|
12
|
-
'<div class="date-filter">' +
|
13
|
-
select_date(params[:fr], {include_blank: true, prefix: @name1, id: @dom_id}) + '<br/>' +
|
14
|
-
select_date(params[:to], {include_blank: true, prefix: @name2, id: @dom_id2}) +
|
15
|
-
'</div>'
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
class ConditionsGeneratorColumnDate < ConditionsGeneratorColumn #:nodoc:
|
4
|
+
module CommonJsDateDatetimeConditionsGeneratorMixin #:nodoc:
|
22
5
|
|
23
6
|
def generate_conditions(table_alias, opts) #:nodoc:
|
24
7
|
conditions = [[]]
|
@@ -37,8 +20,7 @@ module Wice
|
|
37
20
|
conditions[0] = conditions[0].join(' and ')
|
38
21
|
conditions
|
39
22
|
end
|
40
|
-
end
|
41
23
|
|
24
|
+
end
|
42
25
|
end
|
43
|
-
|
44
|
-
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Wice
|
3
|
+
module Columns #:nodoc:
|
4
|
+
module CommonStandardDateDatetimeMixin #:nodoc:
|
5
|
+
|
6
|
+
def prepare #:nodoc:
|
7
|
+
x = lambda do|sym|
|
8
|
+
chunk_names.map do|datetime_chunk_name|
|
9
|
+
triple = form_parameter_name_id_and_query(sym => { datetime_chunk_name => '' })
|
10
|
+
[triple[0], triple[3]]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
@queris_ids = x.call(:fr) + x.call(:to)
|
15
|
+
|
16
|
+
_, _, @name1, _ = form_parameter_name_id_and_query(fr: '')
|
17
|
+
_, _, @name2, _ = form_parameter_name_id_and_query(to: '')
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,40 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
module Wice
|
2
|
-
|
3
3
|
class GridOutputBuffer < String #:nodoc:
|
4
4
|
|
5
|
+
# defines behavior for rendering nonexistent filters.
|
6
|
+
# If return_empty_strings_for_nonexistent_filters is true, a call to render a non existent filter will raise an exception
|
7
|
+
# If return_empty_strings_for_nonexistent_filters is false (CSV mode), no exception will be raised.
|
5
8
|
attr_accessor :return_empty_strings_for_nonexistent_filters
|
6
9
|
|
10
|
+
# initializes a grid output buffer
|
7
11
|
def initialize(*attrs)
|
8
12
|
super(*attrs)
|
9
13
|
@filters = HashWithIndifferentAccess.new
|
10
14
|
end
|
11
15
|
|
16
|
+
# returns HTML code the grid
|
12
17
|
def to_s
|
13
18
|
super.html_safe
|
14
19
|
end
|
15
20
|
|
21
|
+
# stores HTML code for a detached filter
|
16
22
|
def add_filter(detach_with_id, filter_code)
|
17
|
-
|
23
|
+
fail WiceGridException.new("Detached ID #{detach_with_id} is already used!") if @filters.key? detach_with_id
|
18
24
|
@filters[detach_with_id] = filter_code
|
19
25
|
end
|
20
26
|
|
21
|
-
|
22
|
-
|
27
|
+
# returns HTML code for a detached filter
|
28
|
+
def filter_for(detach_with_id)
|
29
|
+
unless @filters.key? detach_with_id
|
23
30
|
if @return_empty_strings_for_nonexistent_filters
|
24
31
|
return ''
|
25
32
|
else
|
26
|
-
|
33
|
+
fail WiceGridException.new("No filter with Detached ID '#{detach_with_id}'!")
|
27
34
|
end
|
28
35
|
end
|
29
|
-
|
30
|
-
|
36
|
+
|
37
|
+
unless @filters[detach_with_id]
|
38
|
+
fail WiceGridException.new("Filter with Detached ID '#{detach_with_id}' has already been requested once! There cannot be two instances of the same filter on one page")
|
31
39
|
end
|
40
|
+
|
32
41
|
res = @filters[detach_with_id]
|
33
42
|
@filters[detach_with_id] = false
|
34
|
-
|
43
|
+
res
|
35
44
|
end
|
36
45
|
|
46
|
+
# returns HTML code for a detached filter
|
37
47
|
alias_method :[], :filter_for
|
38
|
-
|
39
48
|
end
|
40
|
-
end
|
49
|
+
end
|
data/lib/wice/grid_renderer.rb
CHANGED
@@ -1,32 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
module Wice
|
2
|
-
class GridRenderer
|
3
3
|
|
4
|
+
# Instance of `GridRenderer` is injected into the top level block of the `grid` helper.
|
5
|
+
# `g.column`, `g.action_column` are all examples of methods of `GridRenderer`
|
6
|
+
class GridRenderer
|
4
7
|
include ActionView::Helpers::TagHelper
|
5
8
|
include ActionView::Helpers::CaptureHelper
|
6
9
|
include ActionView::Helpers::TextHelper
|
7
10
|
include ActionView::Helpers::AssetTagHelper
|
8
11
|
include ActionView::Helpers::JavaScriptHelper
|
9
12
|
|
10
|
-
|
13
|
+
# a Proc object for the after_row block
|
11
14
|
attr_reader :after_row_handler
|
15
|
+
|
16
|
+
# a Proc object for the before_row block
|
12
17
|
attr_reader :before_row_handler
|
18
|
+
|
19
|
+
# a Proc object for the replace_row block
|
13
20
|
attr_reader :replace_row_handler
|
21
|
+
|
22
|
+
# Configuration or a Proc object for the blank_slate block
|
14
23
|
attr_reader :blank_slate_handler
|
24
|
+
|
25
|
+
# a Proc object which returns contents of the last row
|
15
26
|
attr_reader :last_row_handler
|
27
|
+
|
28
|
+
# reference to the WiceGrid instance
|
16
29
|
attr_reader :grid
|
30
|
+
|
31
|
+
# Contents of <caption></caption>
|
17
32
|
attr_reader :kaption
|
18
33
|
|
19
|
-
|
20
|
-
|
21
|
-
|
34
|
+
# HTTP parameter for the order field
|
35
|
+
ORDER_PARAMETER_NAME = 'order'
|
36
|
+
|
37
|
+
# HTTP parameter for the order direction (asc/desc)
|
38
|
+
ORDER_DIRECTION_PARAMETER_NAME = 'order_direction'
|
22
39
|
|
23
40
|
def initialize(grid, view) #:nodoc:
|
24
|
-
@grid
|
25
|
-
@grid.renderer
|
26
|
-
@columns
|
27
|
-
@columns_table
|
41
|
+
@grid = grid
|
42
|
+
@grid.renderer = self
|
43
|
+
@columns = []
|
44
|
+
@columns_table = {}
|
28
45
|
@action_column_present = false
|
29
|
-
@view
|
46
|
+
@view = view
|
30
47
|
end
|
31
48
|
|
32
49
|
def config #:nodoc:
|
@@ -37,7 +54,6 @@ module Wice
|
|
37
54
|
@view.controller
|
38
55
|
end
|
39
56
|
|
40
|
-
|
41
57
|
def add_column(vc) #:nodoc:
|
42
58
|
@columns_table[vc.fully_qualified_attribute_name] = vc if vc.attribute
|
43
59
|
@columns << vc
|
@@ -52,7 +68,7 @@ module Wice
|
|
52
68
|
end
|
53
69
|
|
54
70
|
def each_column_label(filter = nil) #:nodoc:
|
55
|
-
filter_columns(filter).each{|col| yield col.name}
|
71
|
+
filter_columns(filter).each { |col| yield col.name }
|
56
72
|
end
|
57
73
|
|
58
74
|
def column_labels(filter = nil) #:nodoc:
|
@@ -60,12 +76,12 @@ module Wice
|
|
60
76
|
end
|
61
77
|
|
62
78
|
def each_column(filter = nil) #:nodoc:
|
63
|
-
filter_columns(filter).each{|col| yield col}
|
79
|
+
filter_columns(filter).each { |col| yield col }
|
64
80
|
end
|
65
81
|
|
66
82
|
def each_column_aware_of_one_last_one(filter = nil) #:nodoc:
|
67
83
|
cols = filter_columns(filter)
|
68
|
-
cols[0..-2].each{|col| yield col, false}
|
84
|
+
cols[0..-2].each { |col| yield col, false }
|
69
85
|
yield cols.last, true
|
70
86
|
end
|
71
87
|
|
@@ -74,23 +90,24 @@ module Wice
|
|
74
90
|
end
|
75
91
|
|
76
92
|
def select_for(filter) #:nodoc:
|
77
|
-
filter_columns(filter).select{|col| yield col}
|
93
|
+
filter_columns(filter).select { |col| yield col }
|
78
94
|
end
|
79
95
|
|
80
96
|
def find_one_for(filter) #:nodoc:
|
81
|
-
filter_columns(filter).find{|col| yield col}
|
97
|
+
filter_columns(filter).find { |col| yield col }
|
82
98
|
end
|
83
99
|
|
84
|
-
|
85
100
|
def each_column_with_attribute #:nodoc:
|
86
|
-
@columns.select(&:attribute).each{|col| yield col}
|
101
|
+
@columns.select(&:attribute).each { |col| yield col }
|
87
102
|
end
|
88
103
|
|
89
104
|
alias_method :each, :each_column
|
90
105
|
include Enumerable
|
91
106
|
|
92
107
|
def csv_export_icon #:nodoc:
|
93
|
-
content_tag(
|
108
|
+
content_tag(
|
109
|
+
:div,
|
110
|
+
content_tag(:i, '', class: 'fa fa-file-excel-o'),
|
94
111
|
title: NlMessage['csv_export_tooltip'],
|
95
112
|
class: 'clickable export-to-csv-button'
|
96
113
|
)
|
@@ -99,7 +116,7 @@ module Wice
|
|
99
116
|
def pagination_panel(number_of_columns, hide_csv_button) #:nodoc:
|
100
117
|
panel = yield
|
101
118
|
|
102
|
-
render_csv_button = @grid.export_to_csv_enabled && !
|
119
|
+
render_csv_button = @grid.export_to_csv_enabled && !hide_csv_button
|
103
120
|
|
104
121
|
if panel.nil?
|
105
122
|
if render_csv_button
|
@@ -116,9 +133,9 @@ module Wice
|
|
116
133
|
end
|
117
134
|
end
|
118
135
|
|
119
|
-
# Takes one argument and adds the <caption></caption> tag to the table with the
|
120
|
-
# the contents of <caption>.
|
121
|
-
def caption
|
136
|
+
# Takes one argument and adds the <caption></caption> tag to the table with the
|
137
|
+
# argument value as the contents of <caption>.
|
138
|
+
def caption(kaption)
|
122
139
|
@kaption = kaption
|
123
140
|
end
|
124
141
|
|
@@ -140,9 +157,8 @@ module Wice
|
|
140
157
|
# +g.column+ definition. If the block returns +nil+ or +false+ no checkbox will be rendered.
|
141
158
|
|
142
159
|
def action_column(opts = {}, &block)
|
143
|
-
|
144
160
|
if @action_column_present
|
145
|
-
|
161
|
+
fail Wice::WiceGridException.new('There can be only one action column in a WiceGrid')
|
146
162
|
end
|
147
163
|
|
148
164
|
options = {
|
@@ -150,7 +166,7 @@ module Wice
|
|
150
166
|
html: {},
|
151
167
|
select_all_buttons: true,
|
152
168
|
object_property: :id,
|
153
|
-
html_check_box: true
|
169
|
+
html_check_box: true
|
154
170
|
}
|
155
171
|
|
156
172
|
opts.assert_valid_keys(options.keys)
|
@@ -182,7 +198,7 @@ module Wice
|
|
182
198
|
# * <tt>:class</tt> - a shortcut for <tt>html: {class: 'css_class'}</tt>
|
183
199
|
# * <tt>:attribute</tt> - name of a database column (which normally correspond to a model attribute with the
|
184
200
|
# same name). By default the field is assumed to belong to the default table (see documentation for the
|
185
|
-
# +initialize_grid+ method). Parameter <tt>:
|
201
|
+
# +initialize_grid+ method). Parameter <tt>:assoc</tt> (association) allows to specify another joined table. Presence of
|
186
202
|
# this parameter
|
187
203
|
# * adds sorting capabilities by this field
|
188
204
|
# * automatically creates a filter based on the type of the field unless parameter <tt>:filter</tt> is set to false.
|
@@ -202,7 +218,7 @@ module Wice
|
|
202
218
|
# list of available filters.
|
203
219
|
# * <tt>:ordering</tt> - Enable/disable ordering links in the column titles. The default is +true+
|
204
220
|
# (i.e. if <tt>:attribute</tt> is defined, ordering is enabled)
|
205
|
-
# * <tt>:
|
221
|
+
# * <tt>:assoc</tt> - Name of the model association. <tt>:attribute</tt> belongs to the table joined via this association.
|
206
222
|
# * <tt>:table_alias</tt> - In case there are two joined assocations both referring to the same table, ActiveRecord
|
207
223
|
# constructs a query where the second join provides an alias for the joined table. Setting <tt>:table_alias</tt>
|
208
224
|
# to this alias will enable WiceGrid to order and filter by columns belonging to different associatiations but
|
@@ -258,9 +274,6 @@ module Wice
|
|
258
274
|
# to false will prohibit the column from inclusion into the export.
|
259
275
|
# * <tt>:in_html</tt> - When CSV export is enabled and it is needed to use a column for CSV export only and ignore it
|
260
276
|
# in HTML, set this parameter to false.
|
261
|
-
# * <tt>:helper_style</tt> - Changes the flavor of Date and DateTime filters. The values are:
|
262
|
-
# * <tt>:standard</tt> - the default Rails Date/DateTime helper
|
263
|
-
# * <tt>:calendar</tt> - a Javascript popup calendar control
|
264
277
|
# * <tt>:negation</tt> - turn on/off the negation checkbox in string filters
|
265
278
|
# * <tt>:auto_reload</tt> - a boolean value specifying if a change in a filter triggers reloading of the grid. Works with all
|
266
279
|
# filter types including the JS calendar, the only exception is the standard Rails date/datetime filters.
|
@@ -282,44 +295,59 @@ module Wice
|
|
282
295
|
|
283
296
|
def column(opts = {}, &block)
|
284
297
|
options = {
|
285
|
-
allow_multiple_selection:
|
286
|
-
|
298
|
+
allow_multiple_selection: ConfigurationProvider.value_for(:ALLOW_MULTIPLE_SELECTION),
|
299
|
+
assoc: nil,
|
287
300
|
attribute: nil,
|
288
|
-
auto_reload:
|
301
|
+
auto_reload: ConfigurationProvider.value_for(:AUTO_RELOAD),
|
289
302
|
boolean_filter_false_label: NlMessage['boolean_filter_false_label'],
|
290
303
|
boolean_filter_true_label: NlMessage['boolean_filter_true_label'],
|
291
304
|
class: nil,
|
292
|
-
name: '',
|
293
305
|
custom_filter: nil,
|
294
306
|
detach_with_id: nil,
|
295
|
-
filter_all_label: Defaults::CUSTOM_FILTER_ALL_LABEL,
|
296
|
-
helper_style: Defaults::HELPER_STYLE,
|
297
|
-
in_csv: true,
|
298
|
-
in_html: true,
|
299
|
-
model: nil,
|
300
|
-
negation: Defaults::NEGATION_IN_STRING_FILTERS,
|
301
307
|
filter: true,
|
308
|
+
filter_all_label: ConfigurationProvider.value_for(:CUSTOM_FILTER_ALL_LABEL),
|
302
309
|
filter_type: nil,
|
303
|
-
|
304
|
-
|
310
|
+
html: {},
|
311
|
+
in_csv: true,
|
312
|
+
in_html: true,
|
313
|
+
model: nil, # will throw an exception with instructions
|
314
|
+
name: '',
|
315
|
+
negation: ConfigurationProvider.value_for(:NEGATION_IN_STRING_FILTERS),
|
316
|
+
ordering: true,
|
317
|
+
table_alias: nil
|
305
318
|
}
|
306
319
|
|
307
320
|
opts.assert_valid_keys(options.keys)
|
308
321
|
options.merge!(opts)
|
309
322
|
|
310
|
-
|
311
|
-
|
312
|
-
|
323
|
+
assocs = nil
|
324
|
+
|
325
|
+
if options[:model]
|
326
|
+
fail WiceGridArgumentError.new('Instead of specifying a model of a joined table please use assoc: :name_of_association')
|
327
|
+
end
|
328
|
+
|
329
|
+
unless options[:assoc].nil?
|
330
|
+
|
331
|
+
unless options[:assoc].is_a?(Symbol) ||
|
332
|
+
(options[:assoc].is_a?(Array) && ! options[:assoc].empty? && options[:assoc].all?{ |assoc| assoc.is_a?(Symbol)})
|
333
|
+
|
334
|
+
fail WiceGridArgumentError.new('Option :assoc can only be a symbol or an array of symbols')
|
335
|
+
end
|
336
|
+
|
337
|
+
assocs = options[:assoc].is_a?(Symbol) ? [options[:assoc]] : options[:assoc]
|
338
|
+
|
339
|
+
options[:model] = get_model_from_associations(@grid.klass, assocs)
|
313
340
|
end
|
314
341
|
|
315
342
|
if options[:attribute].nil? && options[:model]
|
316
|
-
|
343
|
+
fail WiceGridArgumentError.new('Option :assoc is only used together with :attribute')
|
317
344
|
end
|
318
345
|
|
319
346
|
if options[:attribute] && options[:attribute].index('.')
|
320
|
-
|
347
|
+
fail WiceGridArgumentError.new("Invalid attribute name #{options[:attribute]}. An attribute name must not contain a table name!")
|
321
348
|
end
|
322
349
|
|
350
|
+
|
323
351
|
if options[:class]
|
324
352
|
options[:html] ||= {}
|
325
353
|
Wice::WgHash.add_or_append_class_value!(options[:html], options[:class])
|
@@ -327,29 +355,41 @@ module Wice
|
|
327
355
|
end
|
328
356
|
|
329
357
|
if block.nil?
|
330
|
-
if !
|
331
|
-
|
358
|
+
if !options[:attribute].blank?
|
359
|
+
if assocs.nil?
|
360
|
+
block = ->(obj) { obj.send(options[:attribute]) }
|
361
|
+
else
|
362
|
+
messages = assocs + [ options[:attribute] ]
|
363
|
+
block = ->(obj) { obj.deep_send(*messages) }
|
364
|
+
end
|
332
365
|
else
|
333
|
-
|
334
|
-
|
366
|
+
fail WiceGridArgumentError.new(
|
367
|
+
'Missing column block without attribute defined. You can only omit the block if attribute is present.')
|
335
368
|
end
|
336
369
|
end
|
337
370
|
|
338
371
|
klass = Columns::ViewColumn
|
339
372
|
if options[:attribute] &&
|
340
|
-
|
341
|
-
|
342
|
-
|
373
|
+
col_type_and_table_name = @grid.declare_column(
|
374
|
+
column_name: options[:attribute],
|
375
|
+
model: options[:model],
|
376
|
+
custom_filter_active: options[:custom_filter],
|
377
|
+
table_alias: options[:table_alias],
|
378
|
+
filter_type: options[:filter_type],
|
379
|
+
assocs: assocs
|
380
|
+
)
|
381
|
+
|
382
|
+
# [ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::Column, String, Boolean]
|
343
383
|
db_column, table_name, main_table = col_type_and_table_name
|
344
384
|
col_type = db_column.type
|
345
385
|
|
346
386
|
if options[:custom_filter]
|
347
387
|
|
348
388
|
custom_filter = if options[:custom_filter] == :auto
|
349
|
-
|
389
|
+
-> { @grid.distinct_values_for_column(db_column) } # Thank God Ruby has higher order functions!!!
|
350
390
|
|
351
391
|
elsif options[:custom_filter].class == Symbol
|
352
|
-
|
392
|
+
-> { @grid.distinct_values_for_column_in_resultset([options[:custom_filter]]) }
|
353
393
|
|
354
394
|
elsif options[:custom_filter].class == Hash
|
355
395
|
options[:custom_filter].keys
|
@@ -360,19 +400,19 @@ module Wice
|
|
360
400
|
if options[:custom_filter].empty?
|
361
401
|
[]
|
362
402
|
elsif Wice::WgEnumerable.all_items_are_of_class(options[:custom_filter], Symbol)
|
363
|
-
|
403
|
+
-> { @grid.distinct_values_for_column_in_resultset(options[:custom_filter]) }
|
364
404
|
|
365
405
|
elsif Wice::WgEnumerable.all_items_are_of_class(options[:custom_filter], String) || WgEnumerable.all_items_are_of_class(options[:custom_filter], Numeric)
|
366
|
-
options[:custom_filter].map{|i| [i,i]}
|
406
|
+
options[:custom_filter].map { |i| [i, i] }
|
367
407
|
|
368
408
|
elsif Wice::WgEnumerable.all_items_are_of_class(options[:custom_filter], Array)
|
369
409
|
options[:custom_filter]
|
370
410
|
else
|
371
|
-
|
372
|
-
':custom_filter can equal :auto, an array of string and/or numbers (direct values for the dropdown), '
|
373
|
-
'a homogeneous array of symbols (a sequence of methods to send to AR objects in the result set to '
|
374
|
-
'retrieve unique values for the dropdown), a Symbol (a shortcut for a one member array of symbols), '
|
375
|
-
'a hash where keys are labels and values are values for the dropdown option, or an array of two-item arrays, '
|
411
|
+
fail WiceGridArgumentError.new(
|
412
|
+
':custom_filter can equal :auto, an array of string and/or numbers (direct values for the dropdown), ' \
|
413
|
+
'a homogeneous array of symbols (a sequence of methods to send to AR objects in the result set to ' \
|
414
|
+
'retrieve unique values for the dropdown), a Symbol (a shortcut for a one member array of symbols), ' \
|
415
|
+
'a hash where keys are labels and values are values for the dropdown option, or an array of two-item arrays, ' \
|
376
416
|
'each of which contains the label (first element) and the value (second element) for a dropdown option'
|
377
417
|
)
|
378
418
|
end
|
@@ -382,6 +422,18 @@ module Wice
|
|
382
422
|
elsif options[:filter_type]
|
383
423
|
klass = Columns.get_view_column_processor(options[:filter_type])
|
384
424
|
else
|
425
|
+
|
426
|
+
col_type = case col_type
|
427
|
+
when :date
|
428
|
+
Wice::Defaults::DEFAULT_FILTER_FOR_DATE
|
429
|
+
when :datetime
|
430
|
+
Wice::Defaults::DEFAULT_FILTER_FOR_DATETIME
|
431
|
+
when :timestamp
|
432
|
+
Wice::Defaults::DEFAULT_FILTER_FOR_DATETIME
|
433
|
+
else
|
434
|
+
col_type
|
435
|
+
end
|
436
|
+
|
385
437
|
klass = Columns.get_view_column_processor(col_type)
|
386
438
|
end # custom_filter
|
387
439
|
|
@@ -391,14 +443,30 @@ module Wice
|
|
391
443
|
|
392
444
|
vc.negation = options[:negation] if vc.respond_to? :negation=
|
393
445
|
|
394
|
-
vc.filter_all_label = options[:filter_all_label] if vc.
|
395
|
-
if vc.
|
446
|
+
vc.filter_all_label = options[:filter_all_label] if vc.is_a?(Columns.get_view_column_processor(:custom))
|
447
|
+
if vc.is_a?(Columns.get_view_column_processor(:boolean))
|
396
448
|
vc.boolean_filter_true_label = options[:boolean_filter_true_label]
|
397
449
|
vc.boolean_filter_false_label = options[:boolean_filter_false_label]
|
398
450
|
end
|
399
451
|
add_column(vc)
|
400
452
|
end
|
401
453
|
|
454
|
+
def get_model_from_associations(model, assocs) # :nodoc:
|
455
|
+
if assocs.empty?
|
456
|
+
model
|
457
|
+
else
|
458
|
+
head = assocs[0]
|
459
|
+
tail = assocs[1..-1]
|
460
|
+
|
461
|
+
if reflection = model.reflect_on_association(head)
|
462
|
+
next_model = reflection.klass
|
463
|
+
get_model_from_associations(next_model, tail)
|
464
|
+
else
|
465
|
+
fail WiceGridArgumentError.new("Association #{head} not found in #{model}")
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
402
470
|
# Optional method inside the +grid+ block, to which every ActiveRecord instance is injected, just like +column+.
|
403
471
|
# Unlike +column+, it returns a hash which will be used as HTML attributes for the row with the given ActiveRecord instance.
|
404
472
|
#
|
@@ -431,28 +499,28 @@ module Wice
|
|
431
499
|
def last_row(&block)
|
432
500
|
@last_row_handler = block
|
433
501
|
end
|
502
|
+
|
434
503
|
# The output of the block submitted to +blank_slate+ is rendered instead of the whole grid if no filters are active
|
435
504
|
# and there are no records to render.
|
436
505
|
# In addition to the block style two other variants are accepted:
|
437
506
|
# * <tt>g.blank_slate "some text to be rendered"</tt>
|
438
507
|
# * <tt>g.blank_slate partial: "partial_name"</tt>
|
439
508
|
def blank_slate(opts = nil, &block)
|
440
|
-
if (opts.is_a?(Hash) && opts.
|
509
|
+
if (opts.is_a?(Hash) && opts.key?(:partial) && block.nil?) || (opts.is_a?(String) && block.nil?)
|
441
510
|
@blank_slate_handler = opts
|
442
511
|
elsif opts.nil? && block
|
443
512
|
@blank_slate_handler = block
|
444
513
|
else
|
445
|
-
|
514
|
+
fail WiceGridArgumentError.new("blank_slate accepts only a string, a block, or template: 'path_to_template' ")
|
446
515
|
end
|
447
516
|
end
|
448
517
|
|
449
|
-
|
450
518
|
def get_row_attributes(ar_object) #:nodoc:
|
451
519
|
if @row_attributes_handler
|
452
520
|
row_attributes = @row_attributes_handler.call(ar_object)
|
453
521
|
row_attributes = {} if row_attributes.blank?
|
454
522
|
unless row_attributes.is_a?(Hash)
|
455
|
-
|
523
|
+
fail WiceGridArgumentError.new("row_attributes block must return a hash containing HTML attributes. The returned value is #{row_attributes.inspect}")
|
456
524
|
end
|
457
525
|
row_attributes
|
458
526
|
else
|
@@ -460,13 +528,12 @@ module Wice
|
|
460
528
|
end
|
461
529
|
end
|
462
530
|
|
463
|
-
|
464
531
|
def no_filter_needed? #:nodoc:
|
465
|
-
|
532
|
+
!@columns.inject(false) { |a, b| a || b.filter_shown? }
|
466
533
|
end
|
467
534
|
|
468
535
|
def no_filter_needed_in_main_table? #:nodoc:
|
469
|
-
|
536
|
+
!@columns.inject(false) { |a, b| a || b.filter_shown_in_main_table? }
|
470
537
|
end
|
471
538
|
|
472
539
|
def base_link_for_filter(controller, extra_parameters = {}) #:nodoc:
|
@@ -500,19 +567,17 @@ module Wice
|
|
500
567
|
controller.url_for(new_params)
|
501
568
|
end
|
502
569
|
|
503
|
-
|
504
570
|
def column_link(column, direction, params, extra_parameters = {}) #:nodoc:
|
505
|
-
|
506
|
-
column_attribute_name = if column.attribute.index('.') or column.main_table
|
571
|
+
column_attribute_name = if column.attribute.index('.') || column.main_table
|
507
572
|
column.attribute
|
508
573
|
else
|
509
574
|
column.table_alias_or_table_name + '.' + column.attribute
|
510
575
|
end
|
511
576
|
|
512
|
-
query_params = {@grid.name => {
|
513
|
-
|
514
|
-
|
515
|
-
}}
|
577
|
+
query_params = { @grid.name => {
|
578
|
+
ORDER_PARAMETER_NAME => column_attribute_name,
|
579
|
+
ORDER_DIRECTION_PARAMETER_NAME => direction
|
580
|
+
} }
|
516
581
|
|
517
582
|
cleaned_params = Wice::WgHash.deep_clone params
|
518
583
|
cleaned_params.merge!(extra_parameters)
|
@@ -520,16 +585,13 @@ module Wice
|
|
520
585
|
cleaned_params.delete(:controller)
|
521
586
|
cleaned_params.delete(:action)
|
522
587
|
|
523
|
-
|
524
588
|
query_params = Wice::WgHash.rec_merge(cleaned_params, query_params)
|
525
589
|
|
526
590
|
'?' + query_params.to_query
|
527
591
|
end
|
528
592
|
|
529
|
-
|
530
593
|
protected
|
531
594
|
|
532
|
-
|
533
595
|
def filter_columns(method_name = nil) #:nodoc:
|
534
596
|
method_name ? @columns.select(&method_name) : @columns
|
535
597
|
end
|
@@ -541,8 +603,7 @@ module Wice
|
|
541
603
|
# /foo?grid=some_value --> /foo?grid=some_value
|
542
604
|
|
543
605
|
empty_hash_rx = Regexp.new "([&?])#{Regexp.escape @grid.name}=([&?]|$)" # c.f., issue #140
|
544
|
-
url.gsub(empty_hash_rx, '\1').gsub
|
606
|
+
url.gsub(empty_hash_rx, '\1').gsub(/\?+$/, '')
|
545
607
|
end
|
546
|
-
|
547
608
|
end
|
548
609
|
end
|