effective_datatables 2.4.6 → 2.5.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: ac1937cf904292d69703161cb4421ff66e342a42
4
- data.tar.gz: b42cb1580452e1a46800769f87ee3a2b107b5925
3
+ metadata.gz: 698076a0613349e6b87650757f70464530e59933
4
+ data.tar.gz: 6ec43352f2160e31f382dcccfdc5091537f0fcdb
5
5
  SHA512:
6
- metadata.gz: 68dcd1719dae5c4406160279e27b36b9d24acb2c2b2bcf353aec79fcfcd7f378d03b6ad02c45030580dea565c85aa9dfe26402f94ee74dfac3e384550d11b232
7
- data.tar.gz: c7cf87f9d6232f53d10d14e3d543507773359ceca3945915a2f030738044470e5903e3c73cb48c1b1cf0a469001e06fe28c3612b6cdf475e248b79df7937f09b
6
+ metadata.gz: bf5374370d10c21eda392ea2db88460eeb676de33a7e6e3f0236940955aa6a7399e14c3bbc52c902d390df5f3154b567a443819752b0ec4b8c19610964bd3aee
7
+ data.tar.gz: 0dfdf316d031c7d34c2e2fa0b338d1dde5560375fb14bc9e319129dcc77e2d7845ce3004c276e9f3527dd0f3c760ab05bf302cf362f56b295b7d3637aeed4169
data/README.md CHANGED
@@ -537,6 +537,57 @@ resources :posts do
537
537
  end
