trk_datatables 0.1.8 → 0.1.9
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/Gemfile.lock +1 -1
- data/README.md +106 -28
- data/lib/trk_datatables/active_record.rb +1 -1
- data/lib/trk_datatables/base.rb +16 -1
- data/lib/trk_datatables/column_key_options.rb +26 -6
- data/lib/trk_datatables/render_html.rb +4 -0
- data/lib/trk_datatables/version.rb +1 -1
- data/lib/trk_datatables.rb +5 -0
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57e78f6b6116b69f62786d4c055b7ba4d13ea30e47c268d3de230e2bac8b9b2f
|
4
|
+
data.tar.gz: ec35ef831ff82b46b10b88d8f37415317db17966912ee2aae01870f6dd9db3d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdea7f9b9fe10cd4a61f43206756e129dc8fdb8ea9f53b7d5716933c9930909a69e4a100f23812975da067bfc734937d4423b661d548afc35b6647792ba4726a
|
7
|
+
data.tar.gz: 35bc6e872063f0a694b8b25f7b9c8dc4400141439eed414a18ab5740774c6ce2e8c4172265441a1fc37740085c5152cd102d479e557120c25c89397355f2846b
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
# Trk Datatables
|
2
2
|
|
3
|
-
This is a [trk_datatables gem](https://rubygems.org/gems/trk_datatables) that you
|
4
|
-
can use with trk_datatables npm package for easier usage of [Datatables
|
3
|
+
This is a source for [trk_datatables gem](https://rubygems.org/gems/trk_datatables) that you
|
4
|
+
can use with [trk_datatables npm package](https://www.npmjs.com/package/trk_datatables) for easier usage of [Datatables plug-in for jQuery library](https://datatables.net)
|
5
5
|
|
6
|
-
After [
|
7
|
-
datatable
|
8
|
-
|
9
|
-
|
10
|
-
other complex listing based on GET params.
|
11
|
-
|
12
|
-
Table of Contents
|
13
|
-
=================
|
6
|
+
After [configuration](https://github.com/trkin/trk_datatables#configuration) you can use
|
7
|
+
one line commands (like `@datatable.render_html`) to generate first page in html
|
8
|
+
(so non-js crawlers can see it), global search, filtering and sorting, adding
|
9
|
+
map and other complex listing based on GET params.
|
14
10
|
|
11
|
+
## Table of Contents
|
12
|
+
<!--ts-->
|
15
13
|
* [Trk Datatables](#trk-datatables)
|
16
|
-
|
14
|
+
* [Table of Contents](#table-of-contents)
|
17
15
|
* [Installation](#installation)
|
18
16
|
* [Usage example in Ruby on Rails](#usage-example-in-ruby-on-rails)
|
19
17
|
* [Configuration](#configuration)
|
@@ -23,6 +21,8 @@ Table of Contents
|
|
23
21
|
* [Action column](#action-column)
|
24
22
|
* [Params](#params)
|
25
23
|
* [Saved Preferences (optional)](#saved-preferences-optional)
|
24
|
+
* [Additional data to json response](#additional-data-to-json-response)
|
25
|
+
* [Different response for mobile app](#different-response-for-mobile-app)
|
26
26
|
* [Debug](#debug)
|
27
27
|
* [Alternatives](#alternatives)
|
28
28
|
* [Development](#development)
|
@@ -30,6 +30,10 @@ Table of Contents
|
|
30
30
|
* [License](#license)
|
31
31
|
* [Code of Conduct](#code-of-conduct)
|
32
32
|
|
33
|
+
<!-- Added by: orlovic, at: Mon Sep 9 09:38:44 CEST 2019 -->
|
34
|
+
|
35
|
+
<!--te-->
|
36
|
+
|
33
37
|
## Installation
|
34
38
|
|
35
39
|
Add this line to your application's Gemfile:
|
@@ -47,7 +51,7 @@ can use Rails generator)
|
|
47
51
|
|
48
52
|
## Usage example in Ruby on Rails
|
49
53
|
|
50
|
-
For a table you need to define `
|
54
|
+
For a table you need to define `columns` and `rows` (well that is obvious 😌).
|
51
55
|
In datatable class you also need to define `all_items` method which will be
|
52
56
|
used to populate `rows` with paginated, sorted and filtered items (we will call
|
53
57
|
them `filtered`)
|
@@ -55,10 +59,6 @@ them `filtered`)
|
|
55
59
|
```
|
56
60
|
# app/datatables/posts_datatable.rb
|
57
61
|
class PostsDatatable < TrkDatatables::ActiveRecord
|
58
|
-
def all_items
|
59
|
-
Post.left_joins(:user)
|
60
|
-
end
|
61
|
-
|
62
62
|
def columns
|
63
63
|
{
|
64
64
|
'posts.title': {},
|
@@ -74,6 +74,10 @@ class PostsDatatable < TrkDatatables::ActiveRecord
|
|
74
74
|
]
|
75
75
|
end
|
76
76
|
end
|
77
|
+
|
78
|
+
def all_items
|
79
|
+
Post.left_joins(:user)
|
80
|
+
end
|
77
81
|
end
|
78
82
|
```
|
79
83
|
|
@@ -115,10 +119,10 @@ And finally in a view, use `render_html` to have first page show up prerendered
|
|
115
119
|
|
116
120
|
## Configuration
|
117
121
|
|
118
|
-
|
122
|
+
Datatables will search all columns that you defined as keys in `columns` using a
|
119
123
|
`ILIKE` (ie `.matches` in Arel ActiveRecord).
|
120
124
|
|
121
|
-
|
125
|
+
In datatables there are two types of search: global (search all columns) and
|
122
126
|
column search (search is done for specific columns).
|
123
127
|
|
124
128
|
### Global search
|
@@ -129,23 +133,96 @@ method.
|
|
129
133
|
```
|
130
134
|
class PostsDatatable < TrkDatatables::ActiveRecord
|
131
135
|
def global_search_columns
|
132
|
-
# those fields will be used
|
136
|
+
# in addition to columns those fields will be used to match global search
|
133
137
|
%w[posts.body users.name]
|
134
138
|
end
|
135
139
|
end
|
136
140
|
```
|
137
141
|
|
138
|
-
### Column 'ILIKE'
|
142
|
+
### Column 'ILIKE' search
|
139
143
|
|
140
|
-
|
141
|
-
|
144
|
+
All columns are by default caster to string and `ILIKE` is perfomed.
|
145
|
+
There is short notation if you do not need any specific column configuration,
|
146
|
+
for example custom title (in which case you need to define columns as key/value
|
147
|
+
pairs).
|
142
148
|
|
143
|
-
|
144
|
-
|
145
|
-
|
149
|
+
```
|
150
|
+
# app/datatables/posts_datatable.rb
|
151
|
+
class PostsDatatable < TrkDatatables::ActiveRecord
|
152
|
+
def columns
|
153
|
+
# %w[posts.id posts.title posts.body] or even shorter using map
|
154
|
+
%i[id title body].map { |col| "posts.#{col}" }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
```
|
158
|
+
### Column 'BETWEEN' search
|
159
|
+
|
160
|
+
For column search when search string contains BETWEEN_SEPARATOR (` - `) and
|
161
|
+
column_type_in_db as one of the: `:date`, `:datetime`, `:integer` and
|
162
|
+
`:float` than `BETWEEN` is perfomed.
|
163
|
+
|
164
|
+
For columns `:date` there will be `data-datatable-range='true'`
|
165
|
+
attribute so [data range picker](http://www.daterangepicker.com/) will be
|
166
|
+
automatically loaded. For `:datetime` you can enable time picker in addition to
|
167
|
+
date.
|
168
|
+
|
169
|
+
```
|
170
|
+
# app/datatables/posts_datatable.rb
|
171
|
+
class PostsDatatable < TrkDatatables::ActiveRecord
|
172
|
+
def columns
|
173
|
+
{
|
174
|
+
'posts.created_at': { time_picker: true },
|
175
|
+
}
|
176
|
+
end
|
177
|
+
end
|
178
|
+
```
|
179
|
+
|
180
|
+
To enable shortcuts for selecting ranges, you can override predefined ranges
|
181
|
+
|
182
|
+
```
|
183
|
+
# app/datatables/base_trk_datatable.rb
|
184
|
+
class BaseTrkDatable < TrkDatatables::ActiveRecord
|
185
|
+
def predefined_ranges
|
186
|
+
# defaults are defined in https://github.com/trkin/trk_datatables/blob/master/lib/trk_datatables/base.rb
|
187
|
+
default_predefined_ranges
|
188
|
+
end
|
189
|
+
end
|
190
|
+
```
|
191
|
+
or you can override for specific datatable
|
192
|
+
```
|
193
|
+
class PostsDatatable < TrkDatatables::ActiveRecord
|
194
|
+
def columns
|
195
|
+
{
|
196
|
+
'posts.created_at': { predefined_ranges: true },
|
197
|
+
}
|
198
|
+
end
|
199
|
+
|
200
|
+
def predefined_ranges
|
201
|
+
{
|
202
|
+
'Today': Time.zone.now.beginning_of_day..Time.zone.now.end_of_day,
|
203
|
+
'Yesterday': [Time.zone.now.beginning_of_day - 1.day, Time.zone.now.end_of_day - 1.day],
|
204
|
+
'This Month': Time.zone.today.beginning_of_month...Time.zone.now.end_of_day,
|
205
|
+
'Last Month': Time.zone.today.prev_month.beginning_of_month...Time.zone.today.prev_month.end_of_month.end_of_day,
|
206
|
+
'This Year': Time.zone.today.beginning_of_year...Time.zone.today.end_of_day,
|
207
|
+
}
|
208
|
+
end
|
209
|
+
end
|
210
|
+
```
|
211
|
+
or you can define for specific column
|
212
|
+
```
|
213
|
+
# app/datatables/posts_datatable.rb
|
214
|
+
class PostsDatatable < TrkDatatables::ActiveRecord
|
215
|
+
def columns
|
216
|
+
{
|
217
|
+
'posts.created_at': { predefined_ranges: { 'Today': Time.zone.now.beginning_of_day...Time.zone.now.end_of_day } },
|
218
|
+
}
|
219
|
+
end
|
220
|
+
end
|
221
|
+
```
|
146
222
|
|
147
|
-
|
148
|
-
|
223
|
+
We use
|
224
|
+
[ActiveSupport::TimeZone](https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html)
|
225
|
+
so if you use different than UTC you need to set `Time.zone =` in your app [example values](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/values/time_zone.rb#L31). Whenever Time.parse is used (and we use `Time.zone.parse` for params) it needs correct zone (in Rails you can set timezone in `config.time_zone` or use [browser timezone rails gem](https://github.com/kbaum/browser-timezone-rails)).
|
149
226
|
|
150
227
|
### Column 'IN' search
|
151
228
|
|
@@ -184,9 +261,10 @@ use empty column_key
|
|
184
261
|
|
185
262
|
def rows(filtered)
|
186
263
|
filtered.each do |post|
|
264
|
+
actions = @view.link_to('View', post)
|
187
265
|
[
|
188
266
|
post.title,
|
189
|
-
|
267
|
+
actions,
|
190
268
|
]
|
191
269
|
end
|
192
270
|
end
|
@@ -90,7 +90,7 @@ module TrkDatatables
|
|
90
90
|
def _parse_in_zone(time)
|
91
91
|
return nil if time.blank?
|
92
92
|
|
93
|
-
# without
|
93
|
+
# without zone we will parse without zone so make sure params are correct
|
94
94
|
Time.zone ? Time.zone.parse(time) : Time.parse(time)
|
95
95
|
rescue ArgumentError
|
96
96
|
nil
|
data/lib/trk_datatables/base.rb
CHANGED
@@ -15,7 +15,7 @@ module TrkDatatables
|
|
15
15
|
def initialize(view)
|
16
16
|
@view = view
|
17
17
|
@dt_params = DtParams.new view.params
|
18
|
-
@column_key_options = ColumnKeyOptions.new columns, global_search_columns
|
18
|
+
@column_key_options = ColumnKeyOptions.new columns, global_search_columns, predefined_ranges
|
19
19
|
@preferences = Preferences.new preferences_holder, preferences_field
|
20
20
|
|
21
21
|
# if @dt_params.dt_columns.size != @column_key_options.size
|
@@ -215,5 +215,20 @@ module TrkDatatables
|
|
215
215
|
def preferences_field
|
216
216
|
:preferences
|
217
217
|
end
|
218
|
+
|
219
|
+
def predefined_ranges
|
220
|
+
{}
|
221
|
+
end
|
222
|
+
|
223
|
+
def default_predefined_ranges
|
224
|
+
Time.zone ||= 'UTC'
|
225
|
+
{
|
226
|
+
'Today': Time.zone.now.beginning_of_day..Time.zone.now.end_of_day,
|
227
|
+
'Yesterday': [Time.zone.now.beginning_of_day - 1.day, Time.zone.now.end_of_day - 1.day],
|
228
|
+
'This Month': Time.zone.today.beginning_of_month...Time.zone.now.end_of_day,
|
229
|
+
'Last Month': Time.zone.today.prev_month.beginning_of_month...Time.zone.today.prev_month.end_of_month.end_of_day,
|
230
|
+
'This Year': Time.zone.today.beginning_of_year...Time.zone.today.end_of_day,
|
231
|
+
}
|
232
|
+
end
|
218
233
|
end
|
219
234
|
end
|
@@ -16,10 +16,11 @@ module TrkDatatables
|
|
16
16
|
ORDER_OPTION = :order
|
17
17
|
TITLE_OPTION = :title
|
18
18
|
SELECT_OPTIONS = :select_options
|
19
|
+
PREDEFINED_RANGES = :predefined_ranges
|
19
20
|
# this will load date picker
|
20
21
|
# SEARCH_OPTION_DATE_VALUE = :date
|
21
22
|
# SEARCH_OPTION_DATETIME_VALUE = :datetime
|
22
|
-
COLUMN_OPTIONS = [SEARCH_OPTION, ORDER_OPTION, TITLE_OPTION, SELECT_OPTIONS].freeze
|
23
|
+
COLUMN_OPTIONS = [SEARCH_OPTION, ORDER_OPTION, TITLE_OPTION, SELECT_OPTIONS, PREDEFINED_RANGES].freeze
|
23
24
|
|
24
25
|
STRING_TYPE_CAST_POSTGRES = 'VARCHAR'.freeze
|
25
26
|
STRING_TYPE_CAST_MYSQL = 'CHAR'.freeze
|
@@ -48,11 +49,17 @@ module TrkDatatables
|
|
48
49
|
# title: 'Name',
|
49
50
|
# html_options: { class: 'my-class' },
|
50
51
|
# }
|
51
|
-
def initialize(cols, global_search_cols)
|
52
|
-
|
52
|
+
def initialize(cols, global_search_cols, predefined_ranges = {})
|
53
|
+
@predefined_ranges = predefined_ranges
|
54
|
+
# short notation is when we use array of keys.
|
55
|
+
# In case first element is hash than we will use that hash
|
53
56
|
if cols.is_a? Array
|
54
|
-
|
55
|
-
|
57
|
+
if cols.first.is_a? Hash
|
58
|
+
cols = cols.first
|
59
|
+
else
|
60
|
+
cols = cols.each_with_object({}) do |column_key, hash|
|
61
|
+
hash[column_key.to_sym] = {}
|
62
|
+
end
|
56
63
|
end
|
57
64
|
end
|
58
65
|
_set_data(cols)
|
@@ -157,9 +164,22 @@ module TrkDatatables
|
|
157
164
|
res = {}
|
158
165
|
res['data-searchable'] = false if column_options[SEARCH_OPTION] == false
|
159
166
|
res['data-orderable'] = false if column_options[ORDER_OPTION] == false
|
160
|
-
|
167
|
+
if %i[date datetime].include? column_type_in_db
|
168
|
+
res['data-datatable-range'] = column_type_in_db == :datetime ? :datetime : true
|
169
|
+
if column_options[PREDEFINED_RANGES].present? || @predefined_ranges.present?
|
170
|
+
res['data-datatable-predefined-ranges'] = if column_options[PREDEFINED_RANGES].is_a? Hash
|
171
|
+
column_options[PREDEFINED_RANGES]
|
172
|
+
else
|
173
|
+
@predefined_ranges
|
174
|
+
end
|
175
|
+
res['data-datatable-predefined-ranges'].transform_values! do |range|
|
176
|
+
[range.first.to_s, range.last.to_s]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
161
180
|
res
|
162
181
|
end
|
182
|
+
|
163
183
|
end
|
164
184
|
# rubocop:enable ClassLength
|
165
185
|
end
|
@@ -45,6 +45,7 @@ module TrkDatatables
|
|
45
45
|
self.class.indent += 1
|
46
46
|
html = "#{' ' * self.class.indent}<#{tag}".html_safe
|
47
47
|
options.each do |attribute, value|
|
48
|
+
value = value.to_json if value.is_a?(Hash) || value.is_a?(Array)
|
48
49
|
html << " #{attribute}='".html_safe << replace_quote(value) << "'".html_safe
|
49
50
|
end
|
50
51
|
html << if inline
|
@@ -99,10 +100,13 @@ module TrkDatatables
|
|
99
100
|
_content_tag :tr do
|
100
101
|
safe_join(@datatable.column_key_options.map do |column_key_option|
|
101
102
|
options = column_key_option[:html_options]
|
103
|
+
# add eventual value from params
|
102
104
|
search_value = @datatable.param_get(column_key_option[:column_key]) if options['data-searchable'] != false
|
103
105
|
options['data-datatable-search-value'] = search_value if search_value.present?
|
106
|
+
# add eventual select element
|
104
107
|
select_options = column_key_option[:column_options][ColumnKeyOptions::SELECT_OPTIONS]
|
105
108
|
options['data-datatable-multiselect'] = _select_tag select_options, search_value if select_options.present?
|
109
|
+
# all other options are pulled from column_key_option[:html_options]
|
106
110
|
_content_tag :th, options, column_key_option[:title]
|
107
111
|
end)
|
108
112
|
end
|
data/lib/trk_datatables.rb
CHANGED
@@ -13,3 +13,8 @@ require 'active_support/core_ext/hash/indifferent_access'
|
|
13
13
|
require 'active_support/core_ext/hash/keys'
|
14
14
|
require 'active_support/core_ext/string/inflections'
|
15
15
|
require 'active_support/core_ext/string/output_safety'
|
16
|
+
require 'active_support/core_ext/time/zones'
|
17
|
+
|
18
|
+
# we need to define here since some conventions will look for definition in this file
|
19
|
+
module TrkDatatables
|
20
|
+
end
|
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.9
|
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-09-
|
11
|
+
date: 2019-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -202,8 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
202
|
- !ruby/object:Gem::Version
|
203
203
|
version: '0'
|
204
204
|
requirements: []
|
205
|
-
|
206
|
-
rubygems_version: 2.7.6
|
205
|
+
rubygems_version: 3.0.4
|
207
206
|
signing_key:
|
208
207
|
specification_version: 4
|
209
208
|
summary: Gem that simplify using datatables with Ruby on Rails and Sinatra.
|