table_sortable 0.2.0 → 0.3.0

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
  SHA1:
3
- metadata.gz: 3a484255d4071117e14633714581e5392da418bd
4
- data.tar.gz: 063b9bcd1e5dab7c85b8473f06d9b9349351df36
3
+ metadata.gz: bb3b153304402456414d809c4ebb4f20598912e1
4
+ data.tar.gz: 1bb7b72fbc3b9052bbd93da005e81f4a37dcf43d
5
5
  SHA512:
6
- metadata.gz: cff13059ff3aa2f36bed53861db9ce00eef623b90a7fc18a233c4523cba19a724ed5b3fc803fcf5687d4ddc2476f5c8356b7af10ceb42d1438a045aed7db177d
7
- data.tar.gz: 847dabaa7a749389d95c0a945e2de623d974732ddcc2a357f0d1ecf7f47f9bba9faf1590fec9121b29208aa02bee1b88f9ef53944b0eefc605711eea92b88554
6
+ metadata.gz: 54e7d680129b165ffe901e66135fb9ada66214c6696eb5b9b7e3d8c3f702cb161443bf53f769e737216e5eb62645c07cac1f4dceb5179263b06a9fc6ce5f733e
7
+ data.tar.gz: 762d3c06491fcc61f56c069b72e8a1820740bb987b3ee897b8f2dae52b48cebdfd62afede63175f8f70f11fe7270a15027c84288e9550fc1740dc1bed3b3d4f9
data/.idea/.rakeTasks CHANGED
@@ -4,4 +4,4 @@ You are allowed to:
4
4
  1. Remove rake task
5
5
  2. Add existing rake tasks
6
6
  To add existing rake tasks automatically delete this file and reload the project.
7
- --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build table_sortable-0.1.8.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Remove any temporary products" fullCmd="clean" taksId="clean" /><RakeTask description="Remove any generated files" fullCmd="clobber" taksId="clobber" /><RakeTask description="Build and install table_sortable-0.1.8.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install table_sortable-0.1.8.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v0.1.8 and build and push table_sortable-0.1.8.gem to Rubygems" fullCmd="release[remote]" taksId="release[remote]" /><RakeTask description="Run tests" fullCmd="test" taksId="test" /><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
7
+ --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build table_sortable-0.2.0.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Remove any temporary products" fullCmd="clean" taksId="clean" /><RakeTask description="Remove any generated files" fullCmd="clobber" taksId="clobber" /><RakeTask description="Build and install table_sortable-0.2.0.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install table_sortable-0.2.0.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v0.2.0 and build and push table_sortable-0.2.0.gem to Rubygems" fullCmd="release[remote]" taksId="release[remote]" /><RakeTask description="Run tests" fullCmd="test" taksId="test" /><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <module type="RUBY_MODULE" version="4">
3
3
  <component name="ModuleRunConfigurationManager">
4
- <configuration default="false" name="All specs in spec: table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec" temporary="true">
4
+ <configuration default="false" name="All specs in spec: table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec">
5
5
  <predefined_log_file id="RUBY_RSPEC" enabled="true" />
6
6
  <module name="table_sortable" />
7
7
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
@@ -34,7 +34,7 @@
34
34
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
35
35
  <method />
36
36
  </configuration>
37
- <configuration default="false" name="Run spec 'proc_spec': table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec" temporary="true">
37
+ <configuration default="false" name="Run spec 'filter_spec': table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec">
38
38
  <predefined_log_file id="RUBY_RSPEC" enabled="true" />
39
39
  <module name="table_sortable" />
40
40
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
@@ -53,7 +53,7 @@
53
53
  </COVERAGE_PATTERN>
54
54
  </EXTENSION>
55
55
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TESTS_FOLDER_PATH" VALUE="" />
56
- <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="$MODULE_DIR$/spec/lib/table_sortable/concerns/proc_spec.rb" />
56
+ <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="$MODULE_DIR$/spec/lib/table_sortable/column/filter_spec.rb" />
57
57
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_RUNNER_PATH" VALUE="" />
58
58
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_FILE_MASK" VALUE="**/*_spec.rb" />
59
59
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_EXAMPLE_NAME" VALUE="" />
@@ -67,7 +67,7 @@
67
67
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
68
68
  <method />
69
69
  </configuration>
70
- <configuration default="false" name="Run spec 'filter_spec': table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec" temporary="true">
70
+ <configuration default="false" name="Run spec 'proc_spec': table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec">
71
71
  <predefined_log_file id="RUBY_RSPEC" enabled="true" />
72
72
  <module name="table_sortable" />
73
73
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
@@ -86,7 +86,7 @@
86
86
  </COVERAGE_PATTERN>
87
87
  </EXTENSION>
88
88
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TESTS_FOLDER_PATH" VALUE="" />
89
- <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="$MODULE_DIR$/spec/lib/table_sortable/column/filter_spec.rb" />
89
+ <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="$MODULE_DIR$/spec/lib/table_sortable/concerns/proc_spec.rb" />
90
90
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_RUNNER_PATH" VALUE="" />
91
91
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_FILE_MASK" VALUE="**/*_spec.rb" />
92
92
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_EXAMPLE_NAME" VALUE="" />
@@ -100,7 +100,7 @@
100
100
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
101
101
  <method />
102
102
  </configuration>
103
- <configuration default="false" name="TableSortable::Controller filter_and_sort filters using a single filter: table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec" temporary="true">
103
+ <configuration default="false" name="TableSortable::Controller filter_and_sort filters using a single filter: table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec">
104
104
  <predefined_log_file id="RUBY_RSPEC" enabled="true" />
105
105
  <module name="table_sortable" />
106
106
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
@@ -133,7 +133,7 @@
133
133
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
134
134
  <method />
135
135
  </configuration>
136
- <configuration default="false" name="TableSortable::Controller filter_and_sort sorts a record set based on the column to sort: table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec" temporary="true">
136
+ <configuration default="false" name="TableSortable::Controller filter_and_sort sorts a record set based on the column to sort: table_sortable" type="RSpecRunConfigurationType" factoryName="RSpec">
137
137
  <predefined_log_file id="RUBY_RSPEC" enabled="true" />
138
138
  <module name="table_sortable" />
139
139
  <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
@@ -174,11 +174,8 @@
174
174
  </content>
175
175
  <orderEntry type="jdk" jdkName="RVM: ruby-2.4.1 [tablesortable]" jdkType="RUBY_SDK" />
176
176
  <orderEntry type="sourceFolder" forTests="false" />