538
538
  ```
539
539
 
540
+ ## scopes
541
+
542
+ When declaring a scope, a form field will automatically be placed above the datatable that can filter on the collection.
543
+
544
+ The value of the scope, its default value, will be available for use anywehre in your datatable via the `attributes` hash.
545
+
546
+ ```ruby
547
+ scope :start_date, Time.zone.now-3.months, filter: { input_html: { class: 'datepicker' } }
548
+ ```
549
+
550
+ and then in your collection, or any `table_column` block:
551
+
552
+ ```ruby
553
+ def collection
554
+ Post.where('updated_at > ?', attributes[:start_date])
555
+ end
556
+ ```
557
+
558
+ So initially, the `:start_date` will have the value of `Time.zone.now-3.months` and when submitted by the form, the value will be set there.
559
+
560
+ The form value will come back as a string, so you may need to `Time.zone.parse` that value.
561
+
562
+ Pass `scope :start_date, Time.zone.now-3.months, fallback: true` to fallback to the default value when the form submission is not present.
563
+
564
+ Any `filter: { ... }` options will be passed straight into simple_form.
565
+
566
+ ## aggregates
567
+
568
+ Each `aggregate` directive adds an additional row to the table's tfoot.
569
+
570
+ This feature is intended to display a sum or average of all the table's currently displayed values.
571
+
572
+ ```ruby
573
+ aggregate :average do |table_column, values, table_data|
574
+ if table_column[:name] == 'user'
575
+ 'Average'
576
+ else
577
+ average = (values.sum { |value| convert_to_column_type(table_column, value) } / [values.length, 1].max)
578
+ content_tag(:span, number_to_percentage(average, precision: 0))
579
+ end
580
+ end
581
+ ```
582
+
583
+ The above aggregate block will be called for each currently visible column in a datatable.
584
+
585
+ Here `table_column` is the table_column being rendered, `values` is an array of all the values in this one column. `table_data` is the whole transposed array of data.
586
+
587
+ The values will be whatever datatype each table_column returns.
588
+
589
+ It might be the case that the formatted values (strings) are returned, which is why `convert_to_column_type` is used above.
590
+
540
591
  ## table_columns
541
592
 
542
593
  Quickly create multiple table_columns all with default options:
@@ -26,21 +26,21 @@ initializeDataTables = ->
26
26
  exportOptions:
27
27
  format:
28
28
  header: (str) -> $("<div>#{str}</div>").children('.filter-label').first().text()
29
- columns: ':visible:not(.col-actions)'
29
+ columns: ':not(.col-actions)'
30
30
  },
31
31
  {
32
32
  extend: 'csv',
33
33
  exportOptions:
34
34
  format:
35
35
  header: (str) -> $("<div>#{str}</div>").children('.filter-label').first().text()
36
- columns: ':visible:not(.col-actions)'
36
+ columns: ':not(.col-actions)'
37
37
  },
38
38
  {
39
39
  extend: 'excel',
40
40
  exportOptions:
41
41
  format:
42
42
  header: (str) -> $("<div>#{str}</div>").children('.filter-label').first().text()
43
- columns: ':visible:not(.col-actions)'
43
+ columns: ':not(.col-actions)'
44
44
  },
45
45
  {
46
46
  extend: 'print',
@@ -69,12 +69,16 @@ initializeDataTables = ->
69
69
  pagingType: 'simple_numbers'
70
70
  initComplete: (settings) ->
71
71
  initializeBulkActions(this.api())
72
+ initializeScopes(this.api())
72
73
  initializeFilters(this.api())
73
74
  drawCallback: (settings) ->
74
75
  $table = $(this.api().table().node())
75
76
  selected = $table.data('bulk-actions-restore-selected-values')
76
77
  completeBulkAction($table, selected) if selected && selected.length > 0
77
78
 
79
+ if settings['json'] && settings['json']['aggregates']
80
+ drawAggregates($table, settings['json']['aggregates'])
81
+
78
82
  # Copies the bulk actions html, stored in a data attribute on the table, into the buttons area
79
83
  initializeBulkActions = (api) ->
80
84
  $table = $(api.table().node())
@@ -94,6 +98,22 @@ initializeDataTables = ->
94
98
  $wrapper.children().first().find('.buttons-bulk-actions').children('button').removeAttr('disabled')
95
99
  $table.siblings('.dataTables_processing').html('Processing...')
96
100
 
101
+ drawAggregates = ($table, aggregates) ->
102
+ $tfoot = $table.find('tfoot').first()
103
+
104
+ $.each aggregates, (row, values) =>
105
+ $row = $tfoot.children().eq(row)
106
+
107
+ if $row
108
+ $.each values, (col, value) => $row.children().eq(col).html(value)
109
+
110
+ # Appends the scope html
111
+ initializeScopes = (api) ->
112
+ $table = $(api.table().node())
113
+ scopes = $table.data('scopes')
114
+
115
+ $table.closest('.dataTables_wrapper').prepend(scopes['scopeHtml']) if scopes
116
+
97
117
  # Appends the filter html, stored in the column definitions, into each column header
98
118
  initializeFilters = (api) ->
99
119
  api.columns().flatten().each (index) =>
@@ -0,0 +1,3 @@
1
+ $(document).on 'click', 'a[data-reset-form]', (event) ->
2
+ event.preventDefault()
3
+ $(event.currentTarget).closest('form').trigger('reset')
@@ -17,6 +17,7 @@
17
17
 
18
18
  //= require effective_datatables/bulk_actions
19
19
  //= require effective_datatables/responsive
20
+ //= require effective_datatables/scopes
20
21
  //= require effective_datatables/initialize
21
22
 
22
23
  $.extend( $.fn.dataTable.defaults, {
@@ -49,7 +49,8 @@ table.dataTable.sort-hidden thead .sorting_desc { background-image: none; }
49
49
 
50
50
  // Filter bar
51
51
  table.dataTable .form-group { width: 100%; margin-left: 0px; margin-right: 0px; }
52
- table.dataTable input,select { width: 100%; }
52
+ table.dataTable input { width: 100%; }
53
+ table.dataTable select { width: 100%; }
53
54
  table.dataTable .form-control { width: 100%; }
54
55
  table.dataTable .form-group.datatable_filter_bulk_actions { margin-left: 4px; }
55
56
 
@@ -51,6 +51,17 @@ module EffectiveDatatablesHelper
51
51
  }.to_json()
52
52
  end
53
53
 
54
+ def datatable_scopes(datatable)
55
+ return false unless datatable.scopes.present?
56
+
57
+ {
58
+ scopeHtml: render(
59
+ partial: 'effective/datatables/scopes',
60
+ locals: HashWithIndifferentAccess.new(datatable: datatable)
61
+ )
62
+ }.to_json()
63
+ end
64
+
54
65
  def datatable_header_filter(form, name, value, opts)
55
66
  return render(partial: opts[:header_partial], locals: {form: form, name: (opts[:label] || name), column: opts}) if opts[:header_partial].present?
56
67
 
@@ -119,7 +130,6 @@ module EffectiveDatatablesHelper
119
130
  attributes[:active_admin_path] rescue false
120
131
  end
121
132
 
122
-
123
133
  ### Bulk Actions DSL Methods
124
134
  def bulk_action(*args)
125
135
  content_for(:effective_datatables_bulk_actions) { content_tag(:li, link_to(*args)) }
@@ -211,7 +211,7 @@ module Effective
211
211
  when :price
212
212
  price_in_cents = (term.gsub(/[^0-9|\.]/, '').to_f * 100.0).to_i
213
213
  collection.public_send(sql_op, "#{sql_column} = :term", term: price_in_cents)
214
- when :currency, :decimal, :number
214
+ when :currency, :decimal, :number, :percentage
215
215
  collection.public_send(sql_op, "#{sql_column} = :term", term: term.gsub(/[^0-9|\.]/, '').to_f)
216
216
  else
217
217
  collection.public_send(sql_op, "#{sql_column} = :term", term: term)
@@ -3,7 +3,7 @@ module Effective
3
3
  class ArrayDatatableTool
4
4
  attr_accessor :table_columns
5
5
 
6
- delegate :page, :per_page, :search_column, :order_column, :display_table_columns, :to => :@datatable
6
+ delegate :page, :per_page, :search_column, :order_column, :display_table_columns, :convert_to_column_type, :to => :@datatable
7
7
 
8
8
  def initialize(datatable, table_columns)
9
9
  @datatable = datatable
@@ -30,7 +30,7 @@ module Effective
30
30
  if direction == :asc
31
31
  collection.sort! do |x, y|
32
32
  if (x[index] && y[index])
33
- cast_array_column_value(table_column, x[index]) <=> cast_array_column_value(table_column, y[index])
33
+ convert_to_column_type(table_column, x[index]) <=> convert_to_column_type(table_column, y[index])
34
34
  elsif x[index]
35
35
  -1
36
36
  elsif y[index]
@@ -42,7 +42,7 @@ module Effective
42
42
  else
43
43
  collection.sort! do |x, y|
44
44
  if (x[index] && y[index])
45
- cast_array_column_value(table_column, y[index]) <=> cast_array_column_value(table_column, x[index])
45
+ convert_to_column_type(table_column, y[index]) <=> convert_to_column_type(table_column, x[index])
46
46
  elsif x[index]
47
47
  1
48
48
  elsif y[index]
@@ -70,7 +70,7 @@ module Effective
70
70
 
71
71
  collection.select! do |row|
72
72
  if table_column[:filter][:fuzzy]
73
- row[index].to_s.downcase.include?(search_term)
73
+ convert_to_column_type(table_column, row[index]).to_s.downcase.include?(search_term)
74
74
  else
75
75
  row[index] == search_term
76
76
  end
@@ -87,19 +87,6 @@ module Effective
87
87
  display_table_columns.present? ? display_table_columns.keys.index(column[:name]) : column[:array_index]
88
88
  end
89
89
 
90
- # When we order by Array, it's already a string.
91
- # This gives us a mechanism to sort numbers as numbers
92
- def cast_array_column_value(table_column, value)
93
- case table_column[:type]
94
- when :number, :price, :decimal, :float
95
- (value.to_s.gsub(/[^0-9|\.]/, '').to_f rescue 0.00)
96
- when :integer
97
- (value.to_s.gsub(/\D/, '').to_i rescue 0)
98
- else
99
- value
100
- end
101
- end
102
-
103
90
  end
104
91
  end
105
92
 
@@ -11,6 +11,7 @@ module Effective
11
11
  extend Effective::EffectiveDatatable::Dsl::ClassMethods
12
12
 
13
13
  include Effective::EffectiveDatatable::Ajax
14
+ include Effective::EffectiveDatatable::Helpers
14
15
  include Effective::EffectiveDatatable::Hooks
15
16
  include Effective::EffectiveDatatable::Options
16
17
  include Effective::EffectiveDatatable::Rendering
@@ -23,6 +24,7 @@ module Effective
23
24
 
24
25
  initialize_datatable # This creates @table_columns based on the DSL datatable do .. end block
25
26
  initialize_options # This normalizes all the options
27
+ initialize_scopes # This normalizes scopes, and copies scopes to attributes
26
28
 
27
29
  unless active_record_collection? || array_collection?
28
30
  raise "Unsupported collection type. Should be ActiveRecord class, ActiveRecord relation, or an Array of Arrays [[1, 'something'], [2, 'something else']]"
@@ -37,9 +39,17 @@ module Effective
37
39
  @table_columns
38
40
  end
39
41
 
42
+ def scopes
43
+ @scopes
44
+ end
45
+
46
+ def aggregates
47
+ @aggregates
48
+ end
49
+
40
50
  # Any attributes set on initialize will be echoed back and available to the class
41
51
  def attributes
42
- @attributes ||= HashWithIndifferentAccess.new()
52
+ @attributes ||= HashWithIndifferentAccess.new
43
53
  end
44
54
 
45
55
  def to_key; []; end # Searching & Filters
@@ -68,12 +78,17 @@ module Effective
68
78
  def to_json
69
79
  raise 'Effective::Datatable to_json called with a nil view. Please call render_datatable(@datatable) or @datatable.view = view before this method' unless view.present?
70
80
 
71
- @json ||= {
72
- :draw => (params[:draw] || 0),
73
- :data => (table_data || []),
74
- :recordsTotal => (total_records || 0),
75
- :recordsFiltered => (display_records || 0)
76
- }
81
+ @json ||= begin
82
+ data = table_data
83
+
84
+ {
85
+ :draw => (params[:draw] || 0),
86
+ :data => (data || []),
87
+ :recordsTotal => (total_records || 0),
88
+ :recordsFiltered => (display_records || 0),
89
+ :aggregates => (aggregate_data(data) || [])
90
+ }
91
+ end
77
92
  end
78
93
 
79
94
  def present?
@@ -104,6 +119,22 @@ module Effective
104
119
  @view = view_context
105
120
  @view.formats = [:html]
106
121
 
122
+ # Set any scopes
123
+ if @view.params[:scopes].kind_of?(Hash)
124
+ @view.params[:scopes].each do |name, value|
125
+ next unless scopes.key?(name)
126
+
127
+ if scopes[name][:fallback] || scopes[name][:presence]
128
+ value = value.presence || scopes[name][:default]
129
+ end
130
+
131
+ self.attributes[name] = value
132
+
133
+ self.scopes[name][:filter][:input_html] ||= HashWithIndifferentAccess.new
134
+ self.scopes[name][:filter][:input_html][:value] = value
135
+ end
136
+ end
137
+
107
138
  # 'Just work' with attributes
108
139
  @view.class.send(:attr_accessor, :attributes)
109
140
  @view.attributes = self.attributes
@@ -116,6 +147,10 @@ module Effective
116
147
  @view.class_eval { delegate view_method, :to => :@effective_datatable }
117
148
  end
118
149
 
150
+ Effective::EffectiveDatatable::Helpers.instance_methods(false).each do |helper_method|
151
+ @view.class_eval { delegate helper_method, :to => :@effective_datatable }
152
+ end
153
+
119
154
  # Clear the search_terms memoization
120
155
  @search_terms = nil
121
156
  @order_name = nil
@@ -27,7 +27,7 @@ module Effective
27
27
  end
28
28
  raise "You cannot use both partial: ... and proc: ..." if options[:partial] && options[:proc]
29
29
 
30
- (@table_columns ||= HashWithIndifferentAccess.new())[name] = options
30
+ (@table_columns ||= HashWithIndifferentAccess.new)[name] = options
31
31
  end
32
32
 
33
33
  def array_column(name, options = {}, proc = nil, &block)
@@ -72,6 +72,24 @@ module Effective
72
72
  table_column(name, opts, proc)
73
73
  end
74
74
 
75
+ def scope(name, default, options = {}, &block)
76
+ if block_given?
77
+ raise "You cannot use partial: ... with the block syntax" if options[:partial]
78
+ options[:block] = block
79
+ end
80
+
81
+ (@scopes ||= HashWithIndifferentAccess.new)[name] = options.merge(default: default)
82
+ end
83
+
84
+ def aggregate(name, options = {}, &block)
85
+ if block_given?
86
+ raise "You cannot use proc: ... with the block syntax" if options[:proc]
87
+ options[:block] = block
88
+ end
89
+
90
+ (@aggregates ||= HashWithIndifferentAccess.new)[name] = options
91
+ end
92
+
75
93
  end
76
94
  end
77
95
  end
@@ -0,0 +1,24 @@
1
+ module Effective
2
+ module EffectiveDatatable
3
+ module Helpers
4
+
5
+ # When we order by Array, it's already a string.
6
+ # This gives us a mechanism to sort numbers as numbers
7
+ def convert_to_column_type(table_column, value)
8
+ if value.html_safe? && value.kind_of?(String) && value.start_with?('<')
9
+ value = ActionView::Base.full_sanitizer.sanitize(value)
10
+ end
11
+
12
+ case table_column[:type]
13
+ when :number, :price, :decimal, :float, :percentage
14
+ (value.to_s.gsub(/[^0-9|\.]/, '').to_f rescue 0.00) unless value.kind_of?(Numeric)
15
+ when :integer
16
+ (value.to_s.gsub(/\D/, '').to_i rescue 0) unless value.kind_of?(Integer)
17
+ else
18
+ ; # Do nothing
19
+ end || value
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -8,12 +8,36 @@ module Effective
8
8
  @table_columns = initialize_column_options(@table_columns)
9
9
  end
10
10
 
11
+ def initialize_scopes
12
+ @scopes = initialize_scope_options(@scopes)
13
+ end
14
+
11
15
  def quote_sql(name)
12
16
  collection_class.connection.quote_column_name(name) rescue name
13
17
  end
14
18
 
15
19
  protected
16
20
 
21
+ # The scope DSL is
22
+ # scope :start_date, default_value, options {}
23
+
24
+ # A scope comes to us like {:start_date => {default: Time.zone.now, filter: {as: :select, collection: ... input_html :}}}
25
+ # We want to make sure an input_html: { value: default } exists
26
+ def initialize_scope_options(scopes)
27
+ (scopes || []).each do |name, options|
28
+ options[:filter] ||= HashWithIndifferentAccess.new()
29
+ options[:filter][:input_html] ||= HashWithIndifferentAccess.new()
30
+ options[:filter][:input_html][:value] = options[:default]
31
+ end
32
+
33
+ # For each scope, copy it into the attributes, so we can get at the value
34
+ (scopes || []).each do |name, options|
35
+ self.attributes[name] ||= options[:default]
36
+ end
37
+
38
+ scopes
39
+ end
40
+
17
41
  def initialize_column_options(cols)
18
42
  sql_table = (collection.table rescue nil)
19
43
 
@@ -81,8 +105,6 @@ module Effective
81
105
  :bulk_actions_column
82
106
  elsif name.include?('_address') && (collection_class.new rescue nil).respond_to?(:effective_addresses)
83
107
  :effective_address
84
- elsif name == 'id' || name.include?('year') || name.include?('_id')
85
- :non_formatted_integer
86
108
  elsif sql_column.try(:type).present?
87
109
  sql_column.type
88
110
  else
@@ -92,6 +114,11 @@ module Effective
92
114
 
93
115
  cols[name][:class] = "col-#{cols[name][:type]} col-#{name} #{cols[name][:class]}".strip
94
116
 
117
+ # Formats
118
+ if name == 'id' || name.include?('year') || name.include?('_id')
119
+ cols[name][:format] = :non_formatted_integer
120
+ end
121
+
95
122
  # We can't really sort a HasMany or EffectiveAddress field
96
123
  if [:has_many, :effective_address].include?(cols[name][:type])
97
124
  cols[name][:sortable] = false
@@ -137,7 +137,7 @@ module Effective
137
137
  obj.send(name)
138
138
  end
139
139
  rescue => e
140
- obj.try(:[], name)
140
+ Rails.env.production? ? obj.try(:[], name) : raise(e)
141
141
  end
142
142
  end
143
143
  end
@@ -154,7 +154,7 @@ module Effective
154
154
  row[index] = value.to_s
155
155
  end
156
156
 
157
- case opts[:type]
157
+ case (opts[:format] || opts[:type])
158
158
  when :belongs_to, :belongs_to_polymorphic
159
159
  row[index] = value.to_s
160
160
  when :has_many
@@ -183,6 +183,8 @@ module Effective
183
183
  row[index] = number_to_currency(value / 100.0)
184
184
  when :currency
185
185
  row[index] = number_to_currency(value || 0)
186
+ when :percentage
187
+ row[index] = number_to_percentage(value || 0)
186
188
  when :integer
187
189
  if EffectiveDatatables.integer_format.kind_of?(Symbol)
188
190
  row[index] = view.instance_exec { public_send(EffectiveDatatables.integer_format, value) }
@@ -206,6 +208,26 @@ module Effective
206
208
  collection
207
209
  end
208
210
 
211
+ # This should return an Array of values the same length as table_data
212
+ def aggregate_data(table_data)
213
+ return false unless aggregates.present?
214
+
215
+ values = table_data.transpose
216
+
217
+ aggregates.map do |name, options|
218
+ (display_table_columns || table_columns).map.with_index do |(name, column), index|
219
+
220
+ if column[:visible] != true
221
+ ''
222
+ elsif (options[:block] || options[:proc]).respond_to?(:call)
223
+ view.instance_exec(column, (values[index] || []), values, &(options[:block] || options[:proc]))
224
+ else
225
+ ''
226
+ end
227
+ end
228
+ end
229
+ end
230
+
209
231
  private
210
232
 
211
233
  def controller_namespace
@@ -7,6 +7,7 @@
7
7
  'bulk-actions' => datatable_bulk_actions(datatable),
8
8
  'columns' => datatable_columns(datatable),
9
9
  'input-js-options' => local_assigns[:input_js_options],
10
+ 'scopes' => datatable_scopes(datatable),
10
11
  'simple' => datatable.simple?.to_s,
11
12
  'source' => effective_datatables.datatable_path(datatable, {format: 'json'}.merge(attributes: datatable.attributes)).chomp('?'),
12
13
  'default-order' => datatable_default_order(datatable),
@@ -23,7 +24,14 @@
23
24
  %th= opts[:label] || name
24
25
 
25
26
  %tbody
26
- - (datatable.to_json[:data] || []).each do |row|
27
+ - datatable.to_json[:data].each do |row|
27
28
  %tr
28
29
  - row.each do |col|
29
30
  %td= col.to_s.html_safe
31
+
32
+ - if datatable.aggregates.present?
33
+ %tfoot
34
+ - datatable.to_json[:aggregates].each do |row|
35
+ %tr
36
+ - row.each do |col|
37
+ %td= col.to_s.html_safe
@@ -0,0 +1,15 @@
1
+ .row
2
+ .col-sm-12
3
+ = simple_form_for :scopes, url: request.path, method: :get, html: { class: 'form-inline' } do |form|
4
+
5
+ - datatable.scopes.each do |name, options|
6
+ - if options[:block].present?
7
+ = form.instance_exec(form, &options[:block])
8
+ - elsif options[:partial].present?
9
+ = render partial: options[:partial], locals: { form: form, f: form, datatable: datatable }
10
+ - else
11
+ = form.input name, options[:filter]
12
+
13
+ = form.submit 'Refresh', class: 'btn btn-primary', 'data-disable-with' => 'Refreshing...'
14
+ = link_to 'Reset', '#', 'data-reset-form' => true
15
+
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '2.4.6'.freeze
2
+ VERSION = '2.5.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.4.6
4
+ version: 2.5.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: 2016-06-13 00:00:00.000000000 Z
11
+ date: 2016-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -123,6 +123,7 @@ files:
123
123
  - app/assets/javascripts/effective_datatables/bulk_actions.js.coffee
124
124
  - app/assets/javascripts/effective_datatables/initialize.js.coffee
125
125
  - app/assets/javascripts/effective_datatables/responsive.js.coffee
126
+ - app/assets/javascripts/effective_datatables/scopes.js.coffee
126
127
  - app/assets/javascripts/vendor/jquery.debounce.min.js
127
128
  - app/assets/javascripts/vendor/jszip.min.js
128
129
  - app/assets/stylesheets/dataTables/buttons/buttons.bootstrap.min.css
@@ -143,6 +144,7 @@ files:
143
144
  - app/models/effective/datatable.rb
144
145
  - app/models/effective/effective_datatable/ajax.rb
145
146
  - app/models/effective/effective_datatable/dsl.rb
147
+ - app/models/effective/effective_datatable/helpers.rb
146
148
  - app/models/effective/effective_datatable/hooks.rb
147
149
  - app/models/effective/effective_datatable/options.rb
148
150
  - app/models/effective/effective_datatable/rendering.rb
@@ -150,6 +152,7 @@ files:
150
152
  - app/views/effective/datatables/_bulk_actions_column.html.haml
151
153
  - app/views/effective/datatables/_bulk_actions_dropdown.html.haml
152
154
  - app/views/effective/datatables/_datatable.html.haml
155
+ - app/views/effective/datatables/_scopes.html.haml
153
156
  - app/views/effective/datatables/_spacer_template.html
154
157
  - config/routes.rb
155
158
  - lib/effective_datatables.rb