jquery-tablesorter-rails-utils 0.0.1 → 0.2.0

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
- SHA1:
3
- metadata.gz: 78cbade05c4684cc14f69a730fef1e7dd40ec1b1
4
- data.tar.gz: dc91520ae73b330131ff2e2c8adf1f659f7e6b77
2
+ SHA256:
3
+ metadata.gz: 6d98212066f5ac93fe21031a01671d3ff844b63839b916aa59bdbf83b6c93d9f
4
+ data.tar.gz: 1a54f4773bcae58fe0e44f3aecef78f79908a57d137e90edc7dd9d1a1efc5ac6
5
5
  SHA512:
6
- metadata.gz: d813e7bcdae763cd440088a3d71d37164d9758f5f8f23d11c8dff9328f1811c6dbce53f28771bb592c43bc31748199b84a77e93658460ec2c29c1d51fc8af39c
7
- data.tar.gz: f5eaae71f1dc5fe2e92ec1e2273108ba187dd0c481e8ad84bd5122998e26d17bd9d022358614546afb9b8b1a0fc4b95706d6a7acd8951e86a773a9ddfed5e467
6
+ metadata.gz: a0e372bf08248ffb06ae896fd9c8c182d1da90ed3c947fb5e0c2e9b09168910781926960beb29739d67f7a265e5eeb4f7ff4702d7b3da058058745b51c4b1a88
7
+ data.tar.gz: 8df400686e4d15a9cd0cd33ff70e5182c91aea9fd33e57a399b7470c92130f43ec50833aeccdf28daecc347bdeb011843b7721eed51ad44706fb537320e80036
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
1
  # Change Log
2
2
 
