effective_datatables 2.10.0 → 2.11.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 38df969bd8b6fe71d4e850119c2b65d8b961b858
4
- data.tar.gz: b89352ad871da29903b18d0f1693740edce96141
3
+ metadata.gz: f5055d945bd4b6b8226f2841e55b02485199622b
4
+ data.tar.gz: 4c4f45643a7eb2918c5347c0961303fd6e53ec86
5
5
  SHA512:
6
- metadata.gz: 1395f9861d1a4c806b3b1e21d618c6782e926d5f3e865d4e3060d99b7b0c56ae022afe50ab5381d940b196b51ec73c131104b1b92d2f5ffe7cbc353715fcefd8
7
- data.tar.gz: 0bc0b48bbfd87c9e09b09520e19b27b68608230f07f7baaad76eb9f446f83d158554f388d4c96b1b3488c035e2671dac3a498768693cc134263dbe4e2bf5997e
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: ':not(.col-actions)'
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: ':not(.col-actions)'
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: ':not(.col-actions)'
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 args.present? && args.first != nil
26
- raise "#{self.class.name}.new() can only be initialized with a Hash like arguments" unless args.first.kind_of?(Hash)
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 ||= (collection.respond_to?(:klass) ? collection.klass : self.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(collection) : 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
- if @active_record_collection == nil
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
- if @array_collection == nil
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 = collection
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 array_collection?
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 array_collection?
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.scopes.each do |name, options|
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?
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '2.10.0'.freeze
2
+ VERSION = '2.11.0'.freeze
3
3
  end
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.10.0
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-12 00:00:00.000000000 Z
11
+ date: 2017-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails