effective_datatables 2.0.1 → 2.0.2

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: b7bd5fa4ae2a9aa6654ae6341bc6e324741c0387
4
- data.tar.gz: b14fdda1521d4046ffc94aaf3fa173ab8d42863c
3
+ metadata.gz: eb195f3890afb3faee956495d534e0a1bb09013e
4
+ data.tar.gz: 8acf1b7ec6a347a3157718504f6830a001d0360c
5
5
  SHA512:
6
- metadata.gz: 83d1fbcad25d8ae5b780efbc70b61c9b8bb2fca94bff5397c640567663efa892a3d0f240f10fc7c15b1781935c7f45df0d45218e4d1abc2cdefc3dbe0dbc38a4
7
- data.tar.gz: 96e02057d1cd10ca8c57b8adc8d6b182b3ec291b91cefcc32e1fa6a2bb7382b1fbcd0f04759b2db9c457b1d7f8e9dad8540003bdfbd7e71b02fb9d80d1d245c2
6
+ metadata.gz: d8cb8fc4dbb8f209bd2a5259e5c0f1594a5c1bb0a8dc763cbd0ae55b63b8194bb5ca96649fd0fbf5b4b97b6bec8cbc06fa8da7144e04d67aeb1c49fce52accfa
7
+ data.tar.gz: 4d9addc52f7eac6742137e29a967aa465a69bd2c4baadcbebbb248b6dcedf6eab3457819e8002447aaf729a59d1a631232ea646ec484bd4fbabd63ae9acd63e3
@@ -20,18 +20,30 @@ initializeDataTables = ->
20
20
  { sortable: false, targets: datatable.data('non-sortable') }
21
21
  ].concat(datatable.data('column-classes') || []).concat(datatable.data('column-names') || [])
22
22
  order: datatable.data('default-order')
23
+ serverParams: (params) ->
24
+ table = this.DataTable()
25
+ table.columns().flatten().each (index) => # Pass which columns are visible back to server
26
+ params['columns'][index]['visible'] = table.column(index).visible()
23
27
  colVis:
24
28
  showAll: 'Show all'
25
29
  restore: 'Show default'
26
30
  activate: 'click'
27
31
  align: 'right'
28
32
  label: (index, title, th) -> $(th).prop('title')
33
+ stateChange: (iCol, bVisible) ->
34
+ timeout = $(this.dom.button).data('timeout')
35
+ clearTimeout(timeout) if timeout
36
+ timeout = setTimeout(
37
+ =>
38
+ $(this.dom.button).closest('.dataTables_wrapper').find('table').first().DataTable().draw()
39
+ $.event.trigger('page:change')
40
+ , 1000)
41
+ $(this.dom.button).data('timeout', timeout)
29
42
  tableTools:
30
43
  sSwfPath: "<%= asset_path('effective_datatables/copy_csv_xls_pdf.swf') %>",
31
44
  aButtons: ['csv', {'sExtends': 'xls', 'sButtonText': 'Excel'}, 'print']
32
45
 
33
- simple = datatable.data('effective-datatables-table') == 'simple'
34
- if simple
46
+ if datatable.data('effective-datatables-table') == 'simple'
35
47
  init_options['lengthMenu'] = [-1] # Show all results
36
48
  init_options['dom'] = "<'row'r>t" # Just show the table
37
49
 
@@ -46,12 +58,14 @@ initializeDataTables = ->
46
58
  table.DataTable().column("#{obj.data('column-name')}:name").search(obj.val()).draw()
47
59
 
48
60
  # For every existing Input, Set up the search events
49
- (search_inputs = datatable.find('thead').first().find('input,select')).each (index, input) ->
61
+ search_inputs = datatable.find('thead').first().find('input,select')
62
+
63
+ search_inputs.each (index, input) ->
50
64
  $input = $(input)
51
65
 
52
66
  if $input.data('column-name')
53
- $input.on 'click', (event) -> false # Dont order columns when you click inside the input
54
- $input.on 'mousedown', (event) -> event.stopPropagation() # Dont order columns when you click inside the input
67
+ $input.parent().on 'click', (event) -> false # Dont order columns when you click inside the input
68
+ $input.parent().on 'mousedown', (event) -> event.stopPropagation() # Dont order columns when you click inside the input
55
69
 
56
70
  if $input.is('select')
57
71
  $input.on 'change', (event) -> dataTableSearch(event)
@@ -1,6 +1,6 @@
1
1
  module Effective
2
2
  class DatatablesController < ApplicationController
3
- skip_log_page_views if defined?(EffectiveLogging)
3
+ skip_log_page_views quiet: true if defined?(EffectiveLogging)
4
4
 
5
5
  # This will respond to both a GET and a POST
6
6
  def show
@@ -31,8 +31,13 @@ module EffectiveDatatablesHelper
31
31
  end
32
32
  end
33
33
 
