effective_datatables 2.10.0 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +43 -0
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee +4 -3
- data/app/models/effective/datatable.rb +26 -18
- data/app/models/effective/effective_datatable/dsl/scopes.rb +6 -1
- data/app/models/effective/effective_datatable/options.rb +38 -2
- data/app/models/effective/effective_datatable/rendering.rb +3 -3
- data/app/views/effective/datatables/_scopes.html.haml +7 -1
- data/lib/effective_datatables/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5055d945bd4b6b8226f2841e55b02485199622b
|
4
|
+
data.tar.gz: 4c4f45643a7eb2918c5347c0961303fd6e53ec86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfbfcd41cce3993fde4ccf3898a2cfd48d5651b7a6322a4aa6f96443c4fe03555a94b58274653b9d8a5a31aa535b9ae7ba21bf8bdd32338f6e4e3d251320c948
|
7
|
+
data.tar.gz: a7c027feb2545b7aed6363f7490eafc57291fa7804394e42ccdc589a0c1229f1788a3428a8ddf2102b9d519c257055ab425cbabeaaae6d12cb6648f78360d0a4
|
data/README.md
CHANGED
@@ -569,6 +569,35 @@ Pass `scope :start_date, Time.zone.now-3.months, fallback: true` to fallback to
|
|
569
569
|
|
570
570
|
Any `filter: { ... }` options will be passed straight into simple_form.
|
571
571
|
|
572
|
+
### current_scope / model scopes
|
573
|
+
|
574
|
+
You can also use scopes as defined on your ActiveRecord model
|
575
|
+
|
576
|
+
When a scope is passed like follows, without a default value, it is assumed to be a klass level scope:
|
577
|
+
|
578
|
+
```ruby
|
579
|
+
scopes do
|
580
|
+
scope :all
|
581
|
+
scope :standard, default: true
|
582
|
+
scope :extended
|
583
|
+
scope :archived
|
584
|
+
end
|
585
|
+
|
586
|
+
def collection
|
587
|
+
collection = Post.all
|
588
|
+
collection = collection.send(current_scope) if current_scope
|
589
|
+
collection
|
590
|
+
end
|
591
|
+
```
|
592
|
+
|
593
|
+
The front end will render these klass scopes as a radio buttons / button group.
|
594
|
+
|
595
|
+
To determine which scope is selected, you can call `current_scope` or `attributes[:current_scope]` or `attributes[:standard]`
|
596
|
+
|
597
|
+
When no scopes are selected, and no defaults are present, the above will return nil.
|
598
|
+
|
599
|
+
It's a bit confusing, but you can mix and match these with regular attribute scopes.
|
600
|
+
|
572
601
|
## aggregates
|
573
602
|
|
574
603
|
Each `aggregate` directive adds an additional row to the table's tfoot.
|
@@ -847,6 +876,20 @@ def finalize(collection)
|
|
847
876
|
end
|
848
877
|
```
|
849
878
|
|
879
|
+
## Customize the datatables JS initializer
|
880
|
+
|
881
|
+
You can customize the initializer javascript passed to datatables.
|
882
|
+
|
883
|
+
The support for this is still pretty limitted.
|
884
|
+
|
885
|
+
```
|
886
|
+
= render_datatable(@datatable, {colReorder: false})
|
887
|
+
```
|
888
|
+
|
889
|
+
```
|
890
|
+
= render_datatable(@datatable, { buttons_export_columns: ':visible:not(.col-actions)' })
|
891
|
+
```
|
892
|
+
|
850
893
|
## Authorization
|
851
894
|
|
852
895
|
All authorization checks are handled via the config.authorization_method found in the `config/initializers/effective_datatables.rb` file.
|
@@ -5,6 +5,7 @@ initializeDataTables = ->
|
|
5
5
|
datatable = $(this)
|
6
6
|
simple = (datatable.data('simple') == true)
|
7
7
|
input_js_options = datatable.data('input-js-options') || {}
|
8
|
+
buttons_export_columns = input_js_options['buttons_export_columns'] || ':not(.col-actions)'
|
8
9
|
|
9
10
|
if input_js_options['buttons'] == false
|
10
11
|
input_js_options['buttons'] = []
|
@@ -26,21 +27,21 @@ initializeDataTables = ->
|
|
26
27
|
exportOptions:
|
27
28
|
format:
|
28
29
|
header: (str) -> $("<div>#{str}</div>").children('.filter-label').first().text()
|
29
|
-
columns:
|
30
|
+
columns: buttons_export_columns
|
30
31
|
},
|
31
32
|
{
|
32
33
|
extend: 'csv',
|
33
34
|
exportOptions:
|
34
35
|
format:
|
35
36
|
header: (str) -> $("<div>#{str}</div>").children('.filter-label').first().text()
|
36
|
-
columns:
|
37
|
+
columns: buttons_export_columns
|
37
38
|
},
|
38
39
|
{
|
39
40
|
extend: 'excel',
|
40
41
|
exportOptions:
|
41
42
|
format:
|
42
43
|
header: (str) -> $("<div>#{str}</div>").children('.filter-label').first().text()
|
43
|
-
columns:
|
44
|
+
columns: buttons_export_columns
|
44
45
|
},
|
45
46
|
{
|
46
47
|
extend: 'print',
|
@@ -22,13 +22,13 @@ module Effective
|
|
22
22
|
include Effective::EffectiveDatatable::Rendering
|
23
23
|
|
24
24
|
def initialize(*args)
|
25
|
-
if
|
26
|
-
|
27
|
-
args.first.each { |k, v| self.attributes[k] = v.presence }
|
25
|
+
if respond_to?(:initialize_scopes) # There was at least one scope defined in the scopes do .. end block
|
26
|
+
initialize_scopes
|
28
27
|
end
|
29
28
|
|
29
|
+
initialize_attributes(args)
|
30
|
+
|
30
31
|
if respond_to?(:initialize_scopes) # There was at least one scope defined in the scopes do .. end block
|
31
|
-
initialize_scopes
|
32
32
|
initialize_scope_options
|
33
33
|
end
|
34
34
|
|
@@ -59,6 +59,18 @@ module Effective
|
|
59
59
|
@scopes
|
60
60
|
end
|
61
61
|
|
62
|
+
def klass_scopes
|
63
|
+
scopes.select { |name, options| options[:klass_scope] }
|
64
|
+
end
|
65
|
+
|
66
|
+
def current_scope # The currently selected (klass) scope
|
67
|
+
attributes[:current_scope]
|
68
|
+
end
|
69
|
+
|
70
|
+
def permitted_params
|
71
|
+
scopes.keys + [:current_scope, :referer]
|
72
|
+
end
|
73
|
+
|
62
74
|
def charts
|
63
75
|
@charts
|
64
76
|
end
|
@@ -91,8 +103,8 @@ module Effective
|
|
91
103
|
raise "You must define a collection. Something like an ActiveRecord User.all or an Array of Arrays [[1, 'something'], [2, 'something else']]"
|
92
104
|
end
|
93
105
|
|
94
|
-
def collection_class
|
95
|
-
@collection_class
|
106
|
+
def collection_class # This is set by initialize_datatable_options()
|
107
|
+
@collection_class # Will be either User/Post/etc or Array
|
96
108
|
end
|
97
109
|
|
98
110
|
def to_json
|
@@ -121,7 +133,7 @@ module Effective
|
|
121
133
|
end
|
122
134
|
|
123
135
|
def total_records
|
124
|
-
@total_records ||= (active_record_collection? ? active_record_collection_size(
|
136
|
+
@total_records ||= (active_record_collection? ? active_record_collection_size(the_collection) : the_collection.size)
|
125
137
|
end
|
126
138
|
|
127
139
|
def view=(view_context)
|
@@ -144,7 +156,7 @@ module Effective
|
|
144
156
|
@view.class_eval { delegate helper_method, to: :@effective_datatable }
|
145
157
|
end
|
146
158
|
|
147
|
-
(self.class.instance_methods(false) - [:collection, :search_column, :order_column]).each do |view_method|
|
159
|
+
(self.class.instance_methods(false) - [:initialize_datatable, :collection, :search_column, :order_column]).each do |view_method|
|
148
160
|
@view.class_eval { delegate view_method, to: :@effective_datatable }
|
149
161
|
end
|
150
162
|
|
@@ -171,6 +183,10 @@ module Effective
|
|
171
183
|
|
172
184
|
protected
|
173
185
|
|
186
|
+
def the_collection
|
187
|
+
@memoized_collection ||= collection
|
188
|
+
end
|
189
|
+
|
174
190
|
def params
|
175
191
|
view.try(:params) || HashWithIndifferentAccess.new()
|
176
192
|
end
|
@@ -187,19 +203,11 @@ module Effective
|
|
187
203
|
# Check if collection has an order() clause and warn about it
|
188
204
|
# Usually that will make the table results look weird.
|
189
205
|
def active_record_collection?
|
190
|
-
|
191
|
-
@active_record_collection = (collection.ancestors.include?(ActiveRecord::Base) rescue false)
|
192
|
-
end
|
193
|
-
|
194
|
-
@active_record_collection
|
206
|
+
@active_record_collection == true
|
195
207
|
end
|
196
208
|
|
197
209
|
def array_collection?
|
198
|
-
|
199
|
-
@array_collection = (collection.kind_of?(Array) && collection.first.kind_of?(Array))
|
200
|
-
end
|
201
|
-
|
202
|
-
@array_collection
|
210
|
+
@array_collection == true
|
203
211
|
end
|
204
212
|
|
205
213
|
# Not every ActiveRecord query will work when calling the simple .count
|
@@ -3,12 +3,17 @@ module Effective
|
|
3
3
|
module Dsl
|
4
4
|
module Scopes
|
5
5
|
# Instance Methods inside the scopes do .. end block
|
6
|
-
def scope(name, default, options = {}, &block)
|
6
|
+
def scope(name, default = :klass_scope, options = {}, &block)
|
7
7
|
if block_given?
|
8
8
|
raise "You cannot use partial: ... with the block syntax" if options[:partial]
|
9
9
|
options[:block] = block
|
10
10
|
end
|
11
11
|
|
12
|
+
if default == :klass_scope || default == { default: true }
|
13
|
+
options[:klass_scope] = true
|
14
|
+
default = (default == :klass_scope ? nil : true)
|
15
|
+
end
|
16
|
+
|
12
17
|
# This needs to be a {} not WithIndifferentAccess or rendering _scopes won't work correctly
|
13
18
|
(@scopes ||= {})[name] = options.merge(default: default)
|
14
19
|
end
|
@@ -5,11 +5,16 @@ module Effective
|
|
5
5
|
module Options
|
6
6
|
|
7
7
|
def initialize_datatable_options
|
8
|
-
@table_columns = _initialize_datatable_options(@table_columns)
|
8
|
+
@table_columns = _initialize_datatable_options(@table_columns, the_collection)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize_attributes(args)
|
12
|
+
_initialize_attributes(args)
|
9
13
|
end
|
10
14
|
|
11
15
|
def initialize_scope_options
|
12
16
|
@scopes = _initialize_scope_options(@scopes)
|
17
|
+
_initialize_current_scope_attribute
|
13
18
|
end
|
14
19
|
|
15
20
|
def initialize_chart_options
|
@@ -22,6 +27,18 @@ module Effective
|
|
22
27
|
|
23
28
|
protected
|
24
29
|
|
30
|
+
def _initialize_attributes(args)
|
31
|
+
args.compact.each do |arg|
|
32
|
+
if arg.respond_to?(:permit) # ActionController::Parameters / Rails 5
|
33
|
+
arg = arg.permit(*permitted_params).to_h() # We permit only the scopes params
|
34
|
+
end
|
35
|
+
|
36
|
+
raise "#{self.class.name}.new() can only be initialized with a Hash like arguments" unless arg.kind_of?(Hash)
|
37
|
+
|
38
|
+
arg.each { |k, v| self.attributes[k] = v.presence }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
25
42
|
# The scope DSL is
|
26
43
|
# scope :start_date, default_value, options: {}
|
27
44
|
#
|
@@ -50,11 +67,30 @@ module Effective
|
|
50
67
|
end
|
51
68
|
end
|
52
69
|
|
70
|
+
def _initialize_current_scope_attribute
|
71
|
+
attributes[:current_scope] ||= klass_scopes.find { |name, options| options[:klass_scope] && options[:default] }.try(:first)
|
72
|
+
|
73
|
+
if attributes[:current_scope].present?
|
74
|
+
attributes[:current_scope] = attributes[:current_scope].to_sym
|
75
|
+
attributes[:current_scope] = nil unless klass_scopes.keys.include?(attributes[:current_scope])
|
76
|
+
end
|
77
|
+
|
78
|
+
if attributes[:current_scope].present?
|
79
|
+
klass_scopes.each { |name, _| attributes[name] = (name == attributes[:current_scope]) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
53
83
|
def _initialize_chart_options(charts)
|
54
84
|
charts
|
55
85
|
end
|
56
86
|
|
57
|
-
def _initialize_datatable_options(cols)
|
87
|
+
def _initialize_datatable_options(cols, collection)
|
88
|
+
# We set some memoized helper values
|
89
|
+
@collection_class = (collection.respond_to?(:klass) ? collection.klass : self.class)
|
90
|
+
@active_record_collection = (collection.ancestors.include?(ActiveRecord::Base) rescue false)
|
91
|
+
@array_collection = (collection.kind_of?(Array) && collection.first.kind_of?(Array))
|
92
|
+
|
93
|
+
# And then parse all the colums
|
58
94
|
sql_table = (collection.table rescue nil)
|
59
95
|
|
60
96
|
# Here we identify all belongs_to associations and build up a Hash like:
|
@@ -10,7 +10,7 @@ module Effective
|
|
10
10
|
# So the idea here is that we want to do as much as possible on the database in ActiveRecord
|
11
11
|
# And then run any array_columns through in post-processed results
|
12
12
|
def table_data
|
13
|
-
col =
|
13
|
+
col = the_collection
|
14
14
|
|
15
15
|
if active_record_collection?
|
16
16
|
col = table_tool.order(col)
|
@@ -32,14 +32,14 @@ module Effective
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
if
|
35
|
+
if col.kind_of?(Array)
|
36
36
|
col = array_tool.order(col)
|
37
37
|
col = array_tool.search(col)
|
38
38
|
end
|
39
39
|
|
40
40
|
self.display_records ||= total_records
|
41
41
|
|
42
|
-
if
|
42
|
+
if col.kind_of?(Array)
|
43
43
|
col = array_tool.paginate(col)
|
44
44
|
else
|
45
45
|
col = table_tool.paginate(col)
|
@@ -2,7 +2,13 @@
|
|
2
2
|
.col-sm-12.effective-datatable-scopes
|
3
3
|
= simple_form_for :scopes, url: request.path, method: :get, html: { class: 'form-inline' } do |form|
|
4
4
|
|
5
|
-
- datatable.
|
5
|
+
- if datatable.klass_scopes.present?
|
6
|
+
= form.input :current_scope, label: false, as: (defined?(EffectiveFormInputs) ? :effective_radio_buttons : :radio_buttons),
|
7
|
+
collection: datatable.klass_scopes.keys.map { |key| [key.to_s.titleize, key] },
|
8
|
+
checked: datatable.current_scope,
|
9
|
+
buttons: true
|
10
|
+
|
11
|
+
- datatable.scopes.except(*datatable.klass_scopes.keys).each do |name, options|
|
6
12
|
- if options[:block].present?
|
7
13
|
= form.instance_exec(form, &options[:block])
|
8
14
|
- elsif options[:partial].present?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_datatables
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|