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 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