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 +5 -5
- data/CHANGELOG.md +11 -1
- data/Gemfile +2 -0
- data/README.md +5 -1
- data/Rakefile +3 -1
- data/jquery-tablesorter-rails-utils.gemspec +9 -7
- data/lib/jquery-tablesorter-rails-utils.rb +2 -0
- data/lib/jquery-tablesorter/rails-utils/ajax.rb +2 -16
- data/lib/jquery-tablesorter/rails-utils/ajax/action_controller.rb +32 -18
- data/lib/jquery-tablesorter/rails-utils/ajax/filter.rb +52 -51
- data/lib/jquery-tablesorter/rails-utils/ajax/handler.rb +120 -152
- data/lib/jquery-tablesorter/rails-utils/version.rb +4 -2
- metadata +26 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6d98212066f5ac93fe21031a01671d3ff844b63839b916aa59bdbf83b6c93d9f
|
4
|
+
data.tar.gz: 1a54f4773bcae58fe0e44f3aecef78f79908a57d137e90edc7dd9d1a1efc5ac6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Jquery::Tablesorter::Rails::Utils
|
2
2
|
|
3
|
+
[](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,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
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.
|
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,20 +1,6 @@
|
|
1
|
-
#
|
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
|
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
|
-
|
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
|
43
|
+
def render_response_html(records, partial: 'row', locals: {} )
|
44
|
+
output = render_to_string(partial: partial, locals: { records: records }.merge(locals))
|
31
45
|
|
32
|
-
|
33
|
-
|
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
|
-
|
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(
|
45
|
-
|
46
|
-
{
|
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.
|
5
|
-
# in your table, but might als be a global/external filter.
|
6
|
+
# Represents a table sorting Filter.
|
6
7
|
class Filter
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def
|
31
|
-
@
|
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(
|
14
|
-
filter = Filter.new(
|
14
|
+
def create_filter_info(position, options = {})
|
15
|
+
filter = Filter.new(position, options)
|
16
|
+
|
15
17
|
ajax_filters << filter
|
16
|
-
|
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
|
-
|
28
|
-
|
29
|
-
result = Hash.new
|
30
|
+
query = base_query
|
31
|
+
result = Hash.new
|
30
32
|
|
31
33
|
# Filters
|
32
|
-
|
34
|
+
query = apply_filters(query, tablesorter_params)
|
33
35
|
|
34
36
|
# Calculate row counts
|
35
|
-
rec_counts = record_counts(base_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
|
-
|
42
|
+
query = handle_pagination(query, tablesorter_params, result)
|
41
43
|
|
42
44
|
# Sorting
|
43
|
-
|
45
|
+
query = apply_sorting(query, tablesorter_params)
|
44
46
|
|
45
|
-
result[:records] =
|
47
|
+
result[:records] = query
|
46
48
|
|
47
|
-
|
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
|
56
|
-
total
|
59
|
+
counts = Hash.new
|
60
|
+
total = model_query.distinct.count(:id)
|
57
61
|
|
58
|
-
|
59
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
-
|
122
|
+
[query, queries, value]
|
119
123
|
end
|
120
124
|
|
121
|
-
#
|
122
|
-
def
|
123
|
-
|
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
|
-
|
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
|
-
|
132
|
-
|
133
|
-
record_relation = record_relation.order("#{sel_col.name} #{order} NULLS LAST")
|
131
|
+
queries = []
|
132
|
+
values = []
|
134
133
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
147
|
+
query.where(queries.join(' OR '), *values)
|
143
148
|
end
|
144
149
|
|
145
|
-
#
|
146
|
-
def
|
147
|
-
|
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
|
-
|
152
|
-
|
153
|
-
.offset(ts_params[:size].to_i * ts_params[:page].to_i)
|
154
|
+
queries = []
|
155
|
+
values = []
|
154
156
|
|
155
|
-
|
156
|
-
|
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
|
-
|
159
|
-
def ajax_filters
|
160
|
-
@_ajax_table_filters ||= []
|
161
|
-
end
|
163
|
+
query, q, v = apply_filter(query, filter, value)
|
162
164
|
|
163
|
-
|
165
|
+
next if q.blank?
|
164
166
|
|
165
|
-
|
166
|
-
|
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
|
-
#
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
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
|
-
|
205
|
-
target_col = "#{table_name}.#{selected_column}"
|
181
|
+
next if filter.blank?
|
206
182
|
|
207
|
-
|
208
|
-
|
209
|
-
end
|
183
|
+
klass = filter.klass || query.klass
|
184
|
+
column = filter.column
|
210
185
|
|
211
|
-
|
212
|
-
|
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
|
193
|
+
query
|
194
|
+
end
|
217
195
|
|
218
|
-
|
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
|
-
#
|
223
|
-
|
224
|
-
|
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
|
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
|
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:
|
12
|
+
date: 2020-01-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: pg
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
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: '
|
31
|
-
- - "<"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '6.0'
|
27
|
+
version: '0'
|
34
28
|
- !ruby/object:Gem::Dependency
|
35
|
-
name:
|
29
|
+
name: actionview
|
36
30
|
requirement: !ruby/object:Gem::Requirement
|
37
31
|
requirements:
|
38
32
|
- - ">="
|
39
33
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
34
|
+
version: '5.0'
|
41
35
|
- - "<"
|
42
36
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
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: '
|
44
|
+
version: '5.0'
|
51
45
|
- - "<"
|
52
46
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
47
|
+
version: '7.0'
|
54
48
|
- !ruby/object:Gem::Dependency
|
55
|
-
name:
|
49
|
+
name: activerecord
|
56
50
|
requirement: !ruby/object:Gem::Requirement
|
57
51
|
requirements:
|
58
52
|
- - ">="
|
59
53
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
54
|
+
version: '5.0'
|
61
55
|
- - "<"
|
62
56
|
- !ruby/object:Gem::Version
|
63
|
-
version: '
|
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: '
|
64
|
+
version: '5.0'
|
71
65
|
- - "<"
|
72
66
|
- !ruby/object:Gem::Version
|
73
|
-
version: '
|
67
|
+
version: '7.0'
|
74
68
|
- !ruby/object:Gem::Dependency
|
75
|
-
name:
|
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:
|
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
|
-
|
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
|