34
- form.input name, label: false, required: false, as: :select, collection: opts[:filter][:values], include_blank: (opts[:label] || name.titleize),
35
- input_html: { name: nil, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} }
34
+ form.input name, label: false, required: false,
35
+ as: (defined?(EffectiveFormInputs) ? :effective_select : :select),
36
+ collection: opts[:filter][:values],
37
+ multiple: opts[:filter][:multiple] == true,
38
+ include_blank: (opts[:label] || name.titleize),
39
+ input_html: { name: nil, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
40
+ input_js: { placeholder: (opts[:label] || name.titleize) }
36
41
  else
37
42
  content_tag(:p, opts[:label] || name)
38
43
  end
@@ -46,6 +46,22 @@ module Effective
46
46
  else
47
47
  collection.where("#{column} ILIKE :term", term: "%#{term}%")
48
48
  end
49
+ when :has_many
50
+ inverse_ids = term.split(',').map { |term| (term = term.to_i) == 0 ? nil : term }.compact
51
+ return collection unless inverse_ids.present?
52
+
53
+ reflection = collection.klass.reflect_on_association(table_column[:name].to_sym)
54
+ raise "unable to find #{collection.klass.name} :has_many :#{table_column[:name]} association" unless reflection
55
+
56
+ obj = reflection.build_association({}) # Clinic
57
+ klass = obj.class
58
+
59
+ inverse = klass.reflect_on_association(collection.table_name) || obj.class.reflect_on_association(collection.table_name.singularize)
60
+ raise "unable to find #{klass.name} has_many :#{collection.table_name} or belongs_to :#{collection.table_name.singularize} associations" unless inverse
61
+
62
+ ids = klass.where(id: inverse_ids).joins(inverse.name).pluck(inverse.foreign_key)
63
+
64
+ collection.where(id: ids)
49
65
  when :datetime, :date
50
66
  begin
51
67
  digits = term.scan(/(\d+)/).flatten.map(&:to_i)
@@ -8,12 +8,11 @@ module Effective
8
8
  # It sends us a list of columns that are different than our table_columns order
9
9
  # So this method just returns an array of column names, as per ColReorder
10
10
  def display_table_columns
11
- if params[:columns].present?
12
- HashWithIndifferentAccess.new().tap do |display_columns|
13
- params[:columns].each do |_, values|
14
- display_columns[values[:name]] = table_columns[values[:name]]
15
- end
16
- end
11
+ return nil if params[:columns].blank?
12
+
13
+ @display_table_columns ||= params[:columns].each_with_object({}) do |(_, column), retval|
14
+ retval[column[:name]] = table_columns[column[:name]] # Same order as ColReordernow
15
+ retval[column[:name]][:visible] = (column[:visible] == 'true') # As per ColVis
17
16
  end
18
17
  end
19
18
 
@@ -15,20 +15,22 @@ module Effective
15
15
 
16
16
  # Here we identify all belongs_to associations and build up a Hash like:
17
17
  # {user: {foreign_key: 'user_id', klass: User}, order: {foreign_key: 'order_id', klass: Effective::Order}}
18
- belong_tos = (collection.ancestors.first.reflect_on_all_associations(:belongs_to) rescue []).inject(HashWithIndifferentAccess.new()) do |retval, bt|
19
- unless bt.options[:polymorphic]
20
- begin
21
- klass = bt.klass || bt.foreign_type.sub('_type', '').classify.constantize
22
- rescue => e
23
- klass = nil
24
- end
18
+ belong_tos = (collection.klass.reflect_on_all_associations(:belongs_to) rescue []).inject({}) do |retval, bt|
19
+ next if bt.options[:polymorphic]
25
20
 
26
- retval[bt.name] = {foreign_key: bt.foreign_key, klass: klass} if bt.foreign_key.present? && klass.present?
27
- end
21
+ klass = bt.klass || (bt.foreign_type.sub('_type', '').classify.constantize rescue nil)
22
+ retval[bt.name.to_s] = {foreign_key: bt.foreign_key, klass: klass} if bt.foreign_key.present? && klass.present?
28
23
 
29
24
  retval
30
25
  end
31
26
 
27
+ # has_manys
28
+ has_manys = (collection.klass.reflect_on_all_associations(:has_many) rescue []).inject({}) do |retval, hm|
29
+ klass = hm.klass || (hm.build_association({}).class)
30
+ retval[hm.name.to_s] = {klass: klass}
31
+ retval
32
+ end
33
+
32
34
  table_columns = cols.each_with_index do |(name, _), index|
33
35
  # If this is a belongs_to, add an :if clause specifying a collection scope if
34
36
  if belong_tos.key?(name)
@@ -45,10 +47,29 @@ module Effective
45
47
  cols[name][:label] ||= name.titleize
46
48
  cols[name][:column] ||= (sql_table && sql_column) ? "\"#{sql_table.name}\".\"#{sql_column.name}\"" : name
47
49
  cols[name][:width] ||= nil
48
- cols[name][:sortable] = true if cols[name][:sortable] == nil
49
- cols[name][:type] ||= (belong_tos.key?(name) ? :belongs_to : sql_column.try(:type).presence) || :string
50
+ cols[name][:sortable] = true if cols[name][:sortable].nil?
51
+ cols[name][:visible] = true if cols[name][:visible].nil?
52
+
53
+ # Type
54
+ cols[name][:type] ||= (
55
+ if belong_tos.key?(name)
56
+ :belongs_to
57
+ elsif has_manys.key?(name)
58
+ :has_many
59
+ elsif sql_column.try(:type).present?
60
+ sql_column.type
61
+ else
62
+ :string # When in doubt
63
+ end
64
+ )
65
+
50
66
  cols[name][:class] = "col-#{cols[name][:type]} col-#{name} #{cols[name][:class]}".strip
51
67
 
68
+ # HasMany
69
+ if cols[name][:type] == :has_many
70
+ cols[name][:sortable] = false
71
+ end
72
+
52
73
  # EffectiveObfuscation
53
74
  if name == 'id' && defined?(EffectiveObfuscation) && collection.respond_to?(:deobfuscate)
54
75
  cols[name][:sortable] = false
@@ -66,7 +87,7 @@ module Effective
66
87
  cols[name][:sql_as_column] = true
67
88
  end
68
89
 
69
- cols[name][:filter] = initialize_table_column_filter(cols[name][:filter], cols[name][:type], belong_tos[name])
90
+ cols[name][:filter] = initialize_table_column_filter(cols[name][:filter], cols[name][:type], belong_tos[name], has_manys[name])
70
91
 
71
92
  if cols[name][:partial]
72
93
  cols[name][:partial_local] ||= (sql_table.try(:name) || cols[name][:partial].split('/').last(2).first.presence || 'obj').singularize.to_sym
@@ -81,7 +102,7 @@ module Effective
81
102
 
82
103
  end
83
104
 
84
- def initialize_table_column_filter(filter, col_type, belongs_to)
105
+ def initialize_table_column_filter(filter, col_type, belongs_to, has_many)
85
106
  return {type: :null} if filter == false
86
107
 
87
108
  filter = {type: filter.to_sym} if filter.kind_of?(String)
@@ -96,6 +117,12 @@ module Effective
96
117
  type: :select,
97
118
  values: Proc.new { belongs_to[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[1] <=> y[1] } }
98
119
  }
