trk_datatables 0.2.4 → 0.2.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: 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.