177
- <orderEntry type="library" scope="PROVIDED" name="actioncable (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
178
- <orderEntry type="library" scope="PROVIDED" name="actionmailer (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
179
177
  <orderEntry type="library" scope="PROVIDED" name="actionpack (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
180
178
  <orderEntry type="library" scope="PROVIDED" name="actionview (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
181
- <orderEntry type="library" scope="PROVIDED" name="activejob (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
182
179
  <orderEntry type="library" scope="PROVIDED" name="activemodel (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
183
180
  <orderEntry type="library" scope="PROVIDED" name="activerecord (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
184
181
  <orderEntry type="library" scope="PROVIDED" name="activesupport (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
@@ -190,20 +187,14 @@
190
187
  <orderEntry type="library" scope="PROVIDED" name="erubi (v1.6.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
191
188
  <orderEntry type="library" scope="PROVIDED" name="factory_girl (v4.8.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
192
189
  <orderEntry type="library" scope="PROVIDED" name="factory_girl_rails (v4.8.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
193
- <orderEntry type="library" scope="PROVIDED" name="globalid (v0.4.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
194
190
  <orderEntry type="library" scope="PROVIDED" name="i18n (v0.8.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
195
191
  <orderEntry type="library" scope="PROVIDED" name="loofah (v2.0.3, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
196
- <orderEntry type="library" scope="PROVIDED" name="mail (v2.6.5, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
197
192
  <orderEntry type="library" scope="PROVIDED" name="method_source (v0.8.2, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
198
- <orderEntry type="library" scope="PROVIDED" name="mime-types (v3.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
199
- <orderEntry type="library" scope="PROVIDED" name="mime-types-data (v3.2016.0521, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
200
193
  <orderEntry type="library" scope="PROVIDED" name="mini_portile2 (v2.1.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
201
194
  <orderEntry type="library" scope="PROVIDED" name="minitest (v5.10.2, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
202
- <orderEntry type="library" scope="PROVIDED" name="nio4r (v2.1.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
203
195
  <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.7.2, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
204
196
  <orderEntry type="library" scope="PROVIDED" name="rack (v2.0.3, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
205
197
  <orderEntry type="library" scope="PROVIDED" name="rack-test (v0.6.3, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
206
- <orderEntry type="library" scope="PROVIDED" name="rails (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
207
198
  <orderEntry type="library" scope="PROVIDED" name="rails-dom-testing (v2.0.3, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
208
199
  <orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.0.3, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
209
200
  <orderEntry type="library" scope="PROVIDED" name="railties (v5.1.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
@@ -213,13 +204,9 @@
213
204
  <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.6.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
214
205
  <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.6.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
215
206
  <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.6.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
216
- <orderEntry type="library" scope="PROVIDED" name="sprockets (v3.7.1, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
217
- <orderEntry type="library" scope="PROVIDED" name="sprockets-rails (v3.2.0, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
218
207
  <orderEntry type="library" scope="PROVIDED" name="sqlite3 (v1.3.13, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
219
208
  <orderEntry type="library" scope="PROVIDED" name="thor (v0.19.4, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
220
209
  <orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.6, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
221
210
  <orderEntry type="library" scope="PROVIDED" name="tzinfo (v1.2.3, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
222
- <orderEntry type="library" scope="PROVIDED" name="websocket-driver (v0.6.5, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
223
- <orderEntry type="library" scope="PROVIDED" name="websocket-extensions (v0.1.2, RVM: ruby-2.4.1 [tablesortable]) [gem]" level="application" />
224
211
  </component>
225
212
  </module>
data/README.md CHANGED
@@ -135,13 +135,253 @@ That's it! The results fetched from the server are now filtered, sorted and pagi
135
135
 
