effective_datatables 3.7.7 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/MIT-LICENSE +1 -1
- data/README.md +32 -32
- data/app/assets/images/dataTables/sort-down.svg +1 -0
- data/app/assets/images/dataTables/sort-up.svg +1 -0
- data/app/assets/images/dataTables/sort.svg +1 -0
- data/app/assets/javascripts/dataTables/buttons/{buttons.bootstrap.js → buttons.bootstrap4.js} +7 -15
- data/app/assets/javascripts/dataTables/dataTables.bootstrap4.js +184 -0
- data/app/assets/javascripts/dataTables/responsive/dataTables.responsive.js +30 -11
- data/app/assets/javascripts/dataTables/responsive/{responsive.bootstrap.js → responsive.bootstrap4.js} +6 -6
- data/app/assets/javascripts/effective_datatables.js +4 -4
- data/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee +43 -43
- data/app/assets/javascripts/effective_datatables/events.js.coffee +7 -4
- data/app/assets/javascripts/effective_datatables/filters.js.coffee +0 -1
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee +45 -49
- data/app/assets/javascripts/effective_datatables/overrides.js +12 -0
- data/app/assets/javascripts/effective_datatables/reset.js.coffee +1 -1
- data/app/assets/stylesheets/dataTables/buttons/{buttons.bootstrap.scss → buttons.bootstrap4.css} +68 -1
- data/app/assets/stylesheets/dataTables/{dataTables.bootstrap.scss → dataTables.bootstrap4.css} +44 -29
- data/app/assets/stylesheets/dataTables/responsive/{responsive.bootstrap.scss → responsive.bootstrap4.css} +3 -3
- data/app/assets/stylesheets/effective_datatables.scss +3 -4
- data/app/assets/stylesheets/effective_datatables/_overrides.scss +72 -152
- data/app/controllers/effective/datatables_controller.rb +6 -39
- data/app/helpers/effective_datatables_helper.rb +55 -50
- data/app/helpers/effective_datatables_private_helper.rb +47 -179
- data/app/models/effective/datatable.rb +16 -44
- data/app/models/effective/datatable_column.rb +0 -1
- data/app/models/effective/datatable_column_tool.rb +1 -1
- data/app/models/effective/datatable_dsl_tool.rb +3 -11
- data/app/models/effective/datatable_value_tool.rb +23 -23
- data/app/models/effective/effective_datatable/attributes.rb +13 -5
- data/app/models/effective/effective_datatable/collection.rb +3 -18
- data/app/models/effective/effective_datatable/compute.rb +6 -17
- data/app/models/effective/effective_datatable/cookie.rb +20 -19
- data/app/models/effective/effective_datatable/dsl.rb +3 -8
- data/app/models/effective/effective_datatable/dsl/bulk_actions.rb +25 -14
- data/app/models/effective/effective_datatable/dsl/datatable.rb +28 -70
- data/app/models/effective/effective_datatable/dsl/filters.rb +5 -5
- data/app/models/effective/effective_datatable/format.rb +50 -95
- data/app/models/effective/effective_datatable/params.rb +3 -8
- data/app/models/effective/effective_datatable/resource.rb +76 -137
- data/app/models/effective/effective_datatable/state.rb +15 -30
- data/app/views/effective/datatables/_actions_column.html.haml +8 -1
- data/app/views/effective/datatables/_bulk_actions_column.html.haml +1 -1
- data/app/views/effective/datatables/_filters.html.haml +11 -12
- data/app/views/effective/datatables/_resource_column.html.haml +8 -11
- data/config/effective_datatables.rb +14 -12
- data/config/routes.rb +0 -1
- data/lib/effective_datatables.rb +4 -57
- data/lib/effective_datatables/engine.rb +1 -1
- data/lib/effective_datatables/version.rb +1 -1
- metadata +20 -30
- data/app/assets/images/dataTables/sort_asc.png +0 -0
- data/app/assets/images/dataTables/sort_both.png +0 -0
- data/app/assets/images/dataTables/sort_desc.png +0 -0
- data/app/assets/javascripts/dataTables/dataTables.bootstrap.js +0 -182
- data/app/assets/javascripts/dataTables/locales/en.lang +0 -33
- data/app/assets/javascripts/dataTables/locales/es.lang +0 -36
- data/app/assets/javascripts/dataTables/locales/nl.lang +0 -30
- data/app/assets/javascripts/effective_datatables/flash.js.coffee +0 -31
- data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +0 -217
- data/app/assets/javascripts/effective_datatables/overrides.js.coffee +0 -7
- data/app/assets/javascripts/effective_datatables/reorder.js.coffee +0 -43
- data/app/assets/stylesheets/effective_datatables/_filters.scss +0 -7
- data/app/views/effective/datatables/_reorder_column.html.haml +0 -5
- data/config/locales/en.yml +0 -12
- data/config/locales/es.yml +0 -12
- data/config/locales/nl.yml +0 -12
@@ -1,15 +1,8 @@
|
|
1
1
|
# These are expected to be called by a developer. They are part of the datatables DSL.
|
2
2
|
module EffectiveDatatablesHelper
|
3
|
-
def render_datatable(datatable, input_js: {}, buttons: true, charts: true, entries: true, filters: true, inline: false, pagination: true, search: true, simple: false, sort: true)
|
4
|
-
raise 'expected datatable to be present' unless datatable
|
5
|
-
raise 'expected input_js to be a Hash' unless input_js.kind_of?(Hash)
|
6
|
-
|
7
|
-
if simple
|
8
|
-
buttons = charts = entries = filters = pagination = search = sort = false
|
9
|
-
end
|
10
3
|
|
11
|
-
|
12
|
-
datatable
|
4
|
+
def render_datatable(datatable, input_js: {}, buttons: true, charts: true, filters: true, simple: false)
|
5
|
+
raise 'expected datatable to be present' unless datatable
|
13
6
|
|
14
7
|
datatable.view ||= self
|
15
8
|
|
@@ -20,48 +13,29 @@ module EffectiveDatatablesHelper
|
|
20
13
|
charts = charts && datatable._charts.present?
|
21
14
|
filters = filters && (datatable._scopes.present? || datatable._filters.present?)
|
22
15
|
|
23
|
-
|
24
|
-
|
25
|
-
if datatable.reorder? && !buttons
|
26
|
-
buttons = true; input_js[:buttons] = false
|
27
|
-
end
|
28
|
-
|
29
|
-
# Build the datatables DOM option
|
30
|
-
input_js[:dom] ||= [
|
31
|
-
("<'row'<'col-sm-12 dataTables_buttons'B>>" if buttons),
|
32
|
-
"<'row'<'col-sm-12'tr>>",
|
33
|
-
("<'row'" if entries || pagination),
|
34
|
-
("<'col-sm-6 dataTables_entries'il>" if entries),
|
35
|
-
("<'col-sm-6'p>" if pagination),
|
36
|
-
(">" if entries || pagination)
|
37
|
-
].compact.join
|
16
|
+
datatable.attributes[:simple] = true if simple
|
17
|
+
input_js[:buttons] = false if simple || !buttons
|
38
18
|
|
39
19
|
effective_datatable_params = {
|
40
20
|
id: datatable.to_param,
|
41
|
-
class:
|
21
|
+
class: ('effective-datatable ' + Array(datatable.table_html_class).join(' ')),
|
42
22
|
data: {
|
43
|
-
'attributes' => EffectiveDatatables.encrypt(datatable.attributes),
|
44
|
-
'authenticity-token' => form_authenticity_token,
|
45
23
|
'bulk-actions' => datatable_bulk_actions(datatable),
|
46
24
|
'columns' => datatable_columns(datatable),
|
25
|
+
'cookie' => datatable.cookie_key,
|
47
26
|
'display-length' => datatable.display_length,
|
48
|
-
'display-order' =>
|
27
|
+
'display-order' => [datatable.order_index, datatable.order_direction].to_json().html_safe,
|
49
28
|
'display-records' => datatable.to_json[:recordsFiltered],
|
50
29
|
'display-start' => datatable.display_start,
|
51
|
-
'
|
52
|
-
'
|
53
|
-
'
|
54
|
-
'reset' => (datatable_reset(datatable) if search),
|
55
|
-
'reorder' => datatable_reorder(datatable),
|
56
|
-
'reorder-index' => (datatable.columns[:_reorder][:index] if datatable.reorder?).to_s,
|
57
|
-
'simple' => simple.to_s,
|
58
|
-
'spinner' => '', # effective_bootstrap
|
30
|
+
'options' => (input_js || {}).to_json.html_safe,
|
31
|
+
'reset' => datatable_reset(datatable),
|
32
|
+
'simple' => datatable.simple?.to_s,
|
59
33
|
'source' => effective_datatables.datatable_path(datatable, {format: 'json'}),
|
60
34
|
'total-records' => datatable.to_json[:recordsTotal]
|
61
35
|
}
|
62
36
|
}
|
63
37
|
|
64
|
-
if (charts || filters)
|
38
|
+
if (charts || filters) && !simple
|
65
39
|
output = ''.html_safe
|
66
40
|
|
67
41
|
if charts
|
@@ -84,28 +58,59 @@ module EffectiveDatatablesHelper
|
|
84
58
|
end
|
85
59
|
end
|
86
60
|
|
87
|
-
def
|
88
|
-
|
61
|
+
def render_simple_datatable(datatable)
|
62
|
+
raise 'expected datatable to be present' unless datatable
|
63
|
+
|
64
|
+
datatable.view ||= self
|
65
|
+
|
66
|
+
unless EffectiveDatatables.authorized?(controller, :index, datatable.collection_class)
|
67
|
+
return content_tag(:p, "You are not authorized to view this datatable. (cannot :index, #{datatable.collection_class})")
|
68
|
+
end
|
69
|
+
|
70
|
+
effective_datatable_params = {
|
71
|
+
id: datatable.to_param,
|
72
|
+
class: ('effective-datatable simple ' + Array(datatable.table_html_class).join(' ')),
|
73
|
+
data: {}
|
74
|
+
}
|
75
|
+
|
76
|
+
render(partial: 'effective/datatables/datatable',
|
77
|
+
locals: { datatable: datatable, effective_datatable_params: effective_datatable_params }
|
78
|
+
)
|
89
79
|
end
|
90
80
|
|
91
|
-
def
|
92
|
-
|
81
|
+
def render_datatable_filters(datatable)
|
82
|
+
raise 'expected datatable to be present' unless datatable
|
83
|
+
|
84
|
+
datatable.view ||= self
|
85
|
+
return unless datatable._scopes.present? || datatable._filters.present?
|
86
|
+
|
87
|
+
if datatable._filters_form_required?
|
88
|
+
render partial: 'effective/datatables/filters', locals: { datatable: datatable }
|
89
|
+
else
|
90
|
+
render(partial: 'effective/datatables/filters', locals: { datatable: datatable }).gsub('<form', '<div').gsub('/form>', '/div>').html_safe
|
91
|
+
end
|
92
|
+
|
93
93
|
end
|
94
94
|
|
95
|
-
def
|
96
|
-
|
95
|
+
def render_datatable_charts(datatable)
|
96
|
+
raise 'expected datatable to be present' unless datatable
|
97
|
+
|
98
|
+
datatable.view ||= self
|
99
|
+
return unless datatable._charts.present?
|
100
|
+
|
101
|
+
datatable._charts.map { |name, _| render_datatable_chart(datatable, name) }.join.html_safe
|
97
102
|
end
|
98
103
|
|
99
|
-
def
|
100
|
-
|
101
|
-
return @_inline_datatable if @_inline_datatable
|
104
|
+
def render_datatable_chart(datatable, name)
|
105
|
+
raise 'expected datatable to be present' unless datatable
|
102
106
|
|
103
|
-
datatable
|
104
|
-
datatable.
|
107
|
+
datatable.view ||= self
|
108
|
+
return unless datatable._charts[name].present?
|
105
109
|
|
106
|
-
|
110
|
+
chart = datatable._charts[name]
|
111
|
+
chart_data = datatable.to_json[:charts][name][:data]
|
107
112
|
|
108
|
-
|
113
|
+
render partial: chart[:partial], locals: { datatable: datatable, chart: chart, chart_data: chart_data }
|
109
114
|
end
|
110
115
|
|
111
116
|
end
|
@@ -1,21 +1,18 @@
|
|
1
1
|
# These aren't expected to be called by a developer. They are internal methods.
|
2
|
-
# These aren't expected to be called by a developer. They are internal methods.
|
3
2
|
module EffectiveDatatablesPrivateHelper
|
4
3
|
|
5
4
|
# https://datatables.net/reference/option/columns
|
6
5
|
def datatable_columns(datatable)
|
7
|
-
sortable = datatable.sortable?
|
8
|
-
|
9
6
|
datatable.columns.map do |name, opts|
|
10
7
|
{
|
11
|
-
className: opts[:col_class],
|
12
8
|
name: name,
|
9
|
+
title: content_tag(:span, opts[:label].presence),
|
10
|
+
className: opts[:col_class],
|
13
11
|
responsivePriority: opts[:responsive],
|
14
12
|
search: datatable.state[:search][name],
|
15
13
|
searchHtml: datatable_search_tag(datatable, name, opts),
|
16
|
-
sortable: (opts[:sort] &&
|
17
|
-
|
18
|
-
visible: datatable.state[:visible][name]
|
14
|
+
sortable: (opts[:sort] && !datatable.simple?),
|
15
|
+
visible: datatable.state[:visible][name],
|
19
16
|
}
|
20
17
|
end.to_json.html_safe
|
21
18
|
end
|
@@ -26,207 +23,78 @@ module EffectiveDatatablesPrivateHelper
|
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
29
|
-
def datatable_display_order(datatable)
|
30
|
-
(datatable.sortable? ? [datatable.order_index, datatable.order_direction] : false).to_json.html_safe
|
31
|
-
end
|
32
|
-
|
33
26
|
def datatable_reset(datatable)
|
34
|
-
link_to(content_tag(:span,
|
35
|
-
end
|
36
|
-
|
37
|
-
def datatable_reorder(datatable)
|
38
|
-
return unless datatable.reorder? && EffectiveDatatables.authorized?(self, :update, datatable.collection_class)
|
39
|
-
link_to(content_tag(:span, t('effective_datatables.reorder')), '#', class: 'btn btn-link btn-sm buttons-reorder', disabled: true)
|
40
|
-
end
|
41
|
-
|
42
|
-
def datatable_new_resource_button(datatable, name, column)
|
43
|
-
return unless column[:inline] && (column[:actions][:new] != false)
|
44
|
-
|
45
|
-
action = { action: :new, class: ['btn', column[:btn_class].presence].compact.join(' '), 'data-remote': true }
|
46
|
-
|
47
|
-
if column[:actions][:new].kind_of?(Hash) # This might be active_record_array_collection?
|
48
|
-
action = action.merge(column[:actions][:new])
|
49
|
-
|
50
|
-
effective_resource = (datatable.effective_resource || datatable.fallback_effective_resource)
|
51
|
-
klass = (column[:actions][:new][:klass] || effective_resource.try(:klass) || datatable.collection_class)
|
52
|
-
elsif Array(datatable.effective_resource.try(:actions)).include?(:new)
|
53
|
-
effective_resource = datatable.effective_resource
|
54
|
-
klass = effective_resource.klass
|
55
|
-
else
|
56
|
-
return
|
57
|
-
end
|
58
|
-
|
59
|
-
# Will only work if permitted
|
60
|
-
render_resource_actions(klass, actions: { t('effective_datatables.new') => action }, effective_resource: effective_resource)
|
61
|
-
end
|
62
|
-
|
63
|
-
def datatable_label_tag(datatable, name, opts)
|
64
|
-
case opts[:as]
|
65
|
-
when :actions
|
66
|
-
content_tag(:span, t('effective_datatables.actions'), style: 'display: none;')
|
67
|
-
when :bulk_actions
|
68
|
-
content_tag(:span, t('effective_datatables.bulk_actions'), style: 'display: none;')
|
69
|
-
when :reorder
|
70
|
-
content_tag(:span, t('effective_datatables.reorder'), style: 'display: none;')
|
71
|
-
else
|
72
|
-
content_tag(:span, opts[:label].presence)
|
73
|
-
end
|
27
|
+
link_to(content_tag(:span, 'Reset'), '#', class: 'btn btn-link btn-sm buttons-reset-search')
|
74
28
|
end
|
75
29
|
|
76
30
|
def datatable_search_tag(datatable, name, opts)
|
77
|
-
return datatable_new_resource_button(datatable, name, opts) if name == :_actions
|
78
|
-
|
79
31
|
return if opts[:search] == false
|
80
32
|
|
81
33
|
# Build the search
|
82
|
-
@_effective_datatables_form_builder ||
|
34
|
+
@_effective_datatables_form_builder || effective_form_with(scope: :datatable_search, url: '#') { |f| @_effective_datatables_form_builder = f }
|
83
35
|
form = @_effective_datatables_form_builder
|
84
36
|
|
85
|
-
include_blank = opts[:search].key?(:include_blank) ? opts[:search][:include_blank] : opts[:label]
|
86
|
-
pattern = opts[:search][:pattern]
|
87
|
-
placeholder = opts[:search][:placeholder] || ''
|
88
|
-
title = opts[:search][:title] || opts[:label]
|
89
|
-
wrapper_html = { class: 'datatable_search' }
|
90
|
-
|
91
37
|
collection = opts[:search].delete(:collection)
|
92
38
|
value = datatable.state[:search][name]
|
93
39
|
|
94
|
-
|
40
|
+
options = opts[:search].except(:fuzzy).merge!(
|
95
41
|
name: nil,
|
42
|
+
feedback: false,
|
43
|
+
label: false,
|
96
44
|
value: value,
|
97
|
-
|
98
|
-
|
99
|
-
data: {'column-name' => name, 'column-index' => opts[:index]}
|
100
|
-
}.delete_if { |k, v| v.blank? && k != :name }
|
45
|
+
data: { 'column-name': name, 'column-index': opts[:index] }
|
46
|
+
)
|
101
47
|
|
102
|
-
case
|
48
|
+
case options.delete(:as)
|
103
49
|
when :string, :text, :number
|
104
|
-
form.
|
105
|
-
as: :string,
|
106
|
-
placeholder: placeholder,
|
107
|
-
wrapper_html: wrapper_html,
|
108
|
-
input_html: input_html
|
109
|
-
when :effective_obfuscation
|
110
|
-
input_html[:pattern] ||= '[0-9]{3}-?[0-9]{4}-?[0-9]{3}'
|
111
|
-
input_html[:title] = 'Expected format: XXX-XXXX-XXX'
|
112
|
-
|
113
|
-
form.input name, label: false, required: false, value: value,
|
114
|
-
as: :string,
|
115
|
-
placeholder: placeholder,
|
116
|
-
wrapper_html: wrapper_html,
|
117
|
-
input_html: input_html
|
50
|
+
form.text_field name, options
|
118
51
|
when :date, :datetime
|
119
|
-
form.
|
120
|
-
|
121
|
-
|
122
|
-
wrapper_html: wrapper_html,
|
123
|
-
input_group: false,
|
124
|
-
input_html: input_html,
|
125
|
-
date_linked: false,
|
126
|
-
input_js: { useStrict: true, keepInvalid: true }
|
127
|
-
# Keep invalid format like "2015-11" so we can still search by year, month or day
|
52
|
+
form.date_field name, options.reverse_merge(
|
53
|
+
date_linked: false, prepend: false, input_js: { useStrict: true, keepInvalid: true }
|
54
|
+
)
|
128
55
|
when :time
|
129
|
-
form.
|
130
|
-
|
131
|
-
|
132
|
-
wrapper_html: wrapper_html,
|
133
|
-
input_group: false,
|
134
|
-
input_html: input_html,
|
135
|
-
date_linked: false,
|
136
|
-
input_js: { useStrict: false, keepInvalid: true }
|
56
|
+
form.time_field name, options.reverse_merge(
|
57
|
+
date_linked: false, prepend: false, input_js: { useStrict: false, keepInvalid: true }
|
58
|
+
)
|
137
59
|
when :select, :boolean
|
138
|
-
|
139
|
-
|
140
|
-
collection: collection,
|
141
|
-
selected: opts[:search][:value],
|
142
|
-
multiple: opts[:search][:multiple],
|
143
|
-
grouped: opts[:search][:grouped],
|
144
|
-
polymorphic: opts[:search][:polymorphic],
|
145
|
-
template: opts[:search][:template],
|
146
|
-
include_blank: include_blank,
|
147
|
-
wrapper_html: wrapper_html,
|
148
|
-
input_html: input_html,
|
149
|
-
input_js: { placeholder: placeholder }
|
60
|
+
options[:input_js] = (options[:input_js] || {}).reverse_merge(placeholder: '')
|
61
|
+
form.select name, collection, options
|
150
62
|
when :bulk_actions
|
151
|
-
|
152
|
-
|
153
|
-
form.input name, label: false, required: false, value: nil,
|
154
|
-
as: :boolean,
|
155
|
-
input_html: input_html
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
def render_datatable_filters(datatable)
|
160
|
-
raise 'expected datatable to be present' unless datatable
|
161
|
-
|
162
|
-
datatable.view ||= self
|
163
|
-
return unless datatable._scopes.present? || datatable._filters.present?
|
164
|
-
|
165
|
-
if datatable._filters_form_required?
|
166
|
-
render partial: 'effective/datatables/filters', locals: { datatable: datatable }
|
167
|
-
else
|
168
|
-
render(partial: 'effective/datatables/filters', locals: { datatable: datatable }).gsub('<form', '<div').gsub('/form>', '/div>').html_safe
|
63
|
+
options[:data]['role'] = 'bulk-actions-all'
|
64
|
+
form.check_box name, options.merge(custom: false)
|
169
65
|
end
|
170
|
-
|
171
66
|
end
|
172
67
|
|
173
68
|
def datatable_filter_tag(form, datatable, name, opts)
|
174
|
-
|
69
|
+
placeholder = opts.delete(:label)
|
70
|
+
|
71
|
+
collection = opts.delete(:collection)
|
175
72
|
value = datatable.state[:filter][name]
|
176
|
-
collection = opts[:collection]
|
177
|
-
input_html = opts[:input_html] || {}
|
178
73
|
|
179
|
-
|
74
|
+
options = opts.except(:parse).merge(
|
75
|
+
placeholder: placeholder,
|
76
|
+
feedback: false,
|
77
|
+
label: false,
|
180
78
|
value: value,
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
label: opts[:label],
|
185
|
-
required: input_html.delete(:required) || opts[:required],
|
186
|
-
multiple: input_html.delete(:multiple) || opts[:multiple],
|
187
|
-
include_blank: input_html.delete(:include_blank) || opts[:include_blank],
|
188
|
-
group_method: input_html.delete(:group_method),
|
189
|
-
group_label_method: input_html.delete(:group_label_method),
|
190
|
-
value_method: input_html.delete(:value_method),
|
191
|
-
label_method: input_html.delete(:label_method),
|
192
|
-
input_html: (({name: ''} unless datatable._filters_form_required?) || {}).merge(input_html),
|
193
|
-
input_js: ({ placeholder: ''} if as == :effective_select),
|
194
|
-
wrapper_html: {class: 'form-group-sm'}
|
195
|
-
}.compact
|
196
|
-
|
197
|
-
form.input name, **attributes
|
198
|
-
end
|
199
|
-
|
200
|
-
def datatable_scope_tag(form, datatable, opts = {})
|
201
|
-
collection = datatable._scopes.map { |name, opts| [opts[:label], name] }
|
202
|
-
value = datatable.state[:scope]
|
79
|
+
wrapper: { class: 'form-group col-auto'},
|
80
|
+
autocomplete: 'off'
|
81
|
+
)
|
203
82
|
|
204
|
-
|
205
|
-
as: (defined?(EffectiveFormInputs) ? :effective_radio_buttons : :radio_buttons),
|
206
|
-
collection: collection,
|
207
|
-
buttons: true,
|
208
|
-
wrapper_html: {class: 'btn-group-sm'}
|
209
|
-
end
|
210
|
-
|
211
|
-
def render_datatable_charts(datatable)
|
212
|
-
raise 'expected datatable to be present' unless datatable
|
213
|
-
|
214
|
-
datatable.view ||= self
|
215
|
-
return unless datatable._charts.present?
|
216
|
-
|
217
|
-
datatable._charts.map { |name, _| render_datatable_chart(datatable, name) }.join.html_safe
|
218
|
-
end
|
219
|
-
|
220
|
-
def render_datatable_chart(datatable, name)
|
221
|
-
raise 'expected datatable to be present' unless datatable
|
83
|
+
options[:name] = '' unless datatable._filters_form_required?
|
222
84
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
85
|
+
case options.delete(:as)
|
86
|
+
when :date
|
87
|
+
form.date_field name, options
|
88
|
+
when :datetime
|
89
|
+
form.datetime_field name, options
|
90
|
+
when :time
|
91
|
+
form.time_field name, options
|
92
|
+
when :select, :boolean
|
93
|
+
options[:input_js] = (options[:input_js] || {}).reverse_merge(placeholder: placeholder)
|
94
|
+
form.select name, collection, options
|
95
|
+
else
|
96
|
+
form.text_field name, options
|
97
|
+
end
|
230
98
|
end
|
231
99
|
|
232
100
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Effective
|
2
2
|
class Datatable
|
3
3
|
attr_reader :attributes # Anything that we initialize our table with. That's it. Can't be changed by state.
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :resource
|
5
5
|
attr_reader :state
|
6
6
|
|
7
7
|
# Hashes of DSL options
|
@@ -15,8 +15,6 @@ module Effective
|
|
15
15
|
|
16
16
|
# The collection itself. Only evaluated once.
|
17
17
|
attr_accessor :_collection
|
18
|
-
attr_accessor :_collection_apply_belongs_to
|
19
|
-
attr_accessor :_collection_apply_scope
|
20
18
|
|
21
19
|
# The view
|
22
20
|
attr_reader :view
|
@@ -33,10 +31,10 @@ module Effective
|
|
33
31
|
include Effective::EffectiveDatatable::Resource
|
34
32
|
include Effective::EffectiveDatatable::State
|
35
33
|
|
36
|
-
def initialize(view = nil, attributes =
|
34
|
+
def initialize(view = nil, attributes = {})
|
37
35
|
(attributes = view; view = nil) if view.kind_of?(Hash)
|
38
36
|
|
39
|
-
@attributes = (attributes
|
37
|
+
@attributes = initial_attributes(attributes)
|
40
38
|
@state = initial_state
|
41
39
|
|
42
40
|
@_aggregates = {}
|
@@ -47,7 +45,6 @@ module Effective
|
|
47
45
|
@_form = {}
|
48
46
|
@_scopes = {}
|
49
47
|
|
50
|
-
raise 'expected a hash of arguments' unless @attributes.kind_of?(Hash)
|
51
48
|
raise 'collection is defined as a method. Please use the collection do ... end syntax.' unless collection.nil?
|
52
49
|
self.view = view if view
|
53
50
|
end
|
@@ -57,23 +54,21 @@ module Effective
|
|
57
54
|
@view = (view.respond_to?(:view_context) ? view.view_context : view)
|
58
55
|
raise 'expected view to respond to params' unless @view.respond_to?(:params)
|
59
56
|
|
60
|
-
|
57
|
+
load_cookie!
|
61
58
|
load_attributes!
|
62
59
|
|
63
60
|
# We need early access to filter and scope, to define defaults from the model first
|
64
|
-
# This means filters do
|
61
|
+
# This means filters do knows about attributes but not about columns.
|
65
62
|
initialize_filters if respond_to?(:initialize_filters)
|
66
63
|
load_filters!
|
67
64
|
load_state!
|
68
65
|
|
69
|
-
# Bulk actions called first so it can add the bulk_actions_col first
|
70
|
-
initialize_bulk_actions if respond_to?(:initialize_bulk_actions)
|
71
|
-
|
72
66
|
# Now we initialize all the columns. columns knows about attributes and filters and scope
|
73
67
|
initialize_datatable if respond_to?(:initialize_datatable)
|
74
68
|
load_columns!
|
75
69
|
|
76
70
|
# Execute any additional DSL methods
|
71
|
+
initialize_bulk_actions if respond_to?(:initialize_bulk_actions)
|
77
72
|
initialize_charts if respond_to?(:initialize_charts)
|
78
73
|
|
79
74
|
# Load the collection. This is the first time def collection is called on the Datatable itself
|
@@ -83,10 +78,9 @@ module Effective
|
|
83
78
|
# Figure out the class, and if it's activerecord, do all the resource discovery on it
|
84
79
|
load_resource!
|
85
80
|
|
86
|
-
#
|
87
|
-
|
81
|
+
# If attributes match a belongs_to column, scope the collection and remove the column
|
82
|
+
apply_belongs_to_attributes!
|
88
83
|
|
89
|
-
# Save for next time
|
90
84
|
save_cookie!
|
91
85
|
end
|
92
86
|
|
@@ -123,18 +117,11 @@ module Effective
|
|
123
117
|
)
|
124
118
|
end
|
125
119
|
|
126
|
-
#
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
# Reordering
|
132
|
-
def reorder?
|
133
|
-
columns.key?(:_reorder)
|
134
|
-
end
|
135
|
-
|
136
|
-
def sortable?
|
137
|
-
!reorder? && attributes[:sortable] != false
|
120
|
+
# When simple only a table will be rendered with
|
121
|
+
# no sorting, no filtering, no export buttons, no pagination, no per page, no colReorder
|
122
|
+
# default sorting only, default visibility only, all records returned, and responsive enabled
|
123
|
+
def simple?
|
124
|
+
attributes[:simple] == true
|
138
125
|
end
|
139
126
|
|
140
127
|
# Whether the filters must be rendered as a <form> or we can keep the normal <div> behaviour
|
@@ -142,12 +129,12 @@ module Effective
|
|
142
129
|
_form[:verb].present?
|
143
130
|
end
|
144
131
|
|
145
|
-
def
|
146
|
-
|
132
|
+
def table_html_class
|
133
|
+
attributes[:class] || EffectiveDatatables.html_class
|
147
134
|
end
|
148
135
|
|
149
136
|
def to_param
|
150
|
-
"#{self.class.name.underscore.parameterize}-#{
|
137
|
+
@to_param ||= "#{self.class.name.underscore.parameterize}-#{cookie_param}"
|
151
138
|
end
|
152
139
|
|
153
140
|
def columns
|
@@ -162,14 +149,6 @@ module Effective
|
|
162
149
|
@dsl_tool ||= DatatableDslTool.new(self)
|
163
150
|
end
|
164
151
|
|
165
|
-
def resource
|
166
|
-
raise('depecated. Please use .effective_resource instead')
|
167
|
-
end
|
168
|
-
|
169
|
-
def fallback_effective_resource
|
170
|
-
@fallback_effective_resource ||= Effective::Resource.new('', namespace: controller_namespace)
|
171
|
-
end
|
172
|
-
|
173
152
|
private
|
174
153
|
|
175
154
|
def column_tool
|
@@ -180,12 +159,5 @@ module Effective
|
|
180
159
|
@value_tool ||= DatatableValueTool.new(self)
|
181
160
|
end
|
182
161
|
|
183
|
-
def validate_datatable!
|
184
|
-
if reorder?
|
185
|
-
raise 'cannot use reorder with an Array collection' unless active_record_collection?
|
186
|
-
raise 'cannot use reorder with a non-Integer column' if effective_resource.sql_type(columns[:_reorder][:reorder]) != :integer
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
162
|
end
|
191
163
|
end
|