jquery-tablesorter-rails-utils 0.0.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![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,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
|