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 +4 -4
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee.erb +19 -5
- data/app/controllers/effective/datatables_controller.rb +1 -1
- data/app/helpers/effective_datatables_helper.rb +7 -2
- data/app/models/effective/active_record_datatable_tool.rb +16 -0
- data/app/models/effective/effective_datatable/ajax.rb +5 -6
- data/app/models/effective/effective_datatable/options.rb +40 -13
- data/app/models/effective/effective_datatable/rendering.rb +10 -16
- 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: eb195f3890afb3faee956495d534e0a1bb09013e
|
4
|
+
data.tar.gz: 8acf1b7ec6a347a3157718504f6830a001d0360c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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)
|
@@ -31,8 +31,13 @@ module EffectiveDatatablesHelper
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
form.input name, label: false, required: false,
|
35
|
-
|
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].
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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.
|
19
|
-
|
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
|
-
|
27
|
-
|
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]
|
49
|
-
cols[name][:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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.
|
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-
|
11
|
+
date: 2015-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|