activeadmin-searchable_select 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +16 -0
- data/.yardopts +2 -0
- data/Appraisals +15 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +25 -0
- data/README.md +247 -0
- data/Rakefile +6 -0
- data/activeadmin-searchable_select.gemspec +37 -0
- data/app/assets/javascripts/active_admin/searchable_select.js.coffee +3 -0
- data/app/assets/javascripts/active_admin/searchable_select/init.js.coffee +29 -0
- data/app/assets/stylesheets/active_admin/searchable_select.scss +5 -0
- data/bin/rspec +17 -0
- data/gemfiles/rails_4.2_active_admin_1.0.0.pre4.gemfile +9 -0
- data/gemfiles/rails_5.1_active_admin_1.0.gemfile +8 -0
- data/gemfiles/rails_5.1_active_admin_1.1.gemfile +8 -0
- data/lib/activeadmin-searchable_select.rb +6 -0
- data/lib/activeadmin/inputs/filters/searchable_select_input.rb +13 -0
- data/lib/activeadmin/inputs/searchable_select_input.rb +11 -0
- data/lib/activeadmin/searchable_select.rb +20 -0
- data/lib/activeadmin/searchable_select/engine.rb +11 -0
- data/lib/activeadmin/searchable_select/option_collection.rb +103 -0
- data/lib/activeadmin/searchable_select/resource_dsl_extension.rb +39 -0
- data/lib/activeadmin/searchable_select/resource_extension.rb +10 -0
- data/lib/activeadmin/searchable_select/select_input_extension.rb +130 -0
- data/lib/activeadmin/searchable_select/version.rb +5 -0
- data/spec/features/ajax_params_spec.rb +53 -0
- data/spec/features/end_to_end_spec.rb +83 -0
- data/spec/features/filter_input_spec.rb +191 -0
- data/spec/features/form_input_spec.rb +178 -0
- data/spec/features/inline_ajax_setting_spec.rb +41 -0
- data/spec/features/input_errors_spec.rb +55 -0
- data/spec/features/options_dsl_spec.rb +248 -0
- data/spec/internal/app/assets/javascripts/active_admin.js +2 -0
- data/spec/internal/app/assets/stylesheets/active_admin.scss +2 -0
- data/spec/internal/app/controllers/application_controller.rb +5 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/initializers/assets.rb +3 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/schema.rb +26 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/rails_helper.rb +13 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/support/active_admin_helpers.rb +9 -0
- data/spec/support/capybara.rb +8 -0
- data/spec/support/models.rb +21 -0
- data/spec/support/pluck_polyfill.rb +12 -0
- data/spec/support/reset_settings.rb +5 -0
- metadata +311 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e45366aab36050f1bacd26cf7c7e083f73366337
|
4
|
+
data.tar.gz: 41b977d5f33c903293d2cccccfcabf2de910c71a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 48d3f353accca041a2bc5d533cc8574d6f895f7b04fca7354b5d10e6fc73c3ae276b555ed031ea8226bcfc0a68f70c49657f737df9c51fb0f6f316700d34c2a4
|
7
|
+
data.tar.gz: 1114951d8895a4a25a1e56162d099c9fc60592241ec79b9ee8c573fed3db93e427b3137f41d555c3a658eef3f0df6cecf2a3f4034e8102a8a4280cfa97336a8e
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.3.4
|
4
|
+
|
5
|
+
# Use container based travis infrastructure which allows caching
|
6
|
+
# features for open source projects.
|
7
|
+
sudo: false
|
8
|
+
cache:
|
9
|
+
bundler: true
|
10
|
+
|
11
|
+
gemfile:
|
12
|
+
- gemfiles/rails_4.2_active_admin_1.0.0.pre4.gemfile
|
13
|
+
- gemfiles/rails_5.1_active_admin_1.0.gemfile
|
14
|
+
- gemfiles/rails_5.1_active_admin_1.1.gemfile
|
15
|
+
|
16
|
+
script: bundle exec rspec
|
data/.yardopts
ADDED
data/Appraisals
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
appraise 'rails-4.2-active-admin-1.0.0.pre4' do
|
2
|
+
gem 'rails', '~> 4.2'
|
3
|
+
gem 'activeadmin', '1.0.0.pre4'
|
4
|
+
gem 'jquery-ui-rails', '~> 5.0'
|
5
|
+
end
|
6
|
+
|
7
|
+
appraise 'rails-5.1-active-admin-1.0' do
|
8
|
+
gem 'rails', '~> 5.1'
|
9
|
+
gem 'activeadmin', '~> 1.0'
|
10
|
+
end
|
11
|
+
|
12
|
+
appraise 'rails-5.1-active-admin-1.1' do
|
13
|
+
gem 'rails', '~> 5.1'
|
14
|
+
gem 'activeadmin', '~> 1.1'
|
15
|
+
end
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
Copyright for portions of `codevise/activeadmin-searchable_select`
|
3
|
+
held by Mark Fariburn, Praxitar Ltd, 2014 as part of
|
4
|
+
`mfairburn/activeadmin-select2` which this project is based on. All
|
5
|
+
other copyright for `codevise/activeadmin-searchable_select` held by
|
6
|
+
Codevise Solutions Ltd, 2017.
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
9
|
+
a copy of this software and associated documentation files (the
|
10
|
+
"Software"), to deal in the Software without restriction, including
|
11
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
12
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
13
|
+
permit persons to whom the Software is furnished to do so, subject to
|
14
|
+
the following conditions:
|
15
|
+
|
16
|
+
The above copyright notice and this permission notice shall be
|
17
|
+
included in all copies or substantial portions of the Software.
|
18
|
+
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
20
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
22
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
23
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
24
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
25
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,247 @@
|
|
1
|
+
# ActiveAdmin Searchable Select
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/activeadmin-searchable_select.svg)](http://badge.fury.io/rb/activeadmin-searchable_select)
|
4
|
+
[![Build Status](https://travis-ci.org/codevise/activeadmin-searchable_select.svg?branch=master)](https://travis-ci.org/codevise/activeadmin-searchable_select)
|
5
|
+
|
6
|
+
Searchable select boxes (via [Select2](https://select2.org/)) for
|
7
|
+
ActiveAdmin forms and filters. Extends the ActiveAdmin resource DSL to
|
8
|
+
allow defining JSON endpoints to fetch options from asynchronously.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add `activeadmin-searchable_select` to your Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'activeadmin-searchable_select
|
16
|
+
```
|
17
|
+
|
18
|
+
Import stylesheets and require javascripts:
|
19
|
+
|
20
|
+
```scss
|
21
|
+
// active_admin.css.scss
|
22
|
+
@import "active_admin/searchable_select";
|
23
|
+
```
|
24
|
+
|
25
|
+
```coffee
|
26
|
+
# active_admin.js.coffee
|
27
|
+
#= require active_admin/searchable_select
|
28
|
+
```
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
### Making Select Boxes Searchable
|
33
|
+
|
34
|
+
To add search functionality to a select box, use the
|
35
|
+
`:searchable_select` input type:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
ActiveAdmin.register Product do
|
39
|
+
form do |f|
|
40
|
+
f.input(:category, as: :searchable_select)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
This also works for filters:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
ActiveAdmin.register Product do
|
49
|
+
filter(:category, as: :searchable_select)
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
### Fetching Options via Ajax
|
54
|
+
|
55
|
+
For large collections, rendering the whole set of options can be to
|
56
|
+
expensive. Use the `ajax` option to fetch a set of matching options
|
57
|
+
once the user begins to type:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
|
61
|
+
ActiveAdmin.register Product do
|
62
|
+
filter(:category,
|
63
|
+
as: :searchable_select,
|
64
|
+
ajax: true)
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
If the input attribute corresponds to an ActiveAdmin resource, it is
|
69
|
+
expected to provide the JSON endpoint that provides the options. Use
|
70
|
+
the `searchable_select_options` method to define the required
|
71
|
+
collection action:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
ActiveAdmin.register Category do
|
75
|
+
searchable_select_options(scope: Category.all,
|
76
|
+
text_attribute: :name)
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
By default, `scope` needs to be a Ransack enabled ActiveRecord
|
81
|
+
collection proxy determining which options are available. The
|
82
|
+
attribute given by `text_attribute` will be used to get a display name
|
83
|
+
for each record. Via Ransack, it is also used to filter by search
|
84
|
+
term. Limiting result set size is handled automatically.
|
85
|
+
|
86
|
+
You can customize the display text:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
ActiveAdmin.register Category do
|
90
|
+
searchable_select_options(scope: Category.all,
|
91
|
+
text_attribute: :name,
|
92
|
+
display_text: ->(record) { "Category: #{record.name}" } )
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
Note that `text_attribute` is still required to perform filtering via
|
97
|
+
Ransack. You can pass the `filter` option, to specify your own
|
98
|
+
filtering strategy:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
ActiveAdmin.register Category do
|
102
|
+
searchable_select_options(scope: Category.all,
|
103
|
+
text_attribute: :name,
|
104
|
+
filter: lambda |term, scope|
|
105
|
+
scope.ransack(name_cont_all: term.split(' ')).result
|
106
|
+
end)
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
`scope` can also be a lambda which is evaluated in the context of the
|
111
|
+
collection action defined by the helper:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
ActiveAdmin.register Category do
|
115
|
+
searchable_select_options(scope: -> { Category.allowed_for(current_user) },
|
116
|
+
text_attribute: :name)
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
If the input attribute is set on the form's object, ajax based
|
121
|
+
searchable selects will automatically render a single option to ensure
|
122
|
+
the selected item is displayed correctly even before options have been
|
123
|
+
loaded asynchronously.
|
124
|
+
|
125
|
+
#### Specifying the Options Endpoint Resource
|
126
|
+
|
127
|
+
If the resource that provides the options endpoint cannot be guessed
|
128
|
+
based on the input attribute name, you can pass an object with a
|
129
|
+
`resource` key as `ajax` option:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
ActiveAdmin.register Product do
|
133
|
+
form do |f|
|
134
|
+
f.input(:additional_category,
|
135
|
+
as: :searchable_select,
|
136
|
+
ajax: { resource: Category })
|
137
|
+
end
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
#### Mutlple Options Endpoints per Resource
|
142
|
+
|
143
|
+
A single ActiveAdmin resource can define multiple options endpoints:
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
ActiveAdmin.register Category do
|
147
|
+
searchable_select_options(name: :favorites,
|
148
|
+
scope: Category.favorites,
|
149
|
+
text_attribute: :name)
|
150
|
+
|
151
|
+
searchable_select_options(name: :recent,
|
152
|
+
scope: Category.recent,
|
153
|
+
text_attribute: :name)
|
154
|
+
end
|
155
|
+
```
|
156
|
+
|
157
|
+
To specify which collection to use, pass an object with a
|
158
|
+
`collection_name` key as `ajax` option:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
ActiveAdmin.register Product do
|
162
|
+
form do |f|
|
163
|
+
f.input(:category,
|
164
|
+
as: :searchable_select,
|
165
|
+
ajax: { collection_name: :favorites })
|
166
|
+
end
|
167
|
+
end
|
168
|
+
```
|
169
|
+
|
170
|
+
#### Passing Parameters
|
171
|
+
|
172
|
+
You can pass additional parameters to the options endpoint:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
ActiveAdmin.register Product do
|
176
|
+
form do |f|
|
177
|
+
f.input(:category,
|
178
|
+
as: :searchable_select,
|
179
|
+
ajax: {
|
180
|
+
params: {
|
181
|
+
some: 'value'
|
182
|
+
}
|
183
|
+
})
|
184
|
+
end
|
185
|
+
end
|
186
|
+
```
|
187
|
+
|
188
|
+
The lambda passed as `scope` can receive those parameters as first
|
189
|
+
argument:
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
ActiveAdmin.register Category do
|
193
|
+
searchable_select_options(scope: lambda do |params|
|
194
|
+
Category.find_all_by_some(params[:some])
|
195
|
+
end,
|
196
|
+
text_attribute: :name)
|
197
|
+
end
|
198
|
+
```
|
199
|
+
|
200
|
+
#### Inlining Ajax Options in Feature Tests
|
201
|
+
|
202
|
+
When writing UI driven feature specs (i.e. with Capybara),
|
203
|
+
asynchronous loading of select options can increase test
|
204
|
+
complexity. `activeadmin-searchable_select` provides an option to
|
205
|
+
render all available options just like a normal select input while
|
206
|
+
still exercsing the same code paths including `scope` and
|
207
|
+
`text_attribute` handling.
|
208
|
+
|
209
|
+
For example with RSpec/Capybara, simply set `inline_ajax_options` true
|
210
|
+
for feature specs:
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
RSpec.configure do |config|
|
214
|
+
config.before(:each) do |example|
|
215
|
+
ActiveAdmin::Select2.inline_ajax_options = (example.metadata[:type] == :feature)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
```
|
220
|
+
|
221
|
+
## Development
|
222
|
+
|
223
|
+
To run the tests install bundled gems and invoke RSpec:
|
224
|
+
|
225
|
+
```
|
226
|
+
$ bundle
|
227
|
+
$ bundle exec rspec
|
228
|
+
```
|
229
|
+
|
230
|
+
The test suite can be run against different versions of Rails and
|
231
|
+
Active Admin (see `Appraisals` file):
|
232
|
+
|
233
|
+
```
|
234
|
+
$ appraisal install
|
235
|
+
$ appraisal rspec
|
236
|
+
```
|
237
|
+
|
238
|
+
Please make sure changes conform with the styleguide:
|
239
|
+
|
240
|
+
```
|
241
|
+
$ bundle exec rubocop
|
242
|
+
```
|
243
|
+
|
244
|
+
## Acknowledgements
|
245
|
+
|
246
|
+
Based on
|
247
|
+
[mfairburn/activeadmin-select2](https://github.com/mfairburn/activeadmin-select2).
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'activeadmin/searchable_select/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'activeadmin-searchable_select'
|
9
|
+
spec.version = ActiveAdmin::SearchableSelect::VERSION
|
10
|
+
spec.summary = 'Use searchable selects based on Select2 in Active Admin forms and filters.'
|
11
|
+
spec.license = 'MIT'
|
12
|
+
spec.authors = ['Codevise Solutions Ltd']
|
13
|
+
spec.email = 'info@codevise.de'
|
14
|
+
spec.homepage = 'https://github.com/codevise/activeadmin-searchable_select'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
|
19
|
+
spec.required_ruby_version = '~> 2.1'
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'appraisal', '~> 2.2'
|
24
|
+
spec.add_development_dependency 'rspec-rails', '~> 3.6'
|
25
|
+
spec.add_development_dependency 'combustion', '~> 0.7.0'
|
26
|
+
spec.add_development_dependency 'database_cleaner', '~> 1.6'
|
27
|
+
spec.add_development_dependency 'sqlite3', '~> 1.3'
|
28
|
+
spec.add_development_dependency 'capybara', '~> 2.15'
|
29
|
+
spec.add_development_dependency 'poltergeist', '~> 1.15'
|
30
|
+
spec.add_development_dependency 'rubocop', '~> 0.42.0'
|
31
|
+
spec.add_development_dependency 'semmy', '~> 1.0'
|
32
|
+
spec.add_development_dependency 'rails'
|
33
|
+
|
34
|
+
spec.add_runtime_dependency 'activeadmin', '~> 1.x'
|
35
|
+
spec.add_runtime_dependency 'jquery-rails', ['>= 3.0', '< 5']
|
36
|
+
spec.add_runtime_dependency 'select2-rails', '~> 4.0'
|
37
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
initSearchableSelects = (inputs, extra = {}) ->
|
4
|
+
inputs.each ->
|
5
|
+
item = $(this)
|
6
|
+
# reading from data allows <input data-searchable_select='{"tags": ['some']}'>
|
7
|
+
# to be passed to select2
|
8
|
+
options = $.extend(extra, item.data('searchableSelect'))
|
9
|
+
url = item.data('ajaxUrl');
|
10
|
+
|
11
|
+
if url
|
12
|
+
$.extend(
|
13
|
+
options,
|
14
|
+
ajax: {
|
15
|
+
url: url,
|
16
|
+
dataType: 'json'
|
17
|
+
}
|
18
|
+
)
|
19
|
+
|
20
|
+
item.select2(options)
|
21
|
+
|
22
|
+
$(document).on 'has_many_add:after', '.has_many_container', (e, fieldset) ->
|
23
|
+
initSearchableSelects(fieldset.find('.searchable-select-input'))
|
24
|
+
|
25
|
+
$(document).on 'page:load turbolinks:load', ->
|
26
|
+
initSearchableSelects($(".searchable-select-input"), placeholder: "")
|
27
|
+
return
|
28
|
+
|
29
|
+
$(-> initSearchableSelects($(".searchable-select-input")))
|