trk_datatables 0.1.2 → 0.1.3
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 +4 -4
- data/CHANGELOG.md +2 -0
- data/Gemfile.lock +1 -1
- data/lib/trk_datatables/active_record.rb +27 -24
- data/lib/trk_datatables/base.rb +32 -10
- data/lib/trk_datatables/dt_params.rb +9 -9
- data/lib/trk_datatables/preferences.rb +17 -24
- data/lib/trk_datatables/render_html.rb +4 -4
- data/lib/trk_datatables/version.rb +1 -1
- data/trk_datatables.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a02c05387d75bc6ec793abce56ca69ab8924d4aab84339fa04740dce0b00ebd
|
4
|
+
data.tar.gz: b983241edd1da7ed12438608591b8acdb96b4704df3bc54eb2193e42b408d5ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64fe2c03de96d9a0cf700c06a1b1bd2560190d6c14abefd066209280e165aab4eda90d0939bf0ee33befc2792fd4034b7be075fbadf1dd481fd9ecc9529adb42
|
7
|
+
data.tar.gz: 4b58ddb0471ea682dc5e3c1ca7e28051ac2f965d9687e01cdd1223038f52c7c47dcbfbdcf3959f687c3d3de5da529b9048277e27fae4d88e68844af7da457cb1
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -2,17 +2,17 @@ module TrkDatatables
|
|
2
2
|
class ActiveRecord < Base
|
3
3
|
# Global search. All columns are typecasted to string. Search string is
|
4
4
|
# splited by space and "and"-ed.
|
5
|
-
def filter_by_search_all(
|
5
|
+
def filter_by_search_all(filtered)
|
6
6
|
conditions = @dt_params.search_all.split(' ').map do |search_string|
|
7
7
|
@column_key_options.searchable_and_global_search.map do |column_key_option|
|
8
8
|
filter_column_as_string column_key_option, search_string
|
9
9
|
end.reduce(:or) # any searchable column is 'or'-ed
|
10
10
|
end.reduce(:and) # 'and' for each search_string
|
11
11
|
|
12
|
-
|
12
|
+
filtered.where conditions
|
13
13
|
end
|
14
14
|
|
15
|
-
def filter_by_columns(
|
15
|
+
def filter_by_columns(filtered)
|
16
16
|
conditions = @dt_params.dt_columns.each_with_object([]) do |dt_column, cond|
|
17
17
|
next unless dt_column[:searchable] && dt_column[:search_value].present?
|
18
18
|
|
@@ -23,7 +23,7 @@ module TrkDatatables
|
|
23
23
|
cond << build_condition_for_column(column_key_option, dt_column[:search_value])
|
24
24
|
end.reduce(:and) # 'and' for each searchable column
|
25
25
|
|
26
|
-
|
26
|
+
filtered.where conditions
|
27
27
|
end
|
28
28
|
|
29
29
|
def build_condition_for_column(column_key_option, search_value)
|
@@ -71,43 +71,46 @@ module TrkDatatables
|
|
71
71
|
|
72
72
|
def _parse_from_to(from, to, column_key_option)
|
73
73
|
case column_key_option[:column_type_in_db]
|
74
|
-
|
75
|
-
|
74
|
+
when :integer, :float
|
75
|
+
# we do not need to cast from string since range will do automatically
|
76
|
+
parsed_from = from
|
77
|
+
parsed_to = to
|
76
78
|
when :date, :datetime
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
# we need to add one day since it looks at begining of a day 2010-10-10 00:00:00
|
83
|
-
_parse_in_zone(to) + 60 * 60 * 24 - 1
|
84
|
-
end
|
79
|
+
parsed_from = _parse_in_zone(from)
|
80
|
+
parsed_to = _parse_in_zone(to)
|
81
|
+
if parsed_to.present? && !to.match(/AM|PM/)
|
82
|
+
# we need to add one day since it looks at begining of a day 2010-10-10 00:00:00
|
83
|
+
parsed_to += 60 * 60 * 24 - 1
|
85
84
|
end
|
86
85
|
end
|
87
|
-
[
|
86
|
+
[parsed_from, parsed_to]
|
88
87
|
end
|
89
88
|
|
90
89
|
# rubocop:disable Rails/TimeZone
|
91
90
|
def _parse_in_zone(time)
|
91
|
+
return nil if time.blank?
|
92
|
+
|
92
93
|
# without rails we will parse without zone so make sure params are correct
|
93
94
|
Time.zone ? Time.zone.parse(time) : Time.parse(time)
|
95
|
+
rescue ArgumentError
|
96
|
+
nil
|
94
97
|
end
|
95
98
|
# rubocop:enable Rails/TimeZone
|
96
99
|
|
97
|
-
def order_and_paginate_items(
|
98
|
-
|
99
|
-
|
100
|
-
|
100
|
+
def order_and_paginate_items(filtered)
|
101
|
+
filtered = order_items filtered
|
102
|
+
filtered = filtered.offset(@dt_params.dt_offset).limit(dt_per_page_or_default)
|
103
|
+
filtered
|
101
104
|
end
|
102
105
|
|
103
|
-
def order_items(
|
104
|
-
order_by =
|
105
|
-
column_key_option = @column_key_options[
|
106
|
+
def order_items(filtered)
|
107
|
+
order_by = dt_orders_or_default_index_and_direction.each_with_object([]) do |(index, direction), queries|
|
108
|
+
column_key_option = @column_key_options[index]
|
106
109
|
next if column_key_option[:column_options][ColumnKeyOptions::ORDER_OPTION] == false
|
107
110
|
|
108
|
-
queries << "#{column_key_option[:column_key]} #{
|
111
|
+
queries << "#{column_key_option[:column_key]} #{direction}"
|
109
112
|
end
|
110
|
-
|
113
|
+
filtered.order(Arel.sql(order_by.join(', ')))
|
111
114
|
end
|
112
115
|
|
113
116
|
def _arel_column(column_key_option)
|
data/lib/trk_datatables/base.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
module TrkDatatables
|
2
2
|
BETWEEN_SEPARATOR = ' - '.freeze
|
3
3
|
MULTIPLE_OPTION_SEPARATOR = '|'.freeze
|
4
|
-
DEFAULT_ORDER = [
|
4
|
+
DEFAULT_ORDER = [[0, :desc]].freeze
|
5
5
|
DEFAULT_PAGE_LENGTH = 10
|
6
6
|
|
7
7
|
class Error < StandardError
|
8
8
|
end
|
9
9
|
|
10
10
|
class Base
|
11
|
-
include TrkDatatables::Preferences
|
12
11
|
attr_accessor :column_key_options
|
13
12
|
|
14
13
|
def initialize(view)
|
15
14
|
@view = view
|
16
15
|
@dt_params = DtParams.new view.params
|
17
16
|
@column_key_options = ColumnKeyOptions.new columns, global_search_columns
|
17
|
+
@preferences = Preferences.new preferences_holder, preferences_field
|
18
18
|
|
19
19
|
# if @dt_params.dt_columns.size != @column_key_options.size
|
20
20
|
# raise Error, "dt_columns size of columns is #{@dt_params.dt_columns.size} \
|
@@ -93,19 +93,21 @@ module TrkDatatables
|
|
93
93
|
raise 'order_and_paginate_items_is_defined_in_specific_orm'
|
94
94
|
end
|
95
95
|
|
96
|
-
# Returns dt_orders or default
|
96
|
+
# Returns dt_orders or default as array of index and direction
|
97
|
+
# https://datatables.net/reference/option/order
|
97
98
|
# @return
|
98
99
|
# [
|
99
|
-
#
|
100
|
+
# [0, :desc],
|
100
101
|
# ]
|
101
|
-
def
|
102
|
+
def dt_orders_or_default_index_and_direction
|
102
103
|
return @dt_orders_or_default if defined? @dt_orders_or_default
|
103
104
|
|
104
105
|
if @dt_params.dt_orders.present?
|
105
106
|
@dt_orders_or_default = @dt_params.dt_orders
|
106
|
-
|
107
|
+
@preferences.set :order, @dt_params.dt_orders
|
107
108
|
else
|
108
|
-
|
109
|
+
check_value = ->(r) { r.is_a?(Array) && r[0].is_a?(Array) && r[0][0].is_a?(Integer) }
|
110
|
+
@dt_orders_or_default = @preferences.get(:order, check_value) || DEFAULT_ORDER
|
109
111
|
end
|
110
112
|
@dt_orders_or_default
|
111
113
|
end
|
@@ -115,10 +117,10 @@ module TrkDatatables
|
|
115
117
|
|
116
118
|
@dt_per_page_or_default = \
|
117
119
|
if @dt_params.dt_per_page.present?
|
118
|
-
|
120
|
+
@preferences.set :per_page, @dt_params.dt_per_page
|
119
121
|
@dt_params.dt_per_page
|
120
122
|
else
|
121
|
-
|
123
|
+
@preferences.get(:per_page) || DEFAULT_PAGE_LENGTH
|
122
124
|
end
|
123
125
|
end
|
124
126
|
|
@@ -164,7 +166,6 @@ module TrkDatatables
|
|
164
166
|
def as_json(_attr = nil)
|
165
167
|
# get the value if it is not a relation
|
166
168
|
all_count = all_items.count
|
167
|
-
filtered_items = filter_by_search_all filter_by_columns all_items
|
168
169
|
@dt_params.as_json(
|
169
170
|
all_count,
|
170
171
|
filtered_items.count,
|
@@ -172,6 +173,10 @@ module TrkDatatables
|
|
172
173
|
)
|
173
174
|
end
|
174
175
|
|
176
|
+
def filtered_items
|
177
|
+
filter_by_search_all filter_by_columns all_items
|
178
|
+
end
|
179
|
+
|
175
180
|
def ordered_paginated_filtered_items
|
176
181
|
order_and_paginate_items filter_by_search_all filter_by_columns all_items
|
177
182
|
end
|
@@ -188,5 +193,22 @@ module TrkDatatables
|
|
188
193
|
render = RenderHtml.new(search_link, self, html_options)
|
189
194
|
render.result
|
190
195
|
end
|
196
|
+
|
197
|
+
# Override this to set model where you can store order, index, page length
|
198
|
+
# @example
|
199
|
+
# def preferences_holder
|
200
|
+
# @view.current_user
|
201
|
+
# end
|
202
|
+
def preferences_holder
|
203
|
+
nil
|
204
|
+
end
|
205
|
+
|
206
|
+
# Override if you use different than :preferences
|
207
|
+
# You can generate with this command:
|
208
|
+
# @code
|
209
|
+
# rails g migration add_preferences_to_users preferences:jsonb
|
210
|
+
def preferences_field
|
211
|
+
:preferences
|
212
|
+
end
|
191
213
|
end
|
192
214
|
end
|
@@ -26,12 +26,12 @@ module TrkDatatables
|
|
26
26
|
# (dt_offset / dt_per_page) + 1
|
27
27
|
# end
|
28
28
|
|
29
|
-
# Typecast so we can safelly use dt_order[
|
30
|
-
# dt_order[
|
29
|
+
# Typecast so we can safelly use dt_order[0] (Integer) and
|
30
|
+
# dt_order[1] (:asc/:desc)
|
31
31
|
# @return
|
32
32
|
# [
|
33
|
-
#
|
34
|
-
#
|
33
|
+
# [ 2, :asc ],
|
34
|
+
# [ 1, :desc ],
|
35
35
|
# ]
|
36
36
|
def dt_orders
|
37
37
|
return @dt_orders if defined? @dt_orders
|
@@ -41,11 +41,11 @@ module TrkDatatables
|
|
41
41
|
|
42
42
|
@dt_orders = \
|
43
43
|
@params[:order].each_with_object([]) do |(_index, dt_order), a|
|
44
|
-
# for order we ignore key (
|
45
|
-
a <<
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
# for order we ignore key (_index) since order is preserved
|
45
|
+
a << [
|
46
|
+
dt_order[:column].to_i,
|
47
|
+
dt_order[:dir]&.to_s&.casecmp('ASC')&.zero? ? :asc : :desc,
|
48
|
+
]
|
49
49
|
end
|
50
50
|
@dt_orders
|
51
51
|
end
|
@@ -1,35 +1,28 @@
|
|
1
1
|
module TrkDatatables
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# @view.current_user
|
7
|
-
# end
|
8
|
-
def preferences_holder
|
9
|
-
nil
|
2
|
+
class Preferences
|
3
|
+
def initialize(holder, field)
|
4
|
+
@holder = holder
|
5
|
+
@field = field
|
10
6
|
end
|
11
7
|
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
:preferences
|
18
|
-
end
|
19
|
-
|
20
|
-
def get_preference(key)
|
21
|
-
return unless preferences_holder
|
8
|
+
# Get the key from holder
|
9
|
+
# Use check_value proc to ignore wrong format. This is usefull when you
|
10
|
+
# change format and you do not want to clear all existing values
|
11
|
+
def get(key, check_value = nil)
|
12
|
+
return unless @holder
|
22
13
|
|
23
|
-
|
14
|
+
result = @holder.send(@field).dig :dt_preferences, self.class.name, key
|
15
|
+
return result if check_value.nil?
|
16
|
+
return result if check_value.call result
|
24
17
|
end
|
25
18
|
|
26
|
-
def
|
27
|
-
return unless
|
19
|
+
def set(key, value)
|
20
|
+
return unless @holder
|
28
21
|
|
29
22
|
h = { dt_preferences: { self.class.name => { key => value } } }
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
@holder.send("#{@field}=", {}) if @holder.send(@field).nil?
|
24
|
+
@holder.send(@field).deep_merge! h
|
25
|
+
@holder.save!
|
33
26
|
end
|
34
27
|
end
|
35
28
|
end
|
@@ -85,10 +85,10 @@ module TrkDatatables
|
|
85
85
|
'data-datatable': true,
|
86
86
|
'data-datatable-ajax-url': @search_link,
|
87
87
|
'data-datatable-page-length': @datatable.dt_per_page_or_default,
|
88
|
-
'data-datatable-order':
|
89
|
-
|
90
|
-
|
91
|
-
'data-datatable-total-length': @datatable.
|
88
|
+
'data-datatable-order': @datatable.dt_orders_or_default_index_and_direction.to_json,
|
89
|
+
# for initial page load we do not have ability to show recordsTotal
|
90
|
+
# https://github.com/trkin/trk_datatables_js/issues/1
|
91
|
+
'data-datatable-total-length': @datatable.filtered_items.count,
|
92
92
|
) do
|
93
93
|
thead << "\n".html_safe << tbody
|
94
94
|
end
|
data/trk_datatables.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.metadata['homepage_uri'] = spec.homepage
|
23
23
|
spec.metadata['source_code_uri'] = 'https://github.com/trkin/trk_datatables'
|
24
|
-
spec.metadata['changelog_uri'] = 'https://github.com/trkin/trk_datatables/CHANGELOG.md'
|
24
|
+
spec.metadata['changelog_uri'] = 'https://github.com/trkin/trk_datatables/blob/master/CHANGELOG.md'
|
25
25
|
spec.metadata['yard.run'] = 'yri' # use "yard" to build full HTML docs.
|
26
26
|
else
|
27
27
|
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trk_datatables
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dusan Orlovic
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -185,7 +185,7 @@ metadata:
|
|
185
185
|
allowed_push_host: https://rubygems.org
|
186
186
|
homepage_uri: https://github.com/trkin/trk_datatables
|
187
187
|
source_code_uri: https://github.com/trkin/trk_datatables
|
188
|
-
changelog_uri: https://github.com/trkin/trk_datatables/CHANGELOG.md
|
188
|
+
changelog_uri: https://github.com/trkin/trk_datatables/blob/master/CHANGELOG.md
|
189
189
|
yard.run: yri
|
190
190
|
post_install_message:
|
191
191
|
rdoc_options: []
|