trk_datatables 0.1.8 → 0.1.9

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
  SHA256:
3
- metadata.gz: cc472e542b418135db2ce0eab6f8b98d9c32d75a17f714c21a8b18772bfc24eb
4
- data.tar.gz: 1c80411cdd014fa67c246a682d51e5b3be08f96ba78211df1119a5cc7a6d895b
3
+ metadata.gz: 57e78f6b6116b69f62786d4c055b7ba4d13ea30e47c268d3de230e2bac8b9b2f
4
+ data.tar.gz: ec35ef831ff82b46b10b88d8f37415317db17966912ee2aae01870f6dd9db3d9
5
5
  SHA512:
6
- metadata.gz: 60ab3e28c6af2d70fbff6f11bbadf915219797eca2a0833389bcf74a04162cbc4a873389c2af8ed43819617f2c2c0cc8945dfa31b0007a04e062be6590491d7c
7
- data.tar.gz: 37369125ed9a3a7c8c404d916e6eb425cd75f0ad83a4c4f7b7d6d7597a8e27c3108c3c1b172ed19a29e06707b407dec2244c55457e0559876e8c187a324690af
6
+ metadata.gz: bdea7f9b9fe10cd4a61f43206756e129dc8fdb8ea9f53b7d5716933c9930909a69e4a100f23812975da067bfc734937d4423b661d548afc35b6647792ba4726a
7
+ data.tar.gz: 35bc6e872063f0a694b8b25f7b9c8dc4400141439eed414a18ab5740774c6ce2e8c4172265441a1fc37740085c5152cd102d479e557120c25c89397355f2846b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- trk_datatables (0.1.8)
4
+ trk_datatables (0.1.9)
5
5
  activesupport
6
6
 
7
7
  GEM
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 js library](https://datatables.net)
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 [configuring one
7
- datatable](https://github.com/trkin/trk_datatables#configuration), it gives you
8
- one liner command to generate first page in html (so non-js crawlers can see
9
- it), global search, filtering and sorting by one or more columns, adding map and
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
- * [Table of Contents](#table-of-contents)
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 `rows` and `columns` (well that is obvious 😌).
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
- Datatable will search all columns that you defined as keys in `columns` using a
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
- On frontend there are two types of search: global (search all columns) and
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 only to match global search
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' and 'BETWEEN' search
142
+ ### Column 'ILIKE' search
139
143
 
140
- For column search when search string does not contain BETWEEN_SEPARATOR (` - `) than
141
- all columns are casted to string and `ILIKE` is perfomed.
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
- When column_type_in_db as one of the: `:date`, `:datetime`, `:integer` and
144
- `:float` than `BETWEEN` is perfomed (when search contains BETWEEN_SEPARATOR,
145
- otherwise it is `ILIKE`).
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
- For columns `:date` and `:datetime` there will be `data-datatable-range='true'`
148
- attribute so bootstrap datepicker will be automatically loaded.
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
- "@view"
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 rails we will parse without zone so make sure params are correct
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
@@ -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
- # if someone use Array instead of hash, we will use first element
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
- cols = cols.each_with_object({}) do |column_key, hash|
55
- hash[column_key.to_sym] = {}
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
- res['data-datatable-range'] = true if %i[date datetime].include? column_type_in_db
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
@@ -1,3 +1,3 @@
1
1
  module TrkDatatables
2
- VERSION = '0.1.8'.freeze
2
+ VERSION = '0.1.9'.freeze
3
3
  end
@@ -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.8
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-04 00:00:00.000000000 Z
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
- rubyforge_project:
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.