120
+ when :has_many
121
+ {
122
+ type: :select,
123
+ multiple: true,
124
+ values: Proc.new { has_many[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[1] <=> y[1] } }
125
+ }
99
126
  when :effective_roles
100
127
  {type: :select, values: EffectiveRoles.roles}
101
128
  when :integer
@@ -59,8 +59,8 @@ module Effective
59
59
 
60
60
  # We want to use the render :collection for each column that renders partials
61
61
  rendered = {}
62
- table_columns.each do |name, opts|
63
- if opts[:partial]
62
+ (display_table_columns || table_columns).each do |name, opts|
63
+ if opts[:partial] && opts[:visible]
64
64
  locals = {
65
65
  datatable: self,
66
66
  table_column: table_columns[name],
@@ -84,14 +84,19 @@ module Effective
84
84
 
85
85
  collection.each_with_index.map do |obj, index|
86
86
  (display_table_columns || table_columns).map do |name, opts|
87
- value = if opts[:partial]
87
+ if opts[:visible] == false
88
+ ''
89
+ elsif opts[:partial]
88
90
  rendered[name][index]
89
91
  elsif opts[:block]
90
92
  view.instance_exec(obj, collection, self, &opts[:block])
91
93
  elsif opts[:proc]
92
94
  view.instance_exec(obj, collection, self, &opts[:proc])
93
95
  elsif opts[:type] == :belongs_to
94
- val = (obj.send(name) rescue nil).to_s
96
+ (obj.send(name) rescue nil).to_s
97
+ elsif opts[:type] == :has_many
98
+ objs = (obj.send(name).map(&:to_s).sort rescue [])
99
+ objs.length == 1 ? objs.first : (opts[:sentence] ? objs.to_sentence : objs.join('<br>'))
95
100
  elsif opts[:type] == :obfuscated_id
96
101
  (obj.send(:to_param) rescue nil).to_s
97
102
  elsif opts[:type] == :effective_roles
@@ -101,20 +106,9 @@ module Effective
101
106
  elsif opts[:type] == :date
102
107
  (obj.send(name).strftime(EffectiveDatatables.date_format) rescue nil)
103
108
  else
104
- val = (obj.send(name) rescue nil)
105
- val = (obj[opts[:array_index]] rescue nil) if val == nil
106
- val
109
+ obj.send(name) rescue (obj[opts[:array_index]] rescue nil)
107
110
  end
108
111
 
109
- # Last minute formatting of dates
110
- case value
111
- when Date
112
- value.strftime(EffectiveDatatables.date_format)
113
- when Time, DateTime
114
- value.strftime(EffectiveDatatables.datetime_format)
115
- else
116
- value.to_s
117
- end
118
112
  end
119
113
  end
120
114
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '2.0.1'.freeze
2
+ VERSION = '2.0.2'.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.0.1
4
+ version: 2.0.2
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: 2015-07-24 00:00:00.000000000 Z
11
+ date: 2015-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails