trk_datatables 0.2.4 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94acc0f23e22979cbdfbbd78356012328d0da999b00706bee6b8feb28e98c7bb
4
- data.tar.gz: 458f2c1fdb9400faf491b494d5866b17397643464431bf8e6a4e115211cbbaca
3
+ metadata.gz: 520b6d86f27312cd4c8bb89e62943f542be727954446ce8c4be03790727f7a4d
4
+ data.tar.gz: dd881cc122ffd0cbec3eca16db24ed65cfc98921d22080920d8df167a8c7260c
5
5
  SHA512:
6
- metadata.gz: b48507c0815c0ab7946eb4fd770cdd317d5fceca8845c1f007556b627cfc5f77d5816497ed2825d1dce4974aa530def7bd455441e2f785131a6cd11fb1281614
7
- data.tar.gz: 609e99cc22a0a195f3903af22f214d9ce8d6e5ffbf221862844389d3af3f0e90c30e82f66ad830d808bf97023f146655d2df55d76638033a2e4c3b733b0ab6e0
6
+ metadata.gz: f7f62cc8d55ca17597c9c65d3aaf646f16f92a94873b97c83847e6e01f843f951ec74796e8064ed81cab802a404599006b3a7c321ecb672fc909c9f5e669724c
7
+ data.tar.gz: 27ea4d1cf61af80539f66502256a173c603416030da3943947fcf5d43eaefd068fe0112a7fa0d87aa2cca493f77b759c76f3c151afd1ecd3d85c44b1804e7216
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- trk_datatables (0.2.4)
4
+ trk_datatables (0.2.9)
5
5
  activesupport
6
6
 
7
7
  GEM
@@ -30,6 +30,7 @@ GEM
30
30
  rake (10.5.0)
31
31
  sqlite3 (1.4.1)
32
32
  thread_safe (0.3.6)
33
+ timecop (0.9.4)
33
34
  tzinfo (1.2.5)
34
35
  thread_safe (~> 0.1)
35
36
  zeitwerk (2.1.10)
@@ -47,6 +48,7 @@ DEPENDENCIES
47
48
  pg
48
49
  rake (~> 10.0)
49
50
  sqlite3
51
+ timecop
50
52
  trk_datatables!
51
53
 
52
54
  BUNDLED WITH
data/README.md CHANGED
@@ -18,7 +18,7 @@ you can get something like
18
18
 
19
19
  ![trk-datatables](test/trk_datatables_with_daterangepicker.png "TRK Datatables")
20
20
 
21
- Currenlty it supports:
21
+ Currently supports:
22
22
  * ActiveRecord
23
23
  * Neo4j
24
24
 
@@ -284,47 +284,32 @@ class PostsDatatable < TrkDatatables::ActiveRecord
284
284
  end
285
285
  ```
286
286
 
287
- To enable shortcuts for selecting ranges, you can override predefined ranges and
288
- enable for all `date` and `datetime` column
289
-
290
- ```
291
- # app/datatables/base_trk_datatable.rb
292
- class BaseTrkDatable < TrkDatatables::ActiveRecord
293
- def predefined_ranges
294
- # defaults are defined in https://github.com/trkin/trk_datatables/blob/master/lib/trk_datatables/base.rb
295
- default_predefined_ranges
296
- end
297
- end
298
- ```
299
- or you can enable for all `date` and `datetime columns` for specific datatable
300
- by defining `predefined_ranges` on that datatable. You can disable for specific columns also
287
+ By default, predefined ranges are enabled. You can find source for
288
+ `predefined_date_ranges` and `predefined_datetime_ranges` in
289
+ [base.rb](https://github.com/trkin/trk_datatables/blob/master/lib/trk_datatables/base.rb)
290
+ You can overwrite them in BaseTrkDatable or your trk datatable class.
291
+ You can disable or enable for specific columns like in this example:
301
292
  ```
302
293
  class PostsDatatable < TrkDatatables::ActiveRecord
303
- def predefined_ranges
294
+ def predefined_datetime_ranges
304
295
  {
305
296
  'Today': Time.zone.now.beginning_of_day..Time.zone.now.end_of_day,
306
297
  'Yesterday': [Time.zone.now.beginning_of_day - 1.day, Time.zone.now.end_of_day - 1.day],
307
298
  'This Month': Time.zone.today.beginning_of_month...Time.zone.now.end_of_day,
308
299
  'Last Month': Time.zone.today.prev_month.beginning_of_month...Time.zone.today.prev_month.end_of_month.end_of_day,
309
300
  'This Year': Time.zone.today.beginning_of_year...Time.zone.today.end_of_day,
310
- }
301
+ }.transform_values do |range|
302
+ # datepicker expects format 2020-11-29 11:59:59
303
+ range.first.strftime('%F %T')..range.last.strftime('%F %T')
304
+ end
311
305
  end
312
306
 
313
307
  def columns
314
308
  {
315
- 'posts.created_at': {}, # this column will have predefined_ranges
316
- 'posts.published_on': { predefined_ranges: false }
317
- end
318
- end
319
- ```
320
- or you can define for specific column
321
- ```
322
- # app/datatables/posts_datatable.rb
323
- class PostsDatatable < TrkDatatables::ActiveRecord
324
- def columns
325
- {
326
- 'posts.created_at': { predefined_ranges: { 'Today': Time.zone.now.beginning_of_day...Time.zone.now.end_of_day } },
327
- }
309
+ 'posts.created_at': {}, # this column will have predefined_datetime_ranges
310
+ 'posts.published_on': { predefined_ranges: false },
311
+ 'posts.updated_at': { predefined_ranges: { 'Today': Time.zone.now.beginning_of_day...Time.zone.now.end_of_day } },
312
+ }
328
313
  end
329
314
  end
330
315
  ```
@@ -567,6 +552,24 @@ class PostsDatatable
567
552
  end
568
553
  ```
569
554
 
555
+ ### Render html with additional css class and different DOM
556
+
557
+ To add additional styling to your datatable you can use `:class` option when you
558
+ are calling `@datatable.render_html url, options` for example
559
+
560
+ ```
561
+ <%= @datatable.render_html search_posts_path(format: :json), class: 'table-hover' %>
562
+ ```
563
+
564
+ Default [DOM](https://datatables.net/reference/option/dom) is
565
+ `<"trk-global-search-wrapper"f>rtp<"trk-move-up"il>` which includes global
566
+ **f**iltering, p**r**ocessing loader, **t**able search, **p**agination, table
567
+ **i**nformation and **l**ength changing control. To override you can use
568
+
569
+ ```
570
+ <%= @datatable.render_html search_posts_path(format: :json), 'data-datatable-dom': 'rt' %>
571
+ ```
572
+
570
573
  ### Params
571
574
 
572
575
  To set parameters that you can use for links to set column search value, use
@@ -589,8 +592,12 @@ This will fill proper column search values so you do not need to do it manually
589
592
  (`post_path(:columns=>{"3"=>{:search=>{:value=>"my@email.com"}},
590
593
  "2"=>{:search=>{:value=>"1|2"}}}, :user_id=>1)`)
591
594
 
592
- For form fields you can use similar helper `PostsDatatable.form_field_name
593
- 'users.email'`
595
+ For form fields you can use similar helper that will return name which points to
596
+ specific column, for example:
597
+ ```
598
+ PostsDatatable.form_field_name('users.email'`) # => 'columns[3][search][value]'
599
+ ```
600
+ Usefull when you want to provide a form for a user to search on specific column
594
601
  ```
595
602
  <%= form_tag url: posts_path, method: :get do |f| %>
596
603
  <%= f.text_field PostsDatatable.form_field_name('users.email'), 'my@email.com' %>
@@ -598,10 +605,19 @@ For form fields you can use similar helper `PostsDatatable.form_field_name
598
605
  <% end %>
599
606
  ```
600
607
 
608
+ For global search you can use `[search][value]` for example
609
+
610
+ ```
611
+ <%= form_tag url: posts_path, method: :get do |f| %>
612
+ <%= f.text_field '[search][value]', 'my@email.com' %>
613
+ <%= f.submit 'Search' %>
614
+ <% end %>
615
+ ```
616
+
601
617
  If you need, you can fetch params with this helper
602
618
 
603
619
  ```
604
- PostsDatatable.param_get('users.email', params)
620
+ datatable.param_get 'users.email'
605
621
  ```
606
622
 
607
623
  You can set filters on datatable even params are blank, for example
@@ -1,9 +1,12 @@
1
1
  module TrkDatatables
2
2
  class ActiveRecord < Base
3
+ # there is a stack level too deep exception for more than 190 strings
4
+ MAX_NUMBER_OF_STRINGS = 190
5
+
3
6
  # Global search. All columns are typecasted to string. Search string is
4
7
  # splited by space and "and"-ed.
5
8
  def filter_by_search_all(filtered)
6
- conditions = @dt_params.search_all.split(' ').map do |search_string|
9
+ conditions = @dt_params.search_all.split(' ').first(MAX_NUMBER_OF_STRINGS).map do |search_string|
7
10
  @column_key_options.searchable_and_global_search.map do |column_key_option|
8
11
  _filter_column_as_string column_key_option, search_string
9
12
  end.reduce(:or) # any searchable column is 'or'-ed
@@ -45,7 +48,7 @@ module TrkDatatables
45
48
  end
46
49
 
47
50
  def _filter_column_as_string(column_key_option, search_value)
48
- search_value.split(' ').map do |search_string|
51
+ search_value.split(' ').first(MAX_NUMBER_OF_STRINGS).map do |search_string|
49
52
  casted_column = ::Arel::Nodes::NamedFunction.new(
50
53
  'CAST',
51
54
  [_arel_column(column_key_option).as(@column_key_options.string_cast)]
@@ -7,7 +7,7 @@ module TrkDatatables
7
7
  class Error < StandardError
8
8
  end
9
9
 
10
- class Base
10
+ class Base # rubocop:todo Metrics/ClassLength
11
11
  extend TrkDatatables::BaseHelpers
12
12
 
13
13
  attr_accessor :column_key_options
@@ -97,8 +97,6 @@ module TrkDatatables
97
97
  raise 'order_and_paginate_items_is_defined_in_specific_orm'
98
98
  end
99
99
 
100
- # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
101
-
102
100
  # Returns dt_orders or default as array of index and direction
103
101
  # https://datatables.net/reference/option/order
104
102
  # @return
@@ -114,12 +112,11 @@ module TrkDatatables
114
112
  @dt_orders_or_default = @dt_params.dt_orders
115
113
  @preferences.set :order, @dt_params.dt_orders
116
114
  else
117
- check_value = ->(r) { r.is_a?(Array) && r[0].is_a?(Array) && r[0][0].is_a?(Integer) }
115
+ check_value = ->(r) { r.is_a?(Array) && r[0].is_a?(Array) && r[0][0].is_a?(Integer) && r[0][0] < @column_key_options.size }
118
116
  @dt_orders_or_default = @preferences.get(:order, check_value) || default_order
119
117
  end
120
118
  @dt_orders_or_default
121
119
  end
122
- # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
123
120
 
124
121
  def default_order
125
122
  [[0, :desc]].freeze
@@ -219,18 +216,35 @@ module TrkDatatables
219
216
  end
220
217
 
221
218
  def predefined_ranges
222
- {}
219
+ Time.zone ||= 'UTC'
220
+ {
221
+ date: predefined_date_ranges,
222
+ datetime: predefined_datetime_ranges,
223
+ }
223
224
  end
224
225
 
225
- def default_predefined_ranges
226
- Time.zone ||= 'UTC'
226
+ def predefined_date_ranges # rubocop:todo Metrics/AbcSize
227
+ {
228
+ 'Today': Time.zone.today..Time.zone.today,
229
+ 'Yesterday': [Time.zone.today - 1.day, Time.zone.today - 1.day],
230
+ 'This Month': Time.zone.today.beginning_of_month...Time.zone.today,
231
+ 'Last Month': Time.zone.today.prev_month.beginning_of_month...Time.zone.today.prev_month.end_of_month,
232
+ 'This Year': Time.zone.today.beginning_of_year...Time.zone.today,
233
+ }
234
+ end
235
+
236
+ def predefined_datetime_ranges # rubocop:todo Metrics/AbcSize
227
237
  {
228
238
  'Today': Time.zone.now.beginning_of_day..Time.zone.now.end_of_day,
229
239
  'Yesterday': [Time.zone.now.beginning_of_day - 1.day, Time.zone.now.end_of_day - 1.day],
230
- 'This Month': Time.zone.today.beginning_of_month...Time.zone.now.end_of_day,
231
- 'Last Month': Time.zone.today.prev_month.beginning_of_month...Time.zone.today.prev_month.end_of_month.end_of_day,
232
- 'This Year': Time.zone.today.beginning_of_year...Time.zone.today.end_of_day,
233
- }
240
+ 'This Month': Time.zone.today.beginning_of_month.beginning_of_day...Time.zone.now.end_of_day,
241
+ 'Last Month':
242
+ Time.zone.today.prev_month.beginning_of_month.beginning_of_day...Time.zone.today.prev_month.end_of_month.end_of_day,
243
+ 'This Year': Time.zone.today.beginning_of_year.beginning_of_day...Time.zone.today.end_of_day,
244
+ }.transform_values do |range|
245
+ # datepicker expects format 2020-11-29 11:59:59
246
+ range.first.strftime('%F %T')..range.last.strftime('%F %T')
247
+ end
234
248
  end
235
249
  end
236
250
  end
@@ -22,11 +22,15 @@ module TrkDatatables
22
22
  end
23
23
 
24
24
  # Get the form field name for column. This is class method so you do not
25
- # need datatable instance.
25
+ # need datatable instance. It returns something like
26
+ # 'column[3][search][value]`. For global search you can use
27
+ # '[search][value]`
26
28
  #
27
29
  # @example
28
30
  # form_tag url: posts_path, method: :get do |f|
29
31
  # f.text_field PostsDatatable.form_field_name('users.email'), 'my@email.com'
32
+ # # it is the same as
33
+ # f.text_field 'columns[3][search][value]', 'my@email.com'
30
34
  def form_field_name(column_key)
31
35
  datatable = new OpenStruct.new(params: {})
32
36
  column_index = datatable.index_by_column_key column_key
@@ -244,11 +244,11 @@ module TrkDatatables
244
244
  if %i[date datetime].include? column_type_in_db
245
245
  res['data-datatable-range'] = column_type_in_db == :datetime ? :datetime : true
246
246
  if column_options[PREDEFINED_RANGES].present? ||
247
- (@predefined_ranges.present? && column_options[PREDEFINED_RANGES] != false)
247
+ (@predefined_ranges.try(:[], column_type_in_db).present? && column_options[PREDEFINED_RANGES] != false)
248
248
  res['data-datatable-predefined-ranges'] = if column_options[PREDEFINED_RANGES].is_a? Hash
249
249
  column_options[PREDEFINED_RANGES]
250
250
  else
251
- @predefined_ranges
251
+ @predefined_ranges[column_type_in_db]
252
252
  end
253
253
  res['data-datatable-predefined-ranges'].transform_values! do |range|
254
254
  [range.first.to_s, range.last.to_s]
@@ -117,7 +117,7 @@ module TrkDatatables
117
117
  def param_get(column_index)
118
118
  @params.dig :columns, column_index.to_s, :search, :value
119
119
  rescue TypeError => e
120
- raise Error, e.message + '. Column search is in a format: { "columns": { "0": { "search": { "value": { "ABC" } } } } }'
120
+ raise Error, "#{e.message}. Column search is in a format: { \"columns\": { \"0\": { \"search\": { \"value\": { \"ABC\" } } } } }"
121
121
  end
122
122
 
123
123
  def self.sample_view_params(options = {})
@@ -4,8 +4,8 @@ module TrkDatatables
4
4
  def initialize(search_link, datatable, html_options = {})
5
5
  @search_link = search_link
6
6
  @datatable = datatable
7
- @html_options = html_options
8
- self.class.indent = -1
7
+ @html_options = html_options.symbolize_keys
8
+ self.class.indent = 0
9
9
  end
10
10
 
11
11
  def result
@@ -53,7 +53,7 @@ module TrkDatatables
53
53
  else
54
54
  ">\n".html_safe << yield << "\n#{' ' * self.class.indent}</#{tag}>".html_safe
55
55
  end
56
- self.class.indent -= 1
56
+ self.class.indent -= 1 if self.class.indent > 1
57
57
  html
58
58
  end
59
59
  # rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
@@ -89,6 +89,7 @@ module TrkDatatables
89
89
  # for initial page load we do not have ability to show recordsTotal
90
90
  # https://github.com/trkin/trk_datatables_js/issues/1
91
91
  'data-datatable-total-length': @datatable.filtered_items_count,
92
+ 'data-datatable-dom': @html_options[:'data-datatable-dom'] || '<"trk-global-search-wrapper"f>rtp<"trk-move-up"il>',
92
93
  ) do
93
94
  thead << "\n".html_safe << tbody
94
95
  end +
@@ -128,6 +129,25 @@ module TrkDatatables
128
129
  end
129
130
 
130
131
  def table_tag_client
132
+ # Should we allow generating datatable only in view
133
+ # <%= ClientDatatable.new(self).render_html do %>
134
+ # <thead>
135
+ # <tr>
136
+ # so we do not need datatable and search route
137
+ # than we just need <table> tag, but it uses datatable to determine page
138
+ # length and order (which in turn it determines from params or
139
+ # preferences)
140
+ # _content_tag(
141
+ # :table,
142
+ # class: "table table-bordered table-striped #{@html_options[:class]}",
143
+ # 'data-datatable': true,
144
+ # 'data-datatable-ajax-url': @search_link,
145
+ # 'data-datatable-page-length': @datatable.dt_per_page_or_default,
146
+ # 'data-datatable-order': @datatable.dt_orders_or_default_index_and_direction.to_json,
147
+ # # for initial page load we do not have ability to show recordsTotal
148
+ # # https://github.com/trkin/trk_datatables_js/issues/1
149
+ # 'data-datatable-total-length': @datatable.filtered_items_count,
150
+ # ) do
131
151
  ''
132
152
  end
133
153
  end
@@ -1,3 +1,3 @@
1
1
  module TrkDatatables
2
- VERSION = '0.2.4'.freeze
2
+ VERSION = '0.2.9'.freeze
3
3
  end
@@ -46,6 +46,7 @@ Gem::Specification.new do |spec|
46
46
  spec.add_development_dependency 'database_cleaner'
47
47
  spec.add_development_dependency 'minitest', '~> 5.0'
48
48
  spec.add_development_dependency 'minitest-color'
49
+ spec.add_development_dependency 'timecop'
49
50
  spec.add_development_dependency 'pg'
50
51
  spec.add_development_dependency 'rake', '~> 10.0'
51
52
  spec.add_development_dependency 'sqlite3'
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.2.4
4
+ version: 0.2.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: 2020-09-15 00:00:00.000000000 Z
11
+ date: 2021-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: timecop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: pg
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -206,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
206
220
  - !ruby/object:Gem::Version
207
221
  version: '0'
208
222
  requirements: []
209
- rubygems_version: 3.0.3
223
+ rubygems_version: 3.0.8
210
224
  signing_key:
211
225
  specification_version: 4
212
226
  summary: Gem that simplify using datatables with Ruby on Rails and Sinatra.