easy_filter 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/.rubocop.yml +112 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +103 -0
- data/Rakefile +5 -0
- data/app/assets/javascripts/easy_filter.js +53 -0
- data/app/assets/stylesheets/easy_filter.css.scss +3 -0
- data/app/views/easy_filter/_buttons.html.erb +2 -0
- data/app/views/easy_filter/_field_array.html.erb +20 -0
- data/app/views/easy_filter/_field_datetime.html.erb +2 -0
- data/app/views/easy_filter/_field_text.html.erb +1 -0
- data/app/views/easy_filter/_form_close.html.erb +2 -0
- data/app/views/easy_filter/_form_field_close.html.erb +1 -0
- data/app/views/easy_filter/_form_field_open.html.erb +1 -0
- data/app/views/easy_filter/_form_open.html.erb +3 -0
- data/app/views/easy_filter/_sort_field.html.erb +2 -0
- data/easy_filter.gemspec +26 -0
- data/lib/easy_filter.rb +5 -0
- data/lib/easy_filter/engine.rb +4 -0
- data/lib/easy_filter/model_additions.rb +34 -0
- data/lib/easy_filter/railtie.rb +14 -0
- data/lib/easy_filter/version.rb +4 -0
- data/lib/easy_filter/view_helpers.rb +69 -0
- data/spec/easy_filter/model_additions_spec.rb +99 -0
- data/spec/spec_helper.rb +3 -0
- metadata +161 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OTQ4MDFmOTlmY2I5ODkxMDliNjViOGYyY2ViNDUxMjczOTJjNTg2MA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MTU0YTMzMmNiMTg5NTUwODQ0OGU0NmFhODhkNTIzODYxOWU2MzIxOQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MWY2M2YyZGE0MTFkYmU4ZTk4MDRlZmE0Mjk0NmI4ODMzM2FjMjkwNjYxZTA4
|
10
|
+
YmE3ODA0MDg1MGNmNTAwMTBmYWVkYWFjZTU1YWExMDZkMGYyYWJlMDI1ZmNh
|
11
|
+
YzRjYjU4NGRjYmE1ZmE0ZmZkMjYwMjQ2ZGMzZDMzZjVjNTk4MGU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NjQ1OGYxZWZkZmQ5Y2YzZGYwYzMwYWE1N2FhMjYyNWQxNzE2OGFhNzM1YzA2
|
14
|
+
ZjhmNWUxMGE5ODgwNWNkNmQyNDRkY2QzZDE4NzY2ZTdkN2NhZmE4YWI5YzYw
|
15
|
+
OWMwMzIyOGIxMTk5MzEyNTFmMzNjZjhkMGU1MzQ3NmQ3NWNjMTg=
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
###########################
|
2
|
+
# Configuration for rubocop
|
3
|
+
#
|
4
|
+
# Most of these are disabling existing cops, primarily
|
5
|
+
# due to a smattering of different styles and loose
|
6
|
+
# guidlines for contributions.
|
7
|
+
#
|
8
|
+
# Any of these may be changed.
|
9
|
+
|
10
|
+
MethodLength:
|
11
|
+
Max: 200
|
12
|
+
|
13
|
+
LineLength:
|
14
|
+
Max: 160
|
15
|
+
|
16
|
+
HashSyntax:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
# Prefer single-quotes
|
20
|
+
StringLiterals:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
AlignParameters:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
SpaceAroundOperators:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Encoding:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
PercentR:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
SpaceAroundBraces:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
FavorPercentR:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
AndOr:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
EmptyLineBetweenDefs:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
SpaceInsideHashLiteralBraces:
|
48
|
+
Enabled: false
|
49
|
+
|
50
|
+
SymbolName:
|
51
|
+
Enabled: false
|
52
|
+
|
53
|
+
ReduceArguments:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
RescueException:
|
57
|
+
Enabled: false
|
58
|
+
|
59
|
+
Syntax:
|
60
|
+
Enabled: false
|
61
|
+
|
62
|
+
WordArray:
|
63
|
+
Enabled: false
|
64
|
+
|
65
|
+
IfUnlessModifier:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
ParenthesesAroundCondition:
|
69
|
+
Enabled: false
|
70
|
+
|
71
|
+
MethodAndVariableSnakeCase:
|
72
|
+
Enabled: false
|
73
|
+
|
74
|
+
AvoidClassVars:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
WhileUntilModifier:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
Semicolon:
|
81
|
+
Enabled: false
|
82
|
+
|
83
|
+
UnlessElse:
|
84
|
+
Enabled: false
|
85
|
+
|
86
|
+
BlockNesting:
|
87
|
+
Enabled: false
|
88
|
+
|
89
|
+
Proc:
|
90
|
+
Enabled: false
|
91
|
+
|
92
|
+
# Global vars should be removed
|
93
|
+
AvoidGlobalVars:
|
94
|
+
Enabled: false
|
95
|
+
|
96
|
+
# Probably some good ones in here.
|
97
|
+
# Disabled for $? => $CHILD_STATUS
|
98
|
+
AvoidPerlisms:
|
99
|
+
Enabled: false
|
100
|
+
|
101
|
+
Lambda:
|
102
|
+
Enabled: false
|
103
|
+
|
104
|
+
CollectionMethods:
|
105
|
+
Enabled: false
|
106
|
+
|
107
|
+
CaseIndentation:
|
108
|
+
Enabled: false
|
109
|
+
|
110
|
+
AllCops:
|
111
|
+
Excludes:
|
112
|
+
- vendor/**
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
easy_filter
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-1.9.3-p484
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Peter Kepes
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# EasyFilter
|
2
|
+
|
3
|
+
By [Peter Kepes](https://github.com/kepes).
|
4
|
+
|
5
|
+
Filter and sort `ActiveRecord` model for Rails app with [Bootstrap](http://getbootstrap.com/) view helpers.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'easy_filter', git: 'https://github.com/kepes/easy-filter.git'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install easy_filter
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Gem provide an AciveRecord model addition and a view helper.
|
24
|
+
|
25
|
+
### Controller
|
26
|
+
|
27
|
+
Model.easy_filter(params)
|
28
|
+
|
29
|
+
EasyFilter works on ActiveRecord::Relation. You can chain with any other module like [Kaminari paginator](https://github.com/amatsuda/kaminari) or [cancan](https://github.com/ryanb/cancan).
|
30
|
+
|
31
|
+
@model = @model.includes(:other_model).easy_filter(params).page params[:page]
|
32
|
+
|
33
|
+
### View
|
34
|
+
|
35
|
+
<%= easy_filter ModelClass, [:name, :expiry_date] %>
|
36
|
+
|
37
|
+
`easy_filter` view helper will generate a search form for `ModelClass` with field `name` and `expiry_date`. EasyFilter try to determine the correct filed type from type of specified column. For text fields it will generate a normal text field and for date field it will generate a `JQuery::DatePicker`.
|
38
|
+
|
39
|
+
You can define an `Array` of `Hash` and EasyFilter will generate a dropdown automaticly.
|
40
|
+
|
41
|
+
Code in model or controller:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
def self.statuses
|
45
|
+
[
|
46
|
+
{ code: 'A', name: 'Status A', color: :default},
|
47
|
+
{ code: 'B', name: 'Status B', color: :info},
|
48
|
+
{ code: 'C', name: 'Status C', color: :warning},
|
49
|
+
]
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
In view:
|
54
|
+
|
55
|
+
<%= easy_filter ModelClass, [:name, :expiry_date, [:status, ModelClass.statuses]] %>
|
56
|
+
|
57
|
+
#### Advanced parameters
|
58
|
+
|
59
|
+
`easy_filter` model addition provide paramters to define HTML input field names for processing.
|
60
|
+
|
61
|
+
def easy_filter(params, prefixes = { main: 'filter_', from: 'from_', to: 'to_', exact: 'exact_', sort: 'sort', direction: 'direction' })
|
62
|
+
|
63
|
+
If you change prefix parameters dont't forget to change it for view helpers too!
|
64
|
+
|
65
|
+
#### Define sorting
|
66
|
+
|
67
|
+
For sorting you can use `easy_sort` view helper.
|
68
|
+
|
69
|
+
<%= easy_sort :id, t('activerecord.attributes.model.id') %>
|
70
|
+
|
71
|
+
#### Override view templates
|
72
|
+
|
73
|
+
Default view helper templates generates [Bootstrap](http://getbootstrap.com/) components. If you want to use your own templates or just modify templates you should create an `app/views/easy_filter` folder in your app and create the corresponding view file. Available view files:
|
74
|
+
|
75
|
+
app/views/easy_filter/_buttons.html.erb
|
76
|
+
app/views/easy_filter/_field_datetime.html.erb
|
77
|
+
app/views/easy_filter/_form_close.html.erb
|
78
|
+
app/views/easy_filter/_form_field_open.html.erb
|
79
|
+
app/views/easy_filter/_sort_field.html.erb
|
80
|
+
app/views/easy_filter/_field_array.html.erb
|
81
|
+
app/views/easy_filter/_field_text.html.erb
|
82
|
+
app/views/easy_filter/_form_field_close.html.erb
|
83
|
+
app/views/easy_filter/_form_open.html.erb
|
84
|
+
|
85
|
+
#### Advanced parameters
|
86
|
+
|
87
|
+
View helpers provide paramters to define HTML input field names.
|
88
|
+
|
89
|
+
def easy_filter(model_class, filters, prefixes = { main: 'filter_', from: 'from_', to: 'to_', exact: 'exact_' })
|
90
|
+
|
91
|
+
def easy_sort(column, title = nil, sort = 'sort', direction = 'direction')
|
92
|
+
|
93
|
+
All default templates will use specified prefixes for input fields. If you have to use different names just use this parameters to redefine it.
|
94
|
+
|
95
|
+
If you change prefix parameters dont't forget to change it for model addition too!
|
96
|
+
|
97
|
+
## Contributing
|
98
|
+
|
99
|
+
1. Fork it
|
100
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
101
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
102
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
103
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
$(document).ready(function() {
|
2
|
+
$('ul.dropdown-filter li a').click(function (e) {
|
3
|
+
html = $(this).html();
|
4
|
+
$(this).parents('ul.dropdown-filter').prev().children().first().remove();
|
5
|
+
$(this).parents('ul.dropdown-filter').prev().prepend(html);
|
6
|
+
$(this).parents('div.dropdown').removeClass('open')
|
7
|
+
$(this).parents('div.dropdown').find('input').first().val($(this).attr('data-target'));
|
8
|
+
});
|
9
|
+
});
|
10
|
+
|
11
|
+
$(document).ready(function() {
|
12
|
+
$(".datepicker").datepicker($.datepicker.regional[ "hu" ]);
|
13
|
+
$(".datepicker").each(function() { $(this).val($(this).attr('value')); });
|
14
|
+
});
|
15
|
+
|
16
|
+
/* Hungarian initialisation for the jQuery UI date picker plugin. */
|
17
|
+
/* Written by Peter Kepes (https://github.com/kepes),
|
18
|
+
*/
|
19
|
+
(function( factory ) {
|
20
|
+
if ( typeof define === "function" && define.amd ) {
|
21
|
+
|
22
|
+
// AMD. Register as an anonymous module.
|
23
|
+
define([ "../jquery.ui.datepicker" ], factory );
|
24
|
+
} else {
|
25
|
+
|
26
|
+
// Browser globals
|
27
|
+
factory( jQuery.datepicker );
|
28
|
+
}
|
29
|
+
}(function( datepicker ) {
|
30
|
+
datepicker.regional['hu'] = {
|
31
|
+
closeText: 'Bezár',
|
32
|
+
prevText: 'Előző',
|
33
|
+
nextText: 'Következő',
|
34
|
+
currentText: 'Aktuális',
|
35
|
+
monthNames: ['január', 'február', 'március', 'április', 'május', 'június',
|
36
|
+
'július', 'augusztus', 'szeptember', 'október', 'november', 'december'],
|
37
|
+
monthNamesShort: ['jan.', 'feb.', 'márc.', 'ápr.', 'máj.', 'jún.',
|
38
|
+
'júl.', 'aug.', 'szept.', 'okt.', 'nov.', 'dec.'],
|
39
|
+
dayNames: [ 'vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat'],
|
40
|
+
dayNamesShort: ['vas.', 'hét.', 'kedd', 'szer.', 'csüt.', 'pén.', 'szom.'],
|
41
|
+
dayNamesMin: ['V','H','K','S','C','P','S'],
|
42
|
+
weekHeader: 'Hét',
|
43
|
+
dateFormat: 'yy.mm.dd',
|
44
|
+
firstDay: 1,
|
45
|
+
isRTL: false,
|
46
|
+
showMonthAfterYear: false,
|
47
|
+
yearSuffix: ''};
|
48
|
+
datepicker.setDefaults(datepicker.regional['hu']);
|
49
|
+
|
50
|
+
return datepicker.regional['hu'];
|
51
|
+
}));
|
52
|
+
|
53
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<div class="dropdown">
|
2
|
+
<%= hidden_field_tag("#{filter_prefixes[:main]}#{filter_prefixes[:exact]}#{filter_col_name}", request.params["#{filter_prefixes[:main]}#{filter_prefixes[:exact]}#{filter_col_name}"]) %>
|
3
|
+
<% button_text = "<span>#{t("activerecord.attributes.#{filter_model_class.name.downcase}.#{filter_col_name}")}</span>" %>
|
4
|
+
|
5
|
+
<% elements.each do |item|
|
6
|
+
if request.params["#{filter_prefixes[:main]}#{filter_prefixes[:exact]}#{filter_col_name}"] == item[:code]
|
7
|
+
button_text = "<span class=\"label label-#{item[:color]}\">#{item[:name]}</span>"
|
8
|
+
break
|
9
|
+
end
|
10
|
+
end %>
|
11
|
+
|
12
|
+
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownFilterButton-<%= filter_col_name %>" data-toggle="dropdown"><%= button_text.html_safe %>
|
13
|
+
<span class="caret"></span></button>
|
14
|
+
|
15
|
+
<ul class="dropdown-menu dropdown-filter" aria-labelledby="dropdownFilterButton-<%= filter_col_name %>">
|
16
|
+
<% elements.each do |item| %>
|
17
|
+
<li role="presentation"><a role="menuitem" tabindex="-1" data-target="<%= item[:code] %>"><span class="label label-<%= item[:color]%>"><%= item[:name] %></span></a></li>
|
18
|
+
<% end %>
|
19
|
+
</ul>
|
20
|
+
</div>
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<%= text_field_tag("#{filter_prefixes[:main]}#{filter_prefixes[:from]}#{filter_col_name}", request.params["#{filter_prefixes[:main]}#{filter_prefixes[:from]}#{filter_col_name}"], class: 'form-control datepicker', placeholder: t("activerecord.attributes.#{filter_model_class.name.downcase}.#{filter_col_name}")) %>
|
2
|
+
<%= text_field_tag("#{filter_prefixes[:main]}#{filter_prefixes[:to]}#{filter_col_name}", request.params["#{filter_prefixes[:main]}#{filter_prefixes[:to]}#{filter_col_name}"], class: 'form-control datepicker', placeholder: t("activerecord.attributes.#{filter_model_class.name.downcase}.#{filter_col_name}")) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= text_field_tag("#{filter_prefixes[:main]}#{filter_col_name}", request.params["#{filter_prefixes[:main]}#{filter_col_name}"], class: 'form-control', placeholder: t("activerecord.attributes.#{filter_model_class.name.downcase}.#{filter_col_name}")) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<div class='form-group'>
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<% icon = "<span class=\"glyphicon glyphicon-chevron-#{direction == "asc" ? "up" : "down"}\"></span>" %>
|
2
|
+
<%= link_to "#{title} #{column == params[sort_param_name] ? icon : ''}".html_safe, request.parameters.merge(sort_param_name => column, direction_param_name => direction) %>
|
data/easy_filter.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'easy_filter/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'easy_filter'
|
8
|
+
spec.version = EasyFilter::VERSION
|
9
|
+
spec.authors = ['Peter Kepes']
|
10
|
+
spec.email = ['kepes.peter@codeplay.hu']
|
11
|
+
spec.description = 'Filter and sort ActiveRecord model for Rails app with Bootstrap view helpers'
|
12
|
+
spec.summary = 'ActiveRecord model filter'
|
13
|
+
spec.homepage = 'https://github.com/kepes/easy-filter'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($RS)
|
17
|
+
spec.test_files = spec.files.grep(/^(test|spec|features)/)
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
21
|
+
spec.add_development_dependency 'rake'
|
22
|
+
spec.add_development_dependency 'rspec'
|
23
|
+
spec.add_development_dependency 'rubocop'
|
24
|
+
spec.add_development_dependency 'activerecord'
|
25
|
+
spec.add_development_dependency 'sqlite3'
|
26
|
+
end
|
data/lib/easy_filter.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module EasyFilter
|
2
|
+
# Define methods for ActiveRecord
|
3
|
+
module ModelAdditions
|
4
|
+
def easy_filter(params, prefixes = { main: 'filter_',
|
5
|
+
from: 'from_',
|
6
|
+
to: 'to_',
|
7
|
+
exact: 'exact_',
|
8
|
+
sort: 'sort',
|
9
|
+
direction: 'direction' })
|
10
|
+
filter = self
|
11
|
+
params.each do |key, value|
|
12
|
+
next unless key.start_with?(prefixes[:main]) && !value.blank? && key != "#{prefixes[:main]}button"
|
13
|
+
|
14
|
+
field = key.gsub(prefixes[:main], '').to_s
|
15
|
+
if field.start_with?(prefixes[:from])
|
16
|
+
filter = filter.where("#{field.gsub(prefixes[:from], '')} >= ?", value)
|
17
|
+
elsif field.start_with?(prefixes[:to])
|
18
|
+
filter = filter.where("#{field.gsub(prefixes[:to], '')} <= ?", value)
|
19
|
+
elsif field.start_with?(prefixes[:exact])
|
20
|
+
filter = filter.where("#{field.gsub(prefixes[:exact], '')} = ?", value)
|
21
|
+
else
|
22
|
+
filter = filter.where("#{field} like ?", "%#{value}%")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
params[prefixes[:sort]] ||= 'id'
|
26
|
+
params[prefixes[:direction]] ||= 'desc'
|
27
|
+
|
28
|
+
sort_column = column_names.include?(params[prefixes[:sort]]) ? params[prefixes[:sort]] : 'id'
|
29
|
+
sort_direction = %w(asc desc).include?(params[prefixes[:direction]]) ? params[prefixes[:direction]] : 'desc'
|
30
|
+
|
31
|
+
filter.order("#{sort_column} #{sort_direction}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module EasyFilter
|
2
|
+
# Load ModuleAdditions and views into Rails env
|
3
|
+
class Railtie < Rails::Railtie
|
4
|
+
initializer 'easy_filter.model_additions' do
|
5
|
+
ActiveSupport.on_load :active_record do
|
6
|
+
extend ModelAdditions
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
initializer 'easy_filter.view_helpers' do
|
11
|
+
ActionView::Base.send :include, ViewHelpers
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module EasyFilter
|
2
|
+
# View helpers for EasyFilter
|
3
|
+
module ViewHelpers
|
4
|
+
def easy_sort(column, title = nil, sort = 'sort', direction = 'direction')
|
5
|
+
title ||= column.titleize
|
6
|
+
dir = (column.to_s == params[sort] && params[direction] == 'asc') ? 'desc' : 'asc'
|
7
|
+
|
8
|
+
render partial: 'easy_filter/sort_field',
|
9
|
+
locals: { column: column.to_s,
|
10
|
+
title: title,
|
11
|
+
sort_param_name: sort,
|
12
|
+
direction: dir,
|
13
|
+
direction_param_name: direction }
|
14
|
+
end
|
15
|
+
|
16
|
+
def easy_filter(model_class, filters, prefixes = { main: 'filter_', from: 'from_', to: 'to_', exact: 'exact_' })
|
17
|
+
form = render_easy 'form_open', prefixes, model_class
|
18
|
+
|
19
|
+
filters.each do |filter|
|
20
|
+
col_name, col_type = determine_column filter, model_class
|
21
|
+
form += render_easy 'form_field_open', prefixes, model_class
|
22
|
+
|
23
|
+
case col_type
|
24
|
+
when :datetime
|
25
|
+
form += render_easy 'field_datetime', prefixes, model_class, col_name
|
26
|
+
|
27
|
+
when :array
|
28
|
+
form += render_easy 'field_array', prefixes, model_class, col_name, filter[1]
|
29
|
+
|
30
|
+
else
|
31
|
+
form += render_easy 'field_text', prefixes, model_class, col_name
|
32
|
+
end
|
33
|
+
|
34
|
+
form += render_easy 'form_field_close', prefixes, model_class
|
35
|
+
end
|
36
|
+
|
37
|
+
form += render_easy 'buttons', prefixes, model_class
|
38
|
+
form += render_easy 'form_close', prefixes, model_class
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def determine_column(filter, model_class)
|
44
|
+
col_name = filter if filter.is_a?(Symbol) || filter.is_a?(String)
|
45
|
+
col_name = filter[0] if filter.is_a? Array
|
46
|
+
|
47
|
+
col_type = nil
|
48
|
+
if filter.is_a? Array
|
49
|
+
col_type = :array
|
50
|
+
else
|
51
|
+
model_class.columns.each do |column|
|
52
|
+
if column.name == col_name.to_s
|
53
|
+
col_type = column.type
|
54
|
+
break
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
[col_name, col_type]
|
59
|
+
end
|
60
|
+
|
61
|
+
def render_easy(name, prefixes, model_class, col_name = nil, elements = nil)
|
62
|
+
render partial: "easy_filter/#{name}",
|
63
|
+
locals: { filter_prefixes: prefixes,
|
64
|
+
filter_model_class: model_class,
|
65
|
+
filter_col_name: col_name,
|
66
|
+
elements: elements }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
ActiveRecord::Base.establish_connection(
|
4
|
+
adapter: 'sqlite3',
|
5
|
+
database: 'easy_filter_test.db'
|
6
|
+
)
|
7
|
+
|
8
|
+
# This class create database table for RSPec tests
|
9
|
+
class CreateUsersTable < ActiveRecord::Migration
|
10
|
+
def self.up
|
11
|
+
create_table :users do |t|
|
12
|
+
t.string :name
|
13
|
+
t.string :born
|
14
|
+
end
|
15
|
+
puts 'Users created'
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :users
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Model class for testing
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
extend EasyFilter::ModelAdditions
|
26
|
+
end
|
27
|
+
|
28
|
+
describe EasyFilter::ModelAdditions do
|
29
|
+
before(:all) do
|
30
|
+
CreateUsersTable.migrate(:up)
|
31
|
+
User.create!(id: 1, name: 'aaaa aaaa', born: '2001.01.01')
|
32
|
+
User.create!(id: 2, name: 'aaaa bbbb', born: '2002.01.01')
|
33
|
+
User.create!(id: 3, name: 'bbbb bbbb', born: '2003.01.01')
|
34
|
+
User.create!(id: 4, name: 'aaaa cccc', born: '2004.01.01')
|
35
|
+
end
|
36
|
+
|
37
|
+
after(:all) do
|
38
|
+
CreateUsersTable.migrate(:down)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should not filter without parameters' do
|
42
|
+
expect(User.scoped.easy_filter({}).count).to eq(4)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should reverse order by ID default' do
|
46
|
+
(0..3).each do |i|
|
47
|
+
expect(User.scoped.easy_filter({})[i][:id]).to eq(4 - i)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should order by name' do
|
52
|
+
users = User.scoped.easy_filter('sort' => 'name', 'direction' => 'asc')
|
53
|
+
expect(users[0][:id]).to eq(1)
|
54
|
+
expect(users[1][:id]).to eq(2)
|
55
|
+
expect(users[2][:id]).to eq(4)
|
56
|
+
expect(users[3][:id]).to eq(3)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should reverse order by name' do
|
60
|
+
users = User.scoped.easy_filter('sort' => 'name', 'direction' => 'desc')
|
61
|
+
expect(users[0][:id]).to eq(3)
|
62
|
+
expect(users[1][:id]).to eq(4)
|
63
|
+
expect(users[2][:id]).to eq(2)
|
64
|
+
expect(users[3][:id]).to eq(1)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should filter by name' do
|
68
|
+
users = User.scoped.easy_filter('filter_name' => 'aa')
|
69
|
+
expect(users.count).to eq(3)
|
70
|
+
|
71
|
+
users = User.scoped.easy_filter('filter_name' => 'bb')
|
72
|
+
expect(users.count).to eq(2)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should exact filter by id' do
|
76
|
+
users = User.scoped.easy_filter('filter_exact_id' => '1')
|
77
|
+
expect(users.count).to eq(1)
|
78
|
+
|
79
|
+
users = User.scoped.easy_filter('filter_exact_name' => 'aaaa bbbb')
|
80
|
+
expect(users.count).to eq(1)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should filter by time' do
|
84
|
+
users = User.scoped.easy_filter('filter_from_born' => '2001.01.01',
|
85
|
+
'filter_to_born' => '2001.02.01')
|
86
|
+
expect(users.count).to eq(1)
|
87
|
+
|
88
|
+
users = User.scoped.easy_filter('filter_from_born' => '2001.01.01',
|
89
|
+
'filter_to_born' => '2002.01.01')
|
90
|
+
expect(users.count).to eq(2)
|
91
|
+
|
92
|
+
users = User.scoped.easy_filter('filter_from_born' => '2003.01.01')
|
93
|
+
expect(users.count).to eq(2)
|
94
|
+
|
95
|
+
users = User.scoped.easy_filter('filter_to_born' => '2003.01.01')
|
96
|
+
expect(users.count).to eq(3)
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: easy_filter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Kepes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activerecord
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sqlite3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Filter and sort ActiveRecord model for Rails app with Bootstrap view
|
98
|
+
helpers
|
99
|
+
email:
|
100
|
+
- kepes.peter@codeplay.hu
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- .gitignore
|
106
|
+
- .rspec
|
107
|
+
- .rubocop.yml
|
108
|
+
- .ruby-gemset
|
109
|
+
- .ruby-version
|
110
|
+
- CHANGELOG.md
|
111
|
+
- Gemfile
|
112
|
+
- LICENSE.txt
|
113
|
+
- README.md
|
114
|
+
- Rakefile
|
115
|
+
- app/assets/javascripts/easy_filter.js
|
116
|
+
- app/assets/stylesheets/easy_filter.css.scss
|
117
|
+
- app/views/easy_filter/_buttons.html.erb
|
118
|
+
- app/views/easy_filter/_field_array.html.erb
|
119
|
+
- app/views/easy_filter/_field_datetime.html.erb
|
120
|
+
- app/views/easy_filter/_field_text.html.erb
|
121
|
+
- app/views/easy_filter/_form_close.html.erb
|
122
|
+
- app/views/easy_filter/_form_field_close.html.erb
|
123
|
+
- app/views/easy_filter/_form_field_open.html.erb
|
124
|
+
- app/views/easy_filter/_form_open.html.erb
|
125
|
+
- app/views/easy_filter/_sort_field.html.erb
|
126
|
+
- easy_filter.gemspec
|
127
|
+
- lib/easy_filter.rb
|
128
|
+
- lib/easy_filter/engine.rb
|
129
|
+
- lib/easy_filter/model_additions.rb
|
130
|
+
- lib/easy_filter/railtie.rb
|
131
|
+
- lib/easy_filter/version.rb
|
132
|
+
- lib/easy_filter/view_helpers.rb
|
133
|
+
- spec/easy_filter/model_additions_spec.rb
|
134
|
+
- spec/spec_helper.rb
|
135
|
+
homepage: https://github.com/kepes/easy-filter
|
136
|
+
licenses:
|
137
|
+
- MIT
|
138
|
+
metadata: {}
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - ! '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ! '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubyforge_project:
|
155
|
+
rubygems_version: 2.1.11
|
156
|
+
signing_key:
|
157
|
+
specification_version: 4
|
158
|
+
summary: ActiveRecord model filter
|
159
|
+
test_files:
|
160
|
+
- spec/easy_filter/model_additions_spec.rb
|
161
|
+
- spec/spec_helper.rb
|