136
136
  For full documentation of the usage of tableSorter.js please go [here](https://mottie.github.io/tablesorter/docs/index.html) for the very popular fork by mottie, or [here](http://tablesorter.com/docs/) for the original version of the plugin.
137
137
 
138
- Of course there are many more configuration options that make TableSortable flexible and adaptable. For those, please see [advanced configuration](#advanced-configuration)
138
+ Of course there are many more configuration options that make TableSortable flexible and adaptable. For those, please see [advanced configuration](#advanced-configuration).
139
139
 
140
140
  ## Advanced Configuration
141
- Coming soon...
141
+
142
+ TableSortable has several advanced configuration settings, which allow for a more fine-grained control over its behaviour.
143
+
144
+ - [define_column](#define_column)
145
+ - [define_column_order](#define_column_order)
146
+ - [define_column_offset](#define_column_offset)
147
+
148
+ #### define_column
149
+
150
+ TableSortable lets you define the columns one by one with many custom attributes, using the `define_column` method.
151
+ ```ruby
152
+ #controllers/users_controller.rb
153
+ class UsersController < ApplicationController
154
+ include TableSortable
155
+
156
+ define_column :full_name,
157
+ value: -> (user) {"#{user.first_name} #{user.last_name}"}
158
+ define_column :email
159
+ end
160
+ ```
161
+ ##### Syntax: `define_column column_name, [arguments]`
162
+
163
+ - `column_name` <sub>(required)</sub>
164
+ A symbol representing the column_name. Can be anything, but should usually be the same as the column name.
165
+ - `arguments` <sub>(optional)</sub>
166
+ - `value: (symbol|proc)`
167
+ <sub>default: same as column name</sub>
168
+ Accepts either a symbol representing a method that the record responds to, like an ActiveRecord attribute,
169
+ or a proc the returns the record's value. for example:
170
+ ```ruby
171
+ define_column :full_name,
172
+ value: -> (user) {"#{user.first_name} #{user.last_name}"}
173
+ ```
174
+ - `content: (symbol|proc)`
175
+ <sub>default: same as value</sub>
176
+ Works the same way as `value`, but allows specifying a different value to be displayed in the table cells.
177
+ The difference between `value` and `content` is that the former determines the value by which the scope will be filtered and sorted,
178
+ while the latter only affects the displayed cell contents.
179
+ ```ruby
180
+ define_column :full_name,
181
+ value: -> (user) {"#{user.first_name} #{user.last_name}"},
182
+ content: -> (user) {"#{user.last_name}, #{user.first_name}"}
183
+ ```
184
+ - `label: (string)`
185
+ <sub>default: 'Titleized' version of the column name</sub>
186
+ Allows specifying a string to be used as the column label, displayed at the table header.
187
+ - `placeholder: (string|false)`
188
+ <sub>default: same as label</sub>
189
+ Allows specifying a string to be used as a placeholder for the column's filter input field.
190
+ You may also specify `false`, in which case no placeholder will be displayed.
191
+ - `filter: (proc|false)`
192
+ <sub>default: free case-insensitive text search on the column's value</sub>
193
+ By default, the column will be filtered according to the column's value. However, you may specify a proc to perform the search on that column.
194
+ The proc itself can contain either ActiveRecord operations (eg. `where`) or array operations (eg. `select`),
195
+ and will be passed the current filter query when run.
196
+ ```ruby
197
+ define_column :full_name,
198
+ filter: ->(query) {where('LOWER(CONCAT(first_name," ", last_name)) LIKE (?)', "%#{query.downcase}%")}
199
+ ```
200
+ If no filtering is to be performed on that column you can set it to `false`. When using TableSortable's [view helpers](#view-helpers),
201
+ this also means that no filter input will be shown on that column.
202
+ - `filter_method: (:array|:active_record)`
203
+ <sub>default: automatically detects method based on the record given</sub>
204
+ Determines whether the default filter function relies on an ActiveRecord `where` method or an Array `select` method.
205
+ When no method and no filters are supplied, TableSortable will check if the column_name corresponds to a database column of the record.
206
+ If it does, it will use an ActiveRecord `where` method, otherwise it will perform an array `select` operation.
207
+ _Only applies when no `filter` option has been specified._
208
+ - `:array` <sub>(default)</sub>
209
+ Filter using the `select` method. While being slower, it selects based on the column's value, whatever it might be, and so fits every scenario.
210
+ - `:active_record`
211
+ Filter using the `where` method. While being faster, it only applies to cases where the column name matches the database column name.
212
+ - `filter_initial_value: (string)`
213
+ <sub>default: nil</sub>
214
+ You may specify an initial filter query for each column.
215
+ - `sort: (proc|false)`
216
+ <sub>default: sorting based on the column's value</sub>
217
+ By default, the record set will be sorted according to the selected column's value.
218
+ However, you may specify a proc to perform the sorting when this column is selected as the sort base.
219
+ The proc itself can contain either ActiveRecord operations (eg. `order`) or array operations (eg. `sort`),
220
+ and will be passed the current sort order as a symbol (`:asc` or `:desc`) when run.
221
+ ```ruby
222
+ define_column :full_name,
223
+ sort: -> (sort_order) { sort{ |a,b| (sort_order == :asc ? a : b) <=> (sort_order == :asc ? b : a) } }
224
+ ```
225
+ If no sorting is to be performed based on that column you can set it to `false`. When using TableSortable's [view helpers](#view-helpers),
226
+ this also means that no sorting handle will be shown on the client side on that column as well.
227
+ - `sort_method: (:array|:active_record)`
228
+ <sub>default: :array</sub>
229
+ Determines whether the default sort function relies on an ActiveRecord `order` method or an Array `sort` method.
230
+ When no method and no filters are supplied, TableSortable will check if the column_name corresponds to a database column of the record.
231
+ If it does, it will use an ActiveRecord `order` method, otherwise it will perform an array `sort` operation.
232
+ _Only applies when no `sort` option has been specified._
233
+ - `:array` <sub>(default)</sub>
234
+ Sort using the `sort` method. While being slower, it sorts based on the column's value, whatever it might be, and so fits every scenario.
235
+ - `:active_record`
236
+ Sort using the `order` method. While being faster, it only applies to cases where the column name matches the database column name.
237
+ - `template: (string)`
238
+ <sub>default: same as column_name</sub>
239
+ Allows setting a custom template name to look for when rendering the header or column contents. For more information see [view helpers](#view-helpers).
240
+
241
+ ##### Dynamic Column Definitions
242
+
243
+ If the column definitions themselves need to be dynamic (eg. if you're using
244
+ dynamic fields in your model) you can also use `define column` in a `before action` callback like this
245
+ ```ruby
246
+ #controllers/users_controller.rb
247
+
248
+ before_action :define_columns
249
+
250
+ private
251
+
252
+ def define_columns
253
+ @user.custom_fields.each do |cf|
254
+ define_column cf,
255
+ value: -> (user) {user.get_custom_field(cf)}
256
+ end
257
+ end
258
+ ```
259
+
260
+ #### define_column_order
261
+ Columns are displayed in the order they are defined using `define_method`. If you wish, you may override this order by specifying your own using the `define_column_order` method.
262
+ It also allows hiding columns that you need to include in the filtering and sorting process, eg. when you want to have an external search box filtering based on a column that you don't necessarily want to display.
263
+ ##### Syntax: `define_column_order column1, [column2], [column3] ...`
264
+ ```ruby
265
+ #controllers/users_controller.rb
266
+ #define a full_name column, allowing to create a custom search box that operates on the 4th column
267
+ define_columns :first_name, :last_name, :email, :full_name
268
+ define_column_order :last_name, :first_name, :email
269
+ ```
270
+ #### define_column_offset
271
+ Sometimes you wish to manually add columns in the views before adding the defined TableSortable columns, eg. to have a checkbox next to each row.
272
+ ```erb
273
+ <!-- views/users/index.html.erb -->
274
+ <table id="usersTable" data-query="<%= users_path %>">
275
+ <thead>
276
+ <tr></tr> <!-- EXTRA COLUMN -->
277
+ <tr>
278
+ <%= table_sortable_headers %>
279
+ </tr>
280
+ </thead>
281
+ <tbody>
282
+ </tbody>
283
+ </table>
284
+
285
+ <!-- views/users/_user_row.html.erb -->
286
+ <tr> <%= check_box_tag :checked %> </tr> <!-- EXTRA COLUMN -->
287
+ <tr>
288
+ <%= table_sortable_columns user %>
289
+ </tr>
290
+ ```
291
+ Since the column numbers that appear in tableSorter.js' ajax request will represent their actual number, you should let TableSortable know that the columns you defined are offset.
292
+ So, in the above case you should define an offset of 1.
293
+
294
+ ##### Syntax: `define_column_offset offset`
295
+ ```ruby
296
+ define_column_offset 1
297
+ ```
298
+ You may define it either using the `define_column_offset` method shown above,
299
+ or using the all inclusive `define_columns` method, as an `offset: <integer>` argument.
300
+ ```ruby
301
+ define_column :first_name, :last_name, :email, offset: 1
302
+ ```
142
303
 
143
304
  ### View Helpers
144
- Coming soon...
305
+ TableSortable offers several view helpers, to help maintain the connection between the view layer and the controller layer, and make your code DRYer and less error prone.
306
+ - [table_sortable_headers](#table_sortable_headers)
307
+ - [table_sortable_columns](#table_sortable_columns)
308
+ - [table_sortable_pager](#table_sortable_pager)
309
+
310
+ #### table_sortable_headers
311
+ ##### Syntax: `table_sortable_headers [html_attributes]`
312
+ Renders the table header columns, each one inside a \<th> tag.
313
+ Notice that it _does not_ wrap a \<tr> tag around the headers, allowing you to add columns before of after TableSortable's headers.
314
+
315
+ It also renders data attributes that let tableSorter.js know the columns behaviour:
316
+ - `data-filter="false"` if the column's `filter` attribute is set to `false`.
317
+ - `data-sorter="false"` if the column's `sort` attribute is set to `false`.
318
+ - `data-placeholder="?"` if a placeholder has been defined (defaults to be the same as the column's label).
319
+ - `data-value="?"` if an initial filter value has been defined.
320
+
321
+ You may also specify any html attribute, as well as additional data attributes to be added to each \<th> element.
322
+ ```erb
323
+ <tr> <%= table_sortable_headers class: 'text-center' %> </tr>
324
+ ```
325
+
326
+ If you wish to render your own version of a specific header (eg. to add an icon),
327
+ you may create a partial inside a `table_sortable` folder nested inside the controller's views folder. The partial should be named according to the following naming scheme:
328
+ `_<template>_header.html`, with `template` corresponding to the column's template attribute.
329
+ Notice that in this case you need to manually specify the different data attributes that correspond to the behaviour you wish this column to have.
330
+
331
+ The view will be supplied with two locals:
332
+ - `label`: the column's label
333
+ - `column`: the TableSortable::Column object
334
+
335
+ Here is an example of a full name header partial, which includes a font-awesome icon:
336
+ ```erb
337
+ <!-- views/users/table_sortable/_full_name_header.html.erb -->
338
+ <th data-placeholder="<%= column.placeholder %>">
339
+ <i class="fa fa-user" aria-hidden="true"></i>
340
+ <%= label %>
341
+ </th>
342
+ ```
343
+
344
+ By using the template attribute you may render several columns using the same template.
345
+
346
+ _Notice that whether using slim or erb, you must include .html before the extension._
347
+
348
+ #### table_sortable_columns
349
+ ##### Syntax: `table_sortable_columns record, [html_attributes]`
350
+ Renders the table columns for a specific `record`, each one inside a \<td> tag.
351
+ Notice that it _does not_ wrap a \<tr> tag around the headers, allowing you to add columns before of after TableSortable's columns.
352
+
353
+ It also renders data attributes that let tableSorter.js know the columns behaviour:
354
+ - `data-text="?"` if the column's `value` attribute is different than the column's `content` attribute, the value will be set in the `data-text` attribute, and the content will be displayed inside the \<td> element.
355
+
356
+ You may also specify any html attribute, as well as additional data attributes to be added to each \<td> element.
357
+ ```erb
358
+ <tr> <%= table_sortable_columns @user, class: 'text-info' %> </tr>
359
+ ```
360
+
361
+ If you wish to render your own version of a specific column (eg. to include a link inside of it),
362
+ you may create a partial inside a `table_sortable` folder nested inside the controller's views folder. The partial should be named according to the following naming scheme:
363
+ `_<template>_column.html`, with `template` corresponding to the column's template attribute.
364
+ Notice that in this case you need to manually specify the different data attributes that correspond to the behaviour you wish this column to have.
365
+
366
+ The view will be supplied with four locals:
367
+ - `source`: the source ActiveRecord object
368
+ - `content`: the column's content to be displayed
369
+ - `value`: the column's value
370
+ - `column`: the TableSortable::Column object
371
+
372
+ Here is an example of a full name column partial, in which the name links to the edit_user_path:
373
+ ```erb
374
+ <!-- views/users/table_sortable/_full_name_column.html.erb -->
375
+ <td>
376
+ <%= link_to content, edit_user_path(source) %>
377
+ </td>
378
+ ```
379
+ By using the template attribute you may render several columns using the same template.
380
+
381
+ _Notice that whether using slim, haml or erb, you must include .html before the extension._
382
+
383
+ #### table_sortable_pager
384
+ documentation coming soon...
145
385
 
146
386
  ## Development
147
387
 
@@ -3,18 +3,20 @@ module TableSortable
3
3
  class Filter
4
4
  include TableSortable::Concerns::Proc
5
5
 
6
- attr_accessor :query
6
+ attr_accessor :query, :default_value
7
7
 
8
8
  def initialize(*args)
9
- super :filter, *args
9
+ options = args.extract_options!
10
+ @default_value = options[:filter_initial_value]
11
+ super :filter, options
10
12
  end
11
13
 
12
14
  def array_proc
13
- -> (value, col=nil) { select{|record| value.downcase.in? col.value(record).to_s.downcase} }
15
+ -> (value, col=nil) { select{|record| col.value(record).to_s.downcase.include? value.downcase} }
14
16
  end
15
17
 
16
- def sql_proc
17
- -> (value, col=nil) { where("LOWER(?) LIKE (?)", filter.to_s.underscore, "%#{value.to_s.downcase}%") }
18
+ def active_record_proc
19
+ -> (value, col=nil) { where("LOWER(#{col.name.to_s.underscore}) LIKE (?)", "%#{value.to_s.downcase}%") }
18
20
  end
19
21
 
20
22
  def proc_wrapper(proc)
@@ -13,8 +13,8 @@ module TableSortable
13
13
  -> (sort_order, col=nil) { sort{ |a,b| col.value(sort_order == :asc ? a : b) <=> col.value(sort_order == :asc ? b : a) } }
14
14
  end
15
15
 
16
- def sql_proc
17
- -> (sort_order, col=nil) { order(sorter => sort_order) }
16
+ def active_record_proc
17
+ -> (sort_order, col=nil) { order(col.name.to_s.underscore => sort_order) }
18
18
  end
19
19
 
20
20
  def proc_wrapper(proc)
@@ -1,20 +1,27 @@
1
1
  module TableSortable
2
2
  class Column
3
3
 
4
- attr_reader :name, :label, :filter, :sorter, :template, :placeholder
4
+ attr_reader :name, :label, :filter, :sorter, :template, :placeholder, :content#, :sort_priority
5
5
 
6
6
  def initialize(col_name, *options)
7
7
 
8
8
  options = options.extract_options!
9
9
  value = options[:value] || col_name
10
+ content = options[:content] || value
10
11
  label = options[:label] || (options[:label] == false ? '' : col_name.to_s.titleize)
11
- placeholder = options[:placeholder] || (options[:placeholder] == false ? false : label)
12
+ placeholder = options[:placeholder] || (options[:placeholder] == false ? nil : label)
13
+ # priority = options[:priority]
12
14
  template = options[:template] || col_name
13
15
 
16
+ # filter_defaultAttrib (data-value)
17
+ # data-sorter (=false?)
18
+
14
19
  @name = col_name
15
- @value = value.is_a?(Proc) ? value : -> (record) { record.send(value) }
20
+ @value = value.respond_to?(:call) ? value : -> (record) { record.send(value) }
21
+ @content = content.respond_to?(:call) ? content : -> (record) { record.send(content) }
16
22
  @label = label
17
23
  @placeholder = placeholder
24
+ # @sort_priority = sort_priority
18
25
  @template = template
19
26
  @filter = TableSortable::Column::Filter.new(options.merge(:column => self) )
20
27
  @sorter = TableSortable::Column::Sorter.new(options.merge(:column => self) )
@@ -25,6 +32,10 @@ module TableSortable
25
32
  record.instance_eval(&@value) unless @value.nil?
26
33
  end
27
34
 
35
+ def content(record)
36
+ record.instance_eval(&@content) unless @content.nil?
37
+ end
38
+
28
39
  end
29
40
 
30
41
  end
@@ -4,7 +4,7 @@ module TableSortable
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- attr_reader :proc, :method, :column, :type
7
+ attr_reader :proc, :column, :type
8
8
  end
9
9
 
10
10
  def initialize(option_name, *options)
@@ -12,8 +12,8 @@ module TableSortable
12
12
  unless options[option_name] == false
13
13
  @type = option_name
14
14
  @column = options[:column]
15
- the_proc = options[option_name] || @column.name if @column
16
- @method = options["#{option_name.to_s}_method".to_sym] || :array
15
+ the_proc = options[option_name] || @column.name
16
+ @method = options["#{option_name.to_s}_method".to_sym] || :autodetect
17
17
  if the_proc.respond_to? :call
18
18
  @proc = proc_wrapper(the_proc)
19
19
  @method = detect_method(@proc)
@@ -21,19 +21,35 @@ module TableSortable
21
21
  case @method
22
22
  when :array
23
23
  @proc = array_proc
24
- when :sql
25
- @proc = sql_proc
24
+ when :active_record
25
+ @proc = active_record_proc
26
26
  end
27
27
  end
28
28
  end
29
29
  end
30
30
 
31
- def detect_method(proc)
31
+ def detect_method(proc, scope = nil)
32
32
  begin
33
33
  [].instance_exec('', &proc)
34
34
  method = :array
35
35
  rescue NoMethodError
36
- method = :sql
36
+ method = :active_record
37
+ end
38
+ method
39
+ end
40
+
41
+ def method(record = nil)
42
+ return @method if record.nil?
43
+ if @method == :autodetect
44
+ if record.class.columns.map{|col| col.name.to_sym}.include? @column.name
45
+ method = :active_record
46
+ @proc = active_record_proc
47
+ else
48
+ method = :array
49
+ @proc = array_proc
50
+ end
51
+ else
52
+ method = @method
37
53
  end
38
54
  method
39
55
  end
@@ -46,7 +62,7 @@ module TableSortable
46
62
  raise NotImplementedError
47
63
  end
48
64
 
49
- def sql_proc
65
+ def active_record_proc
50
66
  raise NotImplementedError
51
67
  end
52
68
 
@@ -18,7 +18,7 @@ module TableSortable
18
18
  columns.each do |column|
19
19
  define_column column
20
20
  end
21
- self.column_offset = column_offset
21
+ define_column_offset column_offset
22
22
  end
23
23
  end
24
24
 
@@ -27,6 +27,18 @@ module TableSortable
27
27
  define_column *args
28
28
  end
29
29
  end
30
+
31
+ def define_column_order(order)
32
+ before_action do
33
+ define_column_order order
34
+ end
35
+ end
36
+
37
+ def define_column_offset(offset)
38
+ before_action do
39
+ define_column_offset offset
40
+ end
41
+ end
30
42
  end
31
43
 
32
44
  def define_column(col_name, *options)
@@ -34,14 +46,26 @@ module TableSortable
34
46
  @columns.add(col_name, options)
35
47
  end
36
48
 
49
+ def define_column_order(*order)
50
+ @column_order = order
51
+ end
52
+
53
+ def define_column_offset(offset)
54
+ @column_offset = offset
55
+ end
56
+
57
+ def columns
58
+ @columns.sort_by(column_order)
59
+ end
60
+
37
61
  private
38
62
 
39
63
  def filter_and_sort(scope, params = nil)
40
64
  populate_params(params)
41
65
 
42
66
  actions = [->(records) { records }]
43
- ordered_actions.reverse.each_with_index do |action, i|
44
- actions << ->(records) { action.used? ? actions[i].call(action.run(records)) : actions[i].call(records) }
67
+ ordered_actions(scope.first).reverse.each_with_index do |action, i|
68
+ actions << ->(records) { action.used? ? (actions[i].call(action.run(records))) : actions[i].call(records) }
45
69
  end
46
70
  scope = actions.last.call(scope)
47
71
  if @query_params.page
@@ -53,17 +77,13 @@ module TableSortable
53
77
 
54
78
  def initialize_table_sortable
55
79
  @columns = TableSortable::Columns.new
56
- self.column_offset = 0
57
- end
58
-
59
- def columns
60
- @columns.sort_by(display_order)
80
+ define_column_offset 0
61
81
  end
62
82
 
63
- def ordered_actions
83
+ def ordered_actions(record = nil)
64
84
  filter_actions = @columns.map{|col| col.filter }
65
85
  sort_actions = @columns.map{|col| col.sorter }
66
- (filter_actions+sort_actions).sort{ |a,b| (a.method && b.method) ? (b.method <=> a.method) : a.method ? 1 : -1 }
86
+ (filter_actions+sort_actions).sort{ |a,b| (a.method(record) && b.method(record)) ? (a.method(record) <=> b.method(record)) : b.method(record) ? 1 : -1 }
67
87
  end
68
88
 
69
89
  def populate_params(params = nil)
@@ -72,8 +92,7 @@ module TableSortable
72
92
 
73
93
  public
74
94
 
75
- attr_writer :filter_order, :sort_order
76
- attr_accessor :display_order, :column_offset
95
+ attr_reader :column_order, :column_offset
77
96
 
78
97
  end
79
98
  end
@@ -0,0 +1,9 @@
1
+ # lib/my_gem/railtie.rb
2
+ require 'table_sortable/view_helpers'
3
+ module TableSortable
4
+ class Railtie < Rails::Railtie
5
+ initializer 'table_sortable.view_helpers' do
6
+ ActionView::Base.send :include, ViewHelpers
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module TableSortable
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -0,0 +1,67 @@
1
+ module TableSortable
2
+ module ViewHelpers
3
+
4
+ def table_sortable_pager(*args)
5
+ options = args.extract_options!
6
+
7
+ pagination_class = options[:wrapper_class] || 'pagination'
8
+ page_display_class = options[:page_display_class] || 'pagedisplay'
9
+ item_wrapper_class = options[:item_wrapper_class]
10
+ item_class = options[:item_class]
11
+ first_item = options[:first] || '<<'
12
+ prev_item = options[:prev] || '<'
13
+ next_item = options[:next] || '>'
14
+ last_item = options[:last] || '>>'
15
+
16
+ content_tag :ul, class:pagination_class do
17
+ content_tag(:li, link_to(first_item, '#', class: ([item_class] + ['first']).flatten.compact.join(' ')), class: item_wrapper_class)+
18
+ content_tag(:li, link_to(prev_item, '#', class: ([item_class] + ['prev'] ).flatten.compact.join(' ')), class: item_wrapper_class)+
19
+ content_tag(:li, content_tag(:span, nil, class: ([item_class] + [page_display_class]).flatten.compact.join(' ')), class: item_wrapper_class)+
20
+ content_tag(:li, link_to(next_item, '#', class: ([item_class] + ['next'] ).flatten.compact.join(' ')), class: item_wrapper_class)+
21
+ content_tag(:li, link_to(last_item, '#', class: ([item_class] + ['last'] ).flatten.compact.join(' ')), class: item_wrapper_class)
22
+ end.html_safe
23
+ end
24
+
25
+ def table_sortable_headers(html_options = {})
26
+ controller.columns.map do |col|
27
+ th_options = {}
28
+ th_options['data-placeholder'] = col.placeholder if col.placeholder
29
+ # th_options['data-priority'] = col.sort_priority if col.sort_priority
30
+ th_options['data-filter'] = 'false' if col.filter.disabled?
31
+ th_options['data-sorter'] = 'false' if col.sorter.disabled?
32
+ th_options['data-value'] = col.filter.default_value if col.filter.default_value
33
+ th_options.merge!(html_options)
34
+
35
+ begin
36
+ render partial: "#{controller_path}/table_sortable/#{col.template}_header.html",
37
+ locals: {label: col.label,
38
+ column: col}
39
+ rescue ActionView::MissingTemplate
40
+ content_tag :th, th_options do
41
+ col.label
42
+ end
43
+ end
44
+ end.join.html_safe
45
+ end
46
+
47
+ def table_sortable_columns(record, html_options = {})
48
+ controller.columns.map do |col|
49
+ td_options = {}
50
+ td_options['data-text'] = col.value(record) if col.value(record) != col.content(record)
51
+ td_options.merge!(html_options)
52
+
53
+ begin
54
+ render partial: "#{controller_path}/table_sortable/#{col.template}_column.html",
55
+ locals: {content: col.content(record),
56
+ value: col.value(record),
57
+ source: record,
58
+ column: col}
59
+ rescue ActionView::MissingTemplate
60
+ content_tag :td, td_options do
61
+ col.value(record)
62
+ end
63
+ end
64
+ end.join.html_safe
65
+ end
66
+ end
67
+ end
@@ -1,6 +1,4 @@
1
- require 'rails/engine'
2
1
  require 'active_support/concern'
3
- require 'action_controller'
4
2
 
5
3
  module TableSortable
6
4
 
@@ -11,11 +9,10 @@ module TableSortable
11
9
  PAGE = 'page'
12
10
  PAGESIZE = 'pagesize'
13
11
 
14
- class Engine < Rails::Engine; end
12
+ # class Engine < Rails::Engine; end
15
13
 
16
14
  end
17
15
 
18
-
19
16
  class TableSortableError < StandardError; end
20
17
 
21
18
  require 'table_sortable/concerns/proc'
@@ -26,4 +23,5 @@ require 'table_sortable/result'
26
23
  require 'table_sortable/columns'
27
24
  require 'table_sortable/version'
28
25
  require 'table_sortable/controller'
29
- require 'table_sortable/query_params'
26
+ require 'table_sortable/query_params'
27
+ require 'table_sortable/railtie' if defined?(Rails)
@@ -1,14 +1,14 @@
1
1
  shared_examples_for 'proc_class' do |parameter_name|
2
2
  include_context 'shared stuff'
3
3
 
4
- let(:dummy_class) { described_class.new(parameter_name => ->(x) {x}) }
4
+ let(:dummy_class) { described_class.new(parameter_name => ->(x) {x}, column: dummy_col) }
5
5
 
6
6
  it 'includes TableSortable::Concerns::Proc' do
7
7
  expect(described_class.included_modules).to include TableSortable::Concerns::Proc
8
8
  end
9
9
  it 'defines methods of its own' do
10
10
  expect(dummy_class.array_proc).to respond_to :call
11
- expect(dummy_class.sql_proc).to respond_to :call
11
+ expect(dummy_class.active_record_proc).to respond_to :call
12
12
  expect(dummy_class.send(:proc_wrapper, -> {x})).to respond_to :call
13
13
  expect(dummy_class).to respond_to :run
14
14
  expect(dummy_class).to respond_to :used?
@@ -1,3 +1,6 @@
1
+ require 'action_controller'
2
+
3
+
1
4
  module Test
2
5
  class Controller < ActionController::Base
3
6
 
@@ -9,7 +9,7 @@ describe TableSortable::Concerns::Proc do
9
9
  -> (x) {x * 2}
10
10
  end
11
11
 
12
- def sql_proc
12
+ def active_record_proc
13
13
  -> (x) {x * 3}
14
14
  end
15
15
 
@@ -33,34 +33,29 @@ describe TableSortable::Concerns::Proc do
33
33
  context 'it is an sql proc' do
34
34
  it 'should detect it as sql' do
35
35
  proc = proc_class.new(:proc, column: TableSortable::Column.new(:proc), proc: -> (value) { where(name: value) } )
36
- expect(proc.method).to eq :sql
36
+ expect(proc.method).to eq :active_record
37
37
  end
38
38
  end
39
39
  context 'it is an array proc' do
40
40
  it 'should detect it as array' do
41
- proc = proc_class.new(:proc, proc: -> (value) { select{|record| record.name == value} } )
41
+ proc = proc_class.new(:proc, column: dummy_col, proc: -> (value) { select{|record| record.name == value} } )
42
42
  expect(proc.method).to eq :array
43
43
  end
44
44
  end
45
45
  end
46
46
  context 'given no proc' do
47
- it 'should use array proc' do
48
- expect(dummy_proc.method).to eq :array
47
+ it 'should set method to autodetect' do
48
+ expect(dummy_proc.method).to eq :autodetect
49
49
  end
50
50
  context '_method: option' do
51
- context 'not provided' do
52
- it 'should replace it with array_proc' do
53
- expect(5.instance_eval(&dummy_proc.proc)).to eq 5.instance_eval(&dummy_proc.array_proc)
54
- end
55
- end
56
- context '== :sql' do
57
- it 'should replace it with sql_proc' do
58
- dummy_proc = proc_class.new(:proc, column: TableSortable::Column.new(:proc), proc_method: :sql)
59
- expect(5.instance_eval(&dummy_proc.proc)).to eq 5.instance_eval(&dummy_proc.sql_proc)
51
+ context '== :active_record' do
52
+ it 'should replace it with active_record_proc' do
53
+ dummy_proc = proc_class.new(:proc, column: TableSortable::Column.new(:proc), proc_method: :active_record)
54
+ expect(5.instance_eval(&dummy_proc.proc)).to eq 5.instance_eval(&dummy_proc.active_record_proc)
60
55
  end
61
56
  end
62
57
  context '== :array' do
63
- it 'should replace it with sql_proc' do
58
+ it 'should replace it with active_record_proc' do
64
59
  dummy_proc = proc_class.new(:proc, column: TableSortable::Column.new(:proc), proc_method: :array)
65
60
  expect(5.instance_eval(&dummy_proc.proc)).to eq 5.instance_eval(&dummy_proc.array_proc)
66
61
  end
@@ -73,7 +68,7 @@ describe TableSortable::Concerns::Proc do
73
68
  context 'given a proc containing an sql method' do
74
69
  it 'should detect it as sql' do
75
70
  proc_to_detect = -> (filter_value) { where(name: filter_value) }
76
- expect(dummy_proc.detect_method(proc_to_detect)).to eq :sql
71
+ expect(dummy_proc.detect_method(proc_to_detect)).to eq :active_record
77
72
  end
78
73
  end
79
74
  context 'given a proc containing an array method' do
@@ -6,23 +6,22 @@ describe TableSortable::Controller do
6
6
  controller.instance_eval('initialize_table_sortable')
7
7
  controller
8
8
  end
9
- let :controller_with_columns do
10
9
 
10
+ let :controller_with_columns do
11
11
  controller.send(:define_column,
12
- :first_name,
13
- filter: -> (value) { where('UPPER(first_name) LIKE (?)', "%#{value.upcase}%") },
14
- sort: -> (sort_order) { order(:first_name => sort_order) })
15
-
12
+ :first_name)#,
13
+ # filter: -> (value) { where('UPPER(first_name) LIKE (?)', "%#{value.upcase}%") },
14
+ # sort: -> (sort_order) { order(:first_name => sort_order) })
16
15
  controller.send(:define_column,
17
16
  :last_name,
18
- filter: -> (value) { select{|record| value.downcase.in? record.last_name.downcase }},
17
+ filter: -> (value) { select{|record| record.last_name.downcase.include? value.downcase }},
19
18
  sort: -> (sort_order) { sort{ |a,b| (sort_order == :asc ? a : b).last_name <=> (sort_order == :asc ? b : a).last_name }})
20
-
19
+ controller.send(:define_column,
20
+ :full_name)
21
21
  controller.send(:define_column,
22
22
  :email,
23
23
  filter: -> (value) { where('UPPER(email) LIKE (?)', "%#{value.upcase}%") },
24
24
  sort: -> (sort_order) { order(:email => sort_order) })
25
-
26
25
  controller
27
26
  end
28
27
 
@@ -50,7 +49,7 @@ describe TableSortable::Controller do
50
49
 
51
50
  context 'ordered_actions' do
52
51
  it 'orders sql actions before array filters' do
53
- expect(controller_with_columns.send(:ordered_actions).map{|action| action.method}).to eq [:sql, :sql, :sql, :sql, :array, :array]
52
+ expect(controller_with_columns.send(:ordered_actions).map{|action| action.method}).to eq [:active_record, :active_record, :array, :array, :autodetect, :autodetect, :autodetect, :autodetect]
54
53
  end
55
54
  end
56
55
 
@@ -67,7 +66,7 @@ describe TableSortable::Controller do
67
66
  sort_by_first_name = controller_with_columns.send(:filter_and_sort, User.all, {TableSortable::PAGESIZE => '10', TableSortable::PAGE => '0', TableSortable::SCOL => {'0' => TableSortable::SORT_ASC}})
68
67
  expect(sort_by_first_name.pluck(:first_name)).to eq %w(Aaron Bob David Jim)
69
68
 
70
- sort_by_email = controller_with_columns.send(:filter_and_sort, User.all, {TableSortable::PAGESIZE => '10', TableSortable::PAGE => '0', TableSortable::SCOL => {'2' => TableSortable::SORT_ASC}})
69
+ sort_by_email = controller_with_columns.send(:filter_and_sort, User.all, {TableSortable::PAGESIZE => '10', TableSortable::PAGE => '0', TableSortable::SCOL => {'3' => TableSortable::SORT_ASC}})
71
70
  expect(sort_by_email.pluck(:first_name)).to eq %w(Jim David Bob Aaron)
72
71
  end
73
72
  context "sort order parameter equals #{TableSortable::SORT_DESC}" do
@@ -76,6 +75,8 @@ describe TableSortable::Controller do
76
75
  expect(sort_by_last_name_desc.pluck(:first_name)).to eq %w(Aaron Jim Bob David)
77
76
  end
78
77
  end
78
+ it 'detects whether to use an active_record or array filter' do
79
79
 
80
+ end
80
81
  end
81
82
  end
@@ -1 +1,7 @@
1
- class User < ActiveRecord::Base ; end
1
+ class User < ActiveRecord::Base
2
+
3
+
4
+ def full_name
5
+ "#{first_name} #{last_name}"
6
+ end
7
+ end
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["davidovoded@gmail.com"]
11
11
 
12
12
  spec.summary = 'Use jquery-tablesorter.js with server side filtering, pagination and sorting'
13
- spec.description = 'Use jquery-tablesorter.js with server side filtering, pagination and sorting'
13
+ spec.description = "TableSortable adds multi-column, server-side filtering, sorting and pagination to the tableSorter jQuery plugin, so you don't have to worry about interpreting the query parameters, combining multiple queries, columns to sort by, or figuring out how to send the correct page back to the client. It is a Rails backend complementation to the frontend tableSorter.js."
14
14
  spec.homepage = 'https://github.com/odedd/table_sortable'
15
15
  spec.license = "MIT"
16
16
 
@@ -34,5 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency "rspec", "~> 3.4"
35
35
  spec.add_development_dependency "sqlite3", "~> 1.3"
36
36
  spec.add_development_dependency "factory_girl_rails", "~> 4.8"
37
- spec.add_dependency "rails", '~> 5.1', '>= 5.1.1'
37
+ spec.add_development_dependency "activerecord", '~> 5.1', '>= 5.1.1'
38
+ spec.add_dependency "railties", '~> 5.1', '>= 5.1.1'
39
+ # spec.add_dependency "activesupport", '~> 5.1', '>= 5.1.1'
38
40
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: table_sortable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oded Davidov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-31 00:00:00.000000000 Z
11
+ date: 2017-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,7 +81,27 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '4.8'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rails
84
+ name: activerecord
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.1'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 5.1.1
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '5.1'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 5.1.1
103
+ - !ruby/object:Gem::Dependency
104
+ name: railties
85
105
  requirement: !ruby/object:Gem::Requirement
86
106
  requirements:
87
107
  - - "~>"
@@ -100,8 +120,11 @@ dependencies:
100
120
  - - ">="
101
121
  - !ruby/object:Gem::Version
102
122
  version: 5.1.1
103
- description: Use jquery-tablesorter.js with server side filtering, pagination and
104
- sorting
123
+ description: TableSortable adds multi-column, server-side filtering, sorting and pagination
124
+ to the tableSorter jQuery plugin, so you don't have to worry about interpreting
125
+ the query parameters, combining multiple queries, columns to sort by, or figuring
126
+ out how to send the correct page back to the client. It is a Rails backend complementation
127
+ to the frontend tableSorter.js.
105
128
  email:
106
129
  - davidovoded@gmail.com
107
130
  executables: []
@@ -123,12 +146,6 @@ files:
123
146
  - LICENSE.txt
124
147
  - README.md
125
148
  - Rakefile
126
- - app/helpers/table_sortable_helper.rb
127
- - app/views/table_sortable/_columns.slim
128
- - app/views/table_sortable/_field.slim
129
- - app/views/table_sortable/_header.slim
130
- - app/views/table_sortable/_headers.slim
131
- - app/views/table_sortable/_pager.slim
132
149
  - bin/console
133
150
  - bin/setup
134
151
  - lib/table_sortable.rb
@@ -140,8 +157,10 @@ files:
140
157
  - lib/table_sortable/controller.rb
141
158
  - lib/table_sortable/process.rb
142
159
  - lib/table_sortable/query_params.rb
160
+ - lib/table_sortable/railtie.rb
143
161
  - lib/table_sortable/result.rb
144
162
  - lib/table_sortable/version.rb
163
+ - lib/table_sortable/view_helpers.rb
145
164
  - spec/concerns/proc_class_spec.rb
146
165
  - spec/controllers/test_controller_spec.rb
147
166
  - spec/lib/table_sortable/column/filter_spec.rb
@@ -1,15 +0,0 @@
1
- module TableSortableHelper
2
-
3
- def table_sortable_pager
4
- render 'table_sortable/pager'
5
- end
6
-
7
- def table_sortable_headers
8
- render 'table_sortable/headers'
9
- end
10
-
11
- def table_sortable_columns(record)
12
- render 'table_sortable/columns', record: record
13
- end
14
-
15
- end
@@ -1,3 +0,0 @@
1
- - columns.each do |col|
2
- - options = {value: col.value(record), source: record, column: col}
3
- = render("#{controller_path}/table_sortable/#{col.template}_field", options) rescue render('table_sortable/field', options)
@@ -1 +0,0 @@
1
- td = value
@@ -1,2 +0,0 @@
1
- th*{'data-filter' => column.filter.disabled? ? 'false' : false, 'data-placeholder'=>column.placeholder }
2
- = label
@@ -1,3 +0,0 @@
1
- - columns.each do |col|
2
- - options = {label: col.label, column: col}
3
- = render("#{controller_path}/table_sortable/#{col.template}_header", options) rescue render('table_sortable/header', options)
@@ -1,42 +0,0 @@
1
- .nav aria-label="Table Navigation"
2
- ul.pagination
3
- li.page-item
4
- a.page-link.first = fa_icon 'fast-backward'
5
- li.page-item
6
- a.page-link.prev = fa_icon 'step-backward'
7
- li.page-item
8
- span.page-link.pagedisplay
9
- li.page-item
10
- a.page-link.next = fa_icon 'step-forward'
11
- li.page-item
12
- a.page-link.last = fa_icon 'fast-forward'
13
-
14
-
15
- /<nav aria-label="Page navigation example">
16
- / <ul class="pagination">
17
- / <li class="page-item">
18
- / <a class="page-link" href="#" aria-label="Previous">
19
- / <span aria-hidden="true">&laquo;</span>
20
- / <span class="sr-only">Previous</span>
21
- / </a>
22
- / </li>
23
- / <li class="page-item"><a class="page-link" href="#">1</a></li>
24
- / <li class="page-item"><a class="page-link" href="#">2</a></li>
25
- / <li class="page-item"><a class="page-link" href="#">3</a></li>
26
- / <li class="page-item">
27
- / <a class="page-link" href="#" aria-label="Next">
28
- / <span aria-hidden="true">&raquo;</span>
29
- / <span class="sr-only">Next</span>
30
- / </a>
31
- / </li>
32
- / </ul>
33
- /</nav>
34
-
35
- /.row
36
- / .col.text-right
37
- / .pagination.my-0.justify-content-center
38
- / a.first.ml-1 = fa_icon 'fast-backward'
39
- / a.prev = fa_icon 'step-backward'
40
- / span.mx-1.pagedisplay
41
- / a.ml-1.next = fa_icon 'step-forward'
42
- / a.last = fa_icon 'fast-forward'