3
- ## 0.1.0 (2016-09-30) (initial release)
3
+ ## 0.2.0 (2020-01-09)
4
+
5
+ ### Important Notice
6
+ This version changes the whole interface of the gem. In case you used it, it will require changes.
7
+ Also please note that the documentation wasn't changed yet.
8
+
9
+ ### Changed
10
+ * Mostly everything.
11
+ * Rails 6 support
12
+
13
+ ## 0.1.0 (2016-09-28) (initial release)
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in jquery-tablesorter-rails-utils.gemspec
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Jquery::Tablesorter::Rails::Utils
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/jquery-tablesorter-rails-utils.svg)](https://badge.fury.io/rb/jquery-tablesorter-rails-utils)
4
+
3
5
  Helpful (hopefully! ;-) ) additions for jQuery tablesorter (only support for [Mottie's fork] targeted) when working with rails.
4
6
 
5
7
  While still in early development - which might bring breaking changes with new releases - it is meant to provide helpful utilities for jquery-tablesorter in rails. At the current state of development it only supports a mechanism to help to work with Ajax based tables.
@@ -26,7 +28,9 @@ Or install it yourself as:
26
28
 
27
29
  $ gem install jquery-tablesorter-rails-utils
28
30
 
29
- ## Usage
31
+ ## Usage (Attention: OUTDATED!)
32
+
33
+ !!! The following information might not fully apply to version 0.2.0 !!!
30
34
 
31
35
  ### Module: Ajax
32
36
 
data/Rakefile CHANGED
@@ -1,2 +1,4 @@
1
- require "bundler/gem_tasks"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
2
4
  task default: :spec
@@ -1,5 +1,6 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'jquery-tablesorter/rails-utils/version'
5
6
 
@@ -14,18 +15,19 @@ Gem::Specification.new do |spec|
14
15
  spec.homepage = 'https://github.com/themilkman/jquery-tablesorter-rails-utils'
15
16
  spec.license = 'MIT'
16
17
 
17
- spec.required_ruby_version = '>= 1.9.3'
18
18
 
19
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ spec.required_ruby_version = '>= 2.4.0'
20
+
21
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
22
  f.match(%r{^(test|spec|features)/})
21
23
  end
22
24
 
23
25
  spec.require_paths = ['lib']
24
26
 
25
- spec.add_dependency 'activerecord', '>= 4.0', '< 6.0'
26
- spec.add_dependency 'activesupport', '>= 4.0', '< 6.0'
27
- spec.add_dependency 'actionview', '>= 4.0', '< 6.0'
28
27
  spec.add_dependency 'pg'
28
+ spec.add_dependency 'actionview', '>= 5.0', '< 7.0'
29
+ spec.add_dependency 'activerecord', '>= 5.0', '< 7.0'
30
+ spec.add_dependency 'activesupport', '>= 5.0', '< 7.0'
29
31
 
30
32
  spec.add_development_dependency 'bundler', '~> 1.13'
31
33
  spec.add_development_dependency 'rake', '~> 10.0'
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'jquery-tablesorter/rails-utils/version'
2
4
  require 'jquery-tablesorter/rails-utils/ajax'
@@ -1,20 +1,6 @@
1
- # Adds mechanisms to work with Ajax based tables and tablesorter.
2
- # Current limitions (extract ;-P):
3
- # * It does not support sorting by multiple columns.
4
- # * Currently only PostgreSQL is supported
5
- #
6
- # Usage:
7
- # Includet this module in your controller and call methods in your query-action,
8
- # where the results can be used to build the response.
9
- #
10
- # Further ToDos/plans/ideas/dreams:
11
- # * There might be a possibility to pass a block for each column-operation such
12
- # as filtering or sorting and allow more dynamic work. This might happen before or better
13
- # instead the standard processing. (partly done with the filter_mapping filter-parameter)
14
- # * Maybe it'd be possible to allow multi-column sorting somehow.
15
- # * In some cases it could make sense not to cast all columns to strings/varchars. So, an optionally passed
16
- # type for a column might get evaluated/used in a different manner. (done for DateTime)
1
+ # frozen_string_literal: true
17
2
 
3
+ # Adds mechanisms to work with Ajax based tables and tablesorter.
18
4
  module JqueryTablesorter
19
5
  module RailsUtils
20
6
  module Ajax
@@ -1,39 +1,52 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Controller concern to help with ajax jquery tablesorter requests.
2
4
  # It handles sorting and filtering.
3
-
5
+ # Current limitions (extract ;-P):
6
+ # * It does not support sorting by multiple columns.
7
+ #
8
+ # Usage:
9
+ # Include module in controller and call methods in query-action,
10
+ # where the results can be used to build the response.
11
+ #
12
+ # Further ToDos/plans/ideas/dreams:
13
+ # * Also, there might be a possibility to pass a block for each column-operation such
14
+ # as filtering or sorting and allow more dynamic work. This might happen before or better
15
+ # instead the standard processing.
16
+ # * Maybe it'd be possible to allow multi-column sorting somehow.
17
+ # * In some cases it could make sense not to cast all columns to strings/varchars. So, an optionally passed
18
+ # type for a column might get evaluated/used in a different manner.
19
+ # * Evaluate if the position of a column should be passed to the columns (in other words: useful?!)
4
20
  module JqueryTablesorter
5
21
  module RailsUtils
6
22
  module Ajax
7
23
  module ActionController
8
24
  extend ActiveSupport::Concern
9
25
 
10
-
11
26
  # A generalized method to handle tablesorter queries. It's meant to be used in the corresponding
12
27
  # Controller action. Params:
13
28
  # clazz: The model's primary class
14
29
  # base_query: If there are any relevant joins or so -> pass the AR relation here
15
30
  # partial (optional): path to the partial to be rendered
16
- def create_query_html_response(base_query, partial: 'row')
17
- resp_data = ts_ajax_handler.query_data(base_query)
31
+ def create_query_html_response(base_query, partial: 'row', locals: {})
32
+ resp_data = ts_ajax_handler.query_data(base_query)
33
+ records = resp_data.delete(:records)
34
+ resp_data[:data] = render_response_html(records, partial: partial, locals: locals)
18
35
 
19
- records = resp_data.delete(:records)
20
- resp_data[:data] = render_response_html(records, partial: partial)
21
-
22
- return resp_data
36
+ resp_data
23
37
  end
24
38
 
25
39
  private
26
40
 
27
41
  # Render the html rows for the given records and an optional named partial.
28
42
  # Returns HTML string or nil
29
- def render_response_html(records, partial: 'row' )
30
- output = render_to_string partial: partial, locals: { records: records }
43
+ def render_response_html(records, partial: 'row', locals: {} )
44
+ output = render_to_string(partial: partial, locals: { records: records }.merge(locals))
31
45
 
32
- unless records.any? # if the query had 0 results, it will return a string which has let jquery crash
33
- output = nil
34
- end
46
+ # if the query has no results, it will return a string which causes jquery to crash
47
+ output = nil unless records.any?
35
48
 
36
- return output
49
+ output
37
50
  end
38
51
 
39
52
  def ts_ajax_handler
@@ -41,11 +54,12 @@ module JqueryTablesorter
41
54
  end
42
55
 
43
56
  def tablesorter_params
44
- params.permit(:page, :size, :controller, :action, :query, :sort, :filter,
45
- { sort: params[:sort].try(:keys) },
46
- { filter: params[:filter].try(:keys) })
57
+ params.permit(
58
+ :page, :size, :controller, :action, :query, :sort, :filter,
59
+ { sort: params[:sort].try(:keys) },
60
+ { filter: params[:filter].try(:keys) }
61
+ )
47
62
  end
48
-
49
63
  end
50
64
  end
51
65
  end
@@ -1,60 +1,61 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JqueryTablesorter
2
4
  module RailsUtils
3
5
  module Ajax
4
- # Represents a table sorting Filter. In most cases this is also a column
5
- # in your table, but might als be a global/external filter.
6
+ # Represents a table sorting Filter.
6
7
  class Filter
7
- # Name of the column in the DB. Used for queries, but may also be :all for glob. filters.
8
- attr_accessor :column_name
9
- # Class of the base model.
10
- attr_accessor :model
11
- # If you need to join, this is your relation table
12
- attr_accessor :join_rel
13
- # An external table column to be used with join.
14
- attr_accessor :external_column
15
- # If a having clase is required, pass it here. This will change the controll flow on
16
- # filter-/sorting.
17
- attr_accessor :having_clause
18
- # Optional data type of the column. This might be used to make queries more flexible.
19
- # For examaple, if DateTime is passed, it will strip away milliseconds from query.
20
- attr_accessor :data_type
21
- # Optional boolean filter if the given filter is a global filter or not.
22
- attr_accessor :global_filter
23
- # Optional index requested by tablesorter, needed for glob. filters.
24
- attr_accessor :position
25
- # Optional block to modify the real input of filters to match UI (e.g. Input: 'Iceland' => DB: 'is')
26
- # This block has to return an array which will be used for an IN-Query. Thus, the current implementation
27
- # depends on an 1:1 match.
28
- attr_accessor :filter_mapping
29
-
30
- def initialize(column_name, model_clazz, opts = {})
31
- @column_name = column_name
32
- @model = model_clazz
33
- @position = opts[:position]
34
- @join_rel = opts[:join_rel]
35
- @external_column = opts[:external_column]
36
- @having_clause = opts[:having_clause]
37
- @data_type = opts[:data_type]
38
- @global_filter = opts[:global_filter]
39
- @filter_mapping = opts[:filter_mapping]
40
- end
41
-
42
- def global_filter?
43
- @global_filter || false
44
- end
45
-
46
- def name
47
- self.column_name
48
- end
49
-
50
- def model_class
51
- self.model
52
- end
53
-
54
- def external?
55
- external_column.present?
8
+ attr_reader :position, :options
9
+
10
+ def initialize(position, options = {})
11
+ @position = position || (options[:global] ? 999 : nil)
12
+ @options = options
13
+ end
14
+
15
+ # dummy filter that will does nothing
16
+ def noop?
17
+ !!@options[:noop]
18
+ end
19
+
20
+ # filter that is only applied on global filtering
21
+ def global?
22
+ @options[:global] || false
23
+ end
24
+
25
+ # data type of column for special handling
26
+ def data_type
27
+ @options[:data_type].presence
28
+ end
29
+
30
+ # model class that has the specified column
31
+ def klass
32
+ @options[:class].presence
56
33
  end
57
34
 
35
+ # column that should be filtered on
36
+ def column
37
+ @options[:column].presence
38
+ end
39
+
40
+ # proc for filtering/mapping values
41
+ def values
42
+ @options[:values].presence
43
+ end
44
+
45
+ # proc for custom query modifications
46
+ def query
47
+ @options[:query].presence
48
+ end
49
+
50
+ # proc for custom column sorter
51
+ def sorter_query
52
+ @options[:sorter_query].presence
53
+ end
54
+
55
+ # string with sql having condition
56
+ def having
57
+ @options[:having].presence
58
+ end
58
59
  end
59
60
  end
60
61
  end
@@ -1,19 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JqueryTablesorter
2
4
  module RailsUtils
3
5
  module Ajax
4
6
  # Class used by ActionController concern. Encapsulates query logic.
5
7
  # For further documentation see ajax-module.
6
8
  class Handler
7
-
8
9
  def initialize(tablesorter_params)
9
10
  @ts_params = tablesorter_params
10
11
  end
11
12
 
12
13
  # Define the table structure
13
- def create_filter_info(column_name, model_clazz, filter_opts = {})
14
- filter = Filter.new(column_name, model_clazz, filter_opts)
14
+ def create_filter_info(position, options = {})
15
+ filter = Filter.new(position, options)
16
+
15
17
  ajax_filters << filter
16
- return filter
18
+
19
+ filter
17
20
  end
18
21
 
19
22
  # Load data for the given tablesorter params in a controller action
@@ -24,40 +27,40 @@ module JqueryTablesorter
24
27
  # filtered_rows: How many records are left after filtering
25
28
  # records: An collection with the resulting records
26
29
  def query_data(base_query)
27
- @query = base_query
28
-
29
- result = Hash.new
30
+ query = base_query
31
+ result = Hash.new
30
32
 
31
33
  # Filters
32
- @query = apply_filters(@query, tablesorter_params)
34
+ query = apply_filters(query, tablesorter_params)
33
35
 
34
36
  # Calculate row counts
35
- rec_counts = record_counts(base_query, @query)
37
+ rec_counts = record_counts(base_query, query)
36
38
  result[:filtered_rows] = rec_counts[:filtered_rows]
37
39
  result[:total_rows] = rec_counts[:total_rows]
38
40
 
39
41
  # Handle paging afterwards
40
- @query = handle_pagination(@query, tablesorter_params, result)
42
+ query = handle_pagination(query, tablesorter_params, result)
41
43
 
42
44
  # Sorting
43
- @query = apply_sorting(@query, tablesorter_params)
45
+ query = apply_sorting(query, tablesorter_params)
44
46
 
45
- result[:records] = @query
47
+ result[:records] = query
46
48
 
47
- return result
49
+ result
48
50
  end
49
51
 
52
+ private
53
+
50
54
  # Calulate count of all and filtered records
51
55
  # Params:
52
56
  # model_query: The base query of the current selection
53
57
  # filtered_query: The filtered query (relation with applied tablesorter filters)
54
58
  def record_counts(model_query, filtered_query)
55
- counts = Hash.new
56
- total = model_query.distinct.count(:id)
59
+ counts = Hash.new
60
+ total = model_query.distinct.count(:id)
57
61
 
58
- if total.is_a?(Hash) # Handle results of joined queries. This feels a little bit hacky.
59
- total = total.keys.length
60
- end
62
+ # Handle results of joined queries. This feels a little bit hacky.
63
+ total = total.keys.length if total.is_a?(Hash)
61
64
 
62
65
  counts[:total_rows] = total
63
66
 
@@ -65,183 +68,148 @@ module JqueryTablesorter
65
68
  # Count again if additional filters were applied (fires a query)
66
69
  cnt = filtered_query.count("#{model_query.table_name}.id")
67
70
 
68
- if cnt.is_a?(Hash) # Handle results of having-queries. This feels a little bit hacky.
69
- cnt = cnt.keys.length
70
- end
71
+ # Handle results of having-queries. This feels a little bit hacky.
72
+ cnt = cnt.keys.length if cnt.is_a?(Hash)
73
+
71
74
  counts[:filtered_rows] = cnt
72
75
  else
73
76
  counts[:filtered_rows] = total # There wasn't any reduction.
74
77
  end
75
78
 
76
- return counts
79
+ counts
77
80
  end
78
81
 
82
+ # add filter query to sql
83
+ def apply_filter(query, filter, value)
84
+ return [query] if query.blank? || filter.blank? || value.blank?
85
+ return [query] if filter.noop?
79
86
 
80
- # let every special case be handled within that block.
81
- # block should remove the values from the params parameter to allow regular processing.
82
- def apply_filters(record_relation, filter_params)
83
- splat_global_filter(filter_params)
84
- record_relation = apply_global_filters(record_relation, filter_params)
87
+ klass = filter.klass || query.klass
88
+ column = filter.column
89
+ value = filter.values.call(value) if filter.values.present?
85
90
 
86
- # iterate over all filter inputs
87
- (filter_params[:filter] || {}).each do |filter_index, filter_value|
88
- sel_col = ajax_filters[filter_index.to_i]
89
- next if sel_col.blank?
90
-
91
- clazz = sel_col.model
92
- selected_column = sel_col.name
93
-
94
- if sel_col.external? # query an external model
95
- ext_query = "LOWER(#{sel_col.join_rel}.#{sel_col.external_column}::varchar) LIKE LOWER(?)"
96
- record_relation = record_relation.where(ext_query, "%#{filter_value}%")
97
-
98
- elsif sel_col.having_clause
99
- clause = sel_col.having_clause
100
- record_relation = record_relation.having("LOWER((#{clause})::varchar) LIKE ?", "%#{filter_value}%")
101
-
102
- elsif sel_col.filter_mapping # there were modifications on the query
103
- target_col = "#{clazz.table_name}.#{selected_column}"
104
- values = sel_col.filter_mapping.call(filter_value)
105
- # Maybe we could use an SIMILAR TO query for this.
106
- record_relation = record_relation.where("LOWER(#{target_col}::varchar) IN (?)", values )
107
-
108
- else # directly on current model
109
- target_col = "#{clazz.table_name}.#{selected_column}"
110
- if sel_col.data_type == DateTime
111
- target_col = "date_trunc('minute', #{target_col})"
91
+ queries = []
92
+
93
+ if column.present?
94
+ target_column = "#{klass.table_name}.#{column}"
95
+
96
+ if filter.data_type == DateTime
97
+ target_column = "date_trunc('second', #{target_column})"
98
+ end
99
+
100
+ vals = Array(value)
101
+ value = []
102
+ q = []
103
+
104
+ vals.each do |val|
105
+ if klass.columns_hash[column.to_s] && klass.columns_hash[column.to_s].type == :integer && !(val.to_s.strip =~ /\A\d+\Z/)
106
+ q << '0 = 1'
107
+ else
108
+ q << "LOWER(#{target_column}::varchar) LIKE LOWER(?)"
109
+ value << "%#{val}%"
112
110
  end
113
- record_relation = record_relation.where("LOWER(#{target_col}::varchar) LIKE LOWER(?)", "%#{filter_value}%" )
114
111
  end
115
112
 
113
+ queries << "(#{q.join(' OR ')})" if q.any?
114
+ elsif filter.query.present?
115
+ query, query_list, value_list = filter.query.call(query, value)
116
+ queries = Array(query_list)
117
+ value = Array(value_list)
118
+ elsif filter.having.present?
119
+ query = query.having("LOWER((#{filter.having})::varchar) LIKE ?", "%#{Array(value).first}%")
116
120
  end
117
121
 
118
- return record_relation
122
+ [query, queries, value]
119
123
  end
120
124
 
121
- # Sort the passed relation by the tablesorter-sorting.
122
- def apply_sorting(record_relation, sort_params)
123
- (sort_params[:sort] || {}).each do |sort_index, order|
124
- order = (order.to_i % 2 == 0) ? :asc : :desc
125
- sel_col = ajax_filters[sort_index.to_i]
125
+ # apply global filter value for all column filters
126
+ def apply_global_filters(query, filter_params)
127
+ value = filter_params[:filter][999.to_s] rescue nil
126
128
 
127
- if sel_col.external?
128
- order_query = [sel_col.join_rel, sel_col.external_column].compact.join('.')
129
- record_relation = record_relation.order("#{order_query} #{order}")
129
+ return query if value.blank?
130
130
 
131
- elsif sel_col.having_clause
132
- # If there is a having_clause, use the column name w/o tablename
133
- record_relation = record_relation.order("#{sel_col.name} #{order} NULLS LAST")
131
+ queries = []
132
+ values = []
134
133
 
135
- else
136
- order_query = [sel_col.model.table_name, sel_col.name].compact.join('.')
137
- record_relation = record_relation.order("#{order_query} #{order} NULLS LAST")
138
- end
134
+ # iterate over all filter inputs
135
+ ajax_filters.each do |filter|
136
+ next if filter.blank?
137
+ next if filter.having.present?
138
+
139
+ query, q, v = apply_filter(query, filter, value)
139
140
 
141
+ next if q.blank?
142
+
143
+ queries += Array(q)
144
+ values += Array(v) unless v.nil?
140
145
  end
141
146
 
142
- return record_relation
147
+ query.where(queries.join(' OR '), *values)
143
148
  end
144
149
 
145
- # Paginiation/the amount of visible rows in the table (per page)
146
- def handle_pagination(query, ts_params, result)
147
- # Tablesorter submits row count or simply 'all'. If user requests more rows
148
- # than available do nothing.
149
- return query if ( (ts_params[:size] == 'all') || (ts_params[:size].to_i >= result[:total_rows]) )
150
+ # apply individual column filters
151
+ def apply_filters(query, filter_params)
152
+ query = apply_global_filters(query, filter_params)
150
153
 
151
- query = query
152
- .limit(ts_params[:size].to_i)
153
- .offset(ts_params[:size].to_i * ts_params[:page].to_i)
154
+ queries = []
155
+ values = []
154
156
 
155
- return query
156
- end
157
+ # iterate over all filter inputs
158
+ (filter_params[:filter] || {}).each do |idx, value|
159
+ ajax_filters.select { |f| f.position == idx.to_i }.each do |filter|
160
+ next if filter.blank?
161
+ next if filter.global?
157
162
 
158
- # Array with all currently configured Filter-Objects
159
- def ajax_filters
160
- @_ajax_table_filters ||= []
161
- end
163
+ query, q, v = apply_filter(query, filter, value)
162
164
 
163
- private
165
+ next if q.blank?
164
166
 
165
- def tablesorter_params
166
- @ts_params
167
+ queries += Array(q)
168
+ values += Array(v) unless v.nil?
169
+ end
170
+ end
171
+
172
+ query.where(queries.join(' AND '), *values)
167
173
  end
168
174
 
169
- # Iterate over all columns with the (previous in *splat_global_filter* initialized)
170
- # global filter value
171
- def apply_global_filters(record_relation, filter_params)
172
- # TODO Wouldn't it be smarter to make query an array and join it by ' OR '?
173
- query = ''
174
- filter_values = []
175
-
176
- (filter_params[:global_filter] || {}).each do |filter_index, filter_value|
177
- sel_col = ajax_filters[filter_index.to_i]
178
- next if sel_col.blank?
179
-
180
- clazz = sel_col.model
181
- selected_column = sel_col.name
182
- table_name = clazz.table_name
183
-
184
- if sel_col.external? # Query an external model
185
- query << "LOWER(#{sel_col.join_rel}.#{sel_col.external_column}::varchar) LIKE LOWER(?) OR "
186
- filter_values << "%#{filter_value}%"
187
-
188
- elsif sel_col.filter_mapping # there were modifications on the query
189
- target_col = "#{clazz.table_name}.#{selected_column}"
190
- values = sel_col.filter_mapping.call(filter_value)
191
- # Maybe we could use an SIMILAR TO query for this.
192
- query << "LOWER(#{target_col}::varchar) IN (?) OR "
193
- filter_values << values
194
-
195
- elsif sel_col.having_clause
196
- # Having clauses will create an extra query to select IDs of base-table records
197
- # an add them into the main query as IN <ids>.
198
- # If there is a having_clause, use the column name only w/o tablename.
199
- clause = "LOWER(#{sel_col.having_clause}::varchar) LIKE LOWER(?)"
200
- filter_values << record_relation.having(clause, "%#{filter_value}%")
201
- .pluck(:id)
202
- query << "#{table_name}.id IN (?) OR "
175
+ # Sort the passed relation by the tablesorter-sorting.
176
+ def apply_sorting(query, sort_params)
177
+ (sort_params[:sort] || {}).each do |idx, order|
178
+ order = (order.to_i % 2 == 0) ? :asc : :desc
179
+ filter = ajax_filters.find { |f| f.position == idx.to_i }
203
180
 
204
- else
205
- target_col = "#{table_name}.#{selected_column}"
181
+ next if filter.blank?
206
182
 
207
- if sel_col.data_type == DateTime # Special handling for Dates -> strip away millisecs
208
- target_col = "date_trunc('second', #{target_col})"
209
- end
183
+ klass = filter.klass || query.klass
184
+ column = filter.column
210
185
 
211
- query << "LOWER(#{target_col}::varchar) LIKE LOWER(?) OR "
212
- filter_values << "%#{filter_value}%"
186
+ if filter.sorter_query.present?
187
+ query = filter.sorter_query.call(query, order)
188
+ else
189
+ query = query.reorder("#{klass.table_name}.#{column} #{order} NULLS LAST")
213
190
  end
214
191
  end
215
192
 
216
- query = query.chomp(' OR ') # remove the last OR
193
+ query
194
+ end
217
195
 
218
- return record_relation.where(query, *filter_values)
196
+ # Paginiation/the amount of visible rows in the table (per page)
197
+ def handle_pagination(query, ts_params, result)
198
+ # Tablesorter submits row count or simply 'all'. If user requests more rows
199
+ # than available do nothing.
200
+ return query if (ts_params[:size] == 'all') || (ts_params[:size].to_i >= result[:total_rows])
219
201
 
202
+ query.limit(ts_params[:size].to_i).offset(ts_params[:size].to_i * ts_params[:page].to_i)
220
203
  end
221
204
 
222
- # If any global filter value (the user input) is found (which currently is asumed to the last),
223
- # take this input and add it to a global_filter subkey with the corresponding index of each
224
- # not global-filter column. Thus, later the may be used to check all coulmns for the given
225
- # input.
226
- def splat_global_filter(filter_params)
227
- # Global filter params is assumed to be at the last index
228
- global_filter = ajax_filters.find { |c| c.global_filter? }
229
- return unless global_filter
230
-
231
- global_filter_value = filter_params.dig(:filter, global_filter.position.to_s)
232
- return if global_filter_value.nil?
233
-
234
- filter_params[:global_filter] ||= {}
235
- ajax_filters.each_with_index do |col, idx|
236
- next if (col.nil? || col.global_filter?)
237
- # Add search query for each (non-global) value
238
- filter_params[:global_filter][idx.to_s] = global_filter_value
239
- end
240
-
241
- # Remove the global filter from the params
242
- filter_params[:filter].delete(global_filter.position.to_s)
205
+ # Array with all currently configured Filter-Objects
206
+ def ajax_filters
207
+ @_ajax_table_filters ||= []
243
208
  end
244
209
 
210
+ def tablesorter_params
211
+ @ts_params
212
+ end
245
213
  end
246
214
  end
247
215
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JqueryTablesorter
2
4
  module RailsUtils
3
5
  MAJOR = 0
4
- MINOR = 0
5
- TINY = 1
6
+ MINOR = 2
7
+ TINY = 0
6
8
 
7
9
  VERSION = [MAJOR, MINOR, TINY].compact.join('.')
8
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jquery-tablesorter-rails-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik-B. Ernst
@@ -9,82 +9,82 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-09-30 00:00:00.000000000 Z
12
+ date: 2020-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: activerecord
15
+ name: pg
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '4.0'
21
- - - "<"
22
- - !ruby/object:Gem::Version
23
- version: '6.0'
20
+ version: '0'
24
21
  type: :runtime
25
22
  prerelease: false
26
23
  version_requirements: !ruby/object:Gem::Requirement
27
24
  requirements:
28
25
  - - ">="
29
26
  - !ruby/object:Gem::Version
30
- version: '4.0'
31
- - - "<"
32
- - !ruby/object:Gem::Version
33
- version: '6.0'
27
+ version: '0'
34
28
  - !ruby/object:Gem::Dependency
35
- name: activesupport
29
+ name: actionview
36
30
  requirement: !ruby/object:Gem::Requirement
37
31
  requirements:
38
32
  - - ">="
39
33
  - !ruby/object:Gem::Version
40
- version: '4.0'
34
+ version: '5.0'
41
35
  - - "<"
42
36
  - !ruby/object:Gem::Version
43
- version: '6.0'
37
+ version: '7.0'
44
38
  type: :runtime
45
39
  prerelease: false
46
40
  version_requirements: !ruby/object:Gem::Requirement
47
41
  requirements:
48
42
  - - ">="
49
43
  - !ruby/object:Gem::Version
50
- version: '4.0'
44
+ version: '5.0'
51
45
  - - "<"
52
46
  - !ruby/object:Gem::Version
53
- version: '6.0'
47
+ version: '7.0'
54
48
  - !ruby/object:Gem::Dependency
55
- name: actionview
49
+ name: activerecord
56
50
  requirement: !ruby/object:Gem::Requirement
57
51
  requirements:
58
52
  - - ">="
59
53
  - !ruby/object:Gem::Version
60
- version: '4.0'
54
+ version: '5.0'
61
55
  - - "<"
62
56
  - !ruby/object:Gem::Version
63
- version: '6.0'
57
+ version: '7.0'
64
58
  type: :runtime
65
59
  prerelease: false
66
60
  version_requirements: !ruby/object:Gem::Requirement
67
61
  requirements:
68
62
  - - ">="
69
63
  - !ruby/object:Gem::Version
70
- version: '4.0'
64
+ version: '5.0'
71
65
  - - "<"
72
66
  - !ruby/object:Gem::Version
73
- version: '6.0'
67
+ version: '7.0'
74
68
  - !ruby/object:Gem::Dependency
75
- name: pg
69
+ name: activesupport
76
70
  requirement: !ruby/object:Gem::Requirement
77
71
  requirements:
78
72
  - - ">="
79
73
  - !ruby/object:Gem::Version
80
- version: '0'
74
+ version: '5.0'
75
+ - - "<"
76
+ - !ruby/object:Gem::Version
77
+ version: '7.0'
81
78
  type: :runtime
82
79
  prerelease: false
83
80
  version_requirements: !ruby/object:Gem::Requirement
84
81
  requirements:
85
82
  - - ">="
86
83
  - !ruby/object:Gem::Version
87
- version: '0'
84
+ version: '5.0'
85
+ - - "<"
86
+ - !ruby/object:Gem::Version
87
+ version: '7.0'
88
88
  - !ruby/object:Gem::Dependency
89
89
  name: bundler
90
90
  requirement: !ruby/object:Gem::Requirement
@@ -144,15 +144,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
144
  requirements:
145
145
  - - ">="
146
146
  - !ruby/object:Gem::Version
147
- version: 1.9.3
147
+ version: 2.4.0
148
148
  required_rubygems_version: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  requirements: []
154
- rubyforge_project:
155
- rubygems_version: 2.5.1
154
+ rubygems_version: 3.1.2
156
155
  signing_key:
157
156
  specification_version: 4
158
157
  summary: Some helpers to work with jQuery tablesorter and Ruby on Rails