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