activeadmin-searchable_select 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
require 'support/models'
|
4
|
+
require 'support/capybara'
|
5
|
+
require 'support/active_admin_helpers'
|
6
|
+
|
7
|
+
RSpec.describe 'end to end', type: :feature, js: true do
|
8
|
+
before(:each) do
|
9
|
+
ActiveAdminHelpers.setup do
|
10
|
+
ActiveAdmin.register(Category) do
|
11
|
+
searchable_select_options(scope: Category, text_attribute: :name)
|
12
|
+
end
|
13
|
+
|
14
|
+
ActiveAdmin.register(Post) do
|
15
|
+
filter(:category, as: :searchable_select, ajax: true)
|
16
|
+
|
17
|
+
form do |f|
|
18
|
+
f.input(:category, as: :searchable_select, ajax: true)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
ActiveAdmin.setup {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'index page with searchable select filter' do
|
27
|
+
before(:each) do
|
28
|
+
music_category = Category.create(name: 'Music')
|
29
|
+
travel_category = Category.create(name: 'Travel')
|
30
|
+
|
31
|
+
Post.create(title: 'Best songs',
|
32
|
+
category: music_category)
|
33
|
+
Post.create(title: 'Best places',
|
34
|
+
category: travel_category)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'loads filter input options' do
|
38
|
+
visit '/admin/posts'
|
39
|
+
|
40
|
+
expand_select_box
|
41
|
+
|
42
|
+
expect(select_box_items).to eq(%w(Music Travel))
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'allows filtering options by term' do
|
46
|
+
visit '/admin/posts'
|
47
|
+
|
48
|
+
expand_select_box
|
49
|
+
|
50
|
+
wait_for_ajax do
|
51
|
+
enter_search_term('T')
|
52
|
+
end
|
53
|
+
|
54
|
+
expect(select_box_items).to eq(%w(Travel))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def expand_select_box
|
59
|
+
find('.select2-container').click
|
60
|
+
end
|
61
|
+
|
62
|
+
def enter_search_term(term)
|
63
|
+
find('.select2-dropdown input').send_keys(term)
|
64
|
+
end
|
65
|
+
|
66
|
+
def select_box_items
|
67
|
+
all('.select2-dropdown li').map(&:text)
|
68
|
+
end
|
69
|
+
|
70
|
+
def wait_for_ajax(count = 1)
|
71
|
+
page.execute_script 'window._ajaxCalls = 0'
|
72
|
+
page.execute_script 'window._ajaxCompleteCounter = function() { window._ajaxCalls += 1; }'
|
73
|
+
page.execute_script '$(document).ajaxComplete(window._ajaxCompleteCounter)'
|
74
|
+
|
75
|
+
yield
|
76
|
+
|
77
|
+
sleep(0.5) until finished_all_ajax_requests?(count)
|
78
|
+
end
|
79
|
+
|
80
|
+
def finished_all_ajax_requests?(count)
|
81
|
+
page.evaluate_script('window._ajaxCalls') == count
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
require 'support/models'
|
4
|
+
require 'support/capybara'
|
5
|
+
require 'support/active_admin_helpers'
|
6
|
+
|
7
|
+
RSpec.describe 'filter input', type: :request do
|
8
|
+
describe 'without ajax option' do
|
9
|
+
before(:each) do
|
10
|
+
ActiveAdminHelpers.setup do
|
11
|
+
ActiveAdmin.register(Post) do
|
12
|
+
filter :category, as: :searchable_select
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'renders select input with searchable-select-input css class' do
|
18
|
+
get '/admin/posts'
|
19
|
+
|
20
|
+
expect(response.body).to have_selector('select.searchable-select-input')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'renders options statically' do
|
24
|
+
Category.create!(name: 'Travel')
|
25
|
+
Category.create!(name: 'Music')
|
26
|
+
|
27
|
+
get '/admin/posts'
|
28
|
+
|
29
|
+
expect(response.body).to have_selector('.searchable-select-input option', text: 'Travel')
|
30
|
+
expect(response.body).to have_selector('.searchable-select-input option', text: 'Music')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'does not set data-ajax-url attribute' do
|
34
|
+
get '/admin/posts'
|
35
|
+
|
36
|
+
expect(response.body).not_to have_selector('.searchable-select-input[data-ajax-url]')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
shared_examples 'renders ajax based searchable select input' do
|
41
|
+
it 'renders select input with searchable-select-input css class' do
|
42
|
+
get '/admin/posts'
|
43
|
+
|
44
|
+
expect(response.body).to have_selector('select.searchable-select-input')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'does not render options statically' do
|
48
|
+
Category.create!(name: 'Travel')
|
49
|
+
|
50
|
+
get '/admin/posts'
|
51
|
+
|
52
|
+
expect(response.body).not_to have_selector('.searchable-select-input option', text: 'Travel')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'sets data-ajax-url attribute' do
|
56
|
+
get '/admin/posts'
|
57
|
+
|
58
|
+
expect(response.body).to have_selector('.searchable-select-input[data-ajax-url]')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'renders selected option for current value' do
|
62
|
+
category = Category.create!(name: 'Travel')
|
63
|
+
|
64
|
+
get "/admin/posts?q[category_id_eq]=#{category.id}"
|
65
|
+
|
66
|
+
expect(response.body).to have_selector('.searchable-select-input option[selected]',
|
67
|
+
text: 'Travel')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'with ajax option set to true' do
|
72
|
+
before(:each) do
|
73
|
+
ActiveAdminHelpers.setup do
|
74
|
+
ActiveAdmin.register(Category) do
|
75
|
+
searchable_select_options(scope: Category, text_attribute: :name)
|
76
|
+
end
|
77
|
+
|
78
|
+
ActiveAdmin.register(Post) do
|
79
|
+
filter(:category,
|
80
|
+
as: :searchable_select,
|
81
|
+
ajax: true)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
include_examples 'renders ajax based searchable select input'
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'with options collection name passed in ajax option' do
|
90
|
+
before(:each) do
|
91
|
+
ActiveAdminHelpers.setup do
|
92
|
+
ActiveAdmin.register(Category) do
|
93
|
+
searchable_select_options(name: 'custom', scope: Category, text_attribute: :name)
|
94
|
+
end
|
95
|
+
|
96
|
+
ActiveAdmin.register(Post) do
|
97
|
+
filter(:category,
|
98
|
+
as: :searchable_select,
|
99
|
+
ajax: {
|
100
|
+
collection_name: 'custom'
|
101
|
+
})
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
include_examples 'renders ajax based searchable select input'
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'with options resource passed in ajax option' do
|
110
|
+
before(:each) do
|
111
|
+
ActiveAdminHelpers.setup do
|
112
|
+
ActiveAdmin.register(Category) do
|
113
|
+
searchable_select_options(scope: Category, text_attribute: :name)
|
114
|
+
end
|
115
|
+
|
116
|
+
ActiveAdmin.register(Post) do
|
117
|
+
filter(:category_id_eq,
|
118
|
+
as: :searchable_select,
|
119
|
+
ajax: {
|
120
|
+
resource: Category
|
121
|
+
})
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
include_examples 'renders ajax based searchable select input'
|
127
|
+
end
|
128
|
+
|
129
|
+
describe 'with options resource and collection name passed in ajax option' do
|
130
|
+
before(:each) do
|
131
|
+
ActiveAdminHelpers.setup do
|
132
|
+
ActiveAdmin.register(Category) do
|
133
|
+
searchable_select_options(name: 'custom', scope: Category, text_attribute: :name)
|
134
|
+
end
|
135
|
+
|
136
|
+
ActiveAdmin.register(Post) do
|
137
|
+
filter(:category_id_eq,
|
138
|
+
as: :searchable_select,
|
139
|
+
ajax: {
|
140
|
+
resource: Category,
|
141
|
+
collection_name: 'custom'
|
142
|
+
})
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
include_examples 'renders ajax based searchable select input'
|
148
|
+
end
|
149
|
+
|
150
|
+
describe 'with selected option in ajax mode' do
|
151
|
+
it 'applies scope when looking up record' do
|
152
|
+
ActiveAdminHelpers.setup do
|
153
|
+
ActiveAdmin.register(Category) do
|
154
|
+
searchable_select_options(scope: Category.none, text_attribute: :name)
|
155
|
+
end
|
156
|
+
|
157
|
+
ActiveAdmin.register(Post) do
|
158
|
+
filter(:category, as: :searchable_select, ajax: true)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
category = Category.create!(name: 'Travel')
|
163
|
+
|
164
|
+
get "/admin/posts?q[category_id_eq]=#{category.id}"
|
165
|
+
|
166
|
+
expect(response.body).not_to have_selector('.searchable-select-input option[selected]')
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'allows to use view helpers in scope lambda' do
|
170
|
+
ActiveAdminHelpers.setup do
|
171
|
+
ActiveAdmin.register(Category) do
|
172
|
+
searchable_select_options(scope: -> { Category.where(created_by: current_user) },
|
173
|
+
text_attribute: :name)
|
174
|
+
end
|
175
|
+
|
176
|
+
ActiveAdmin.register(Post) do
|
177
|
+
filter(:category, as: :searchable_select, ajax: true)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
user = User.create!
|
182
|
+
ApplicationController.current_user = user
|
183
|
+
category = Category.create!(name: 'Travel', created_by: user)
|
184
|
+
|
185
|
+
get "/admin/posts?q[category_id_eq]=#{category.id}"
|
186
|
+
|
187
|
+
expect(response.body).to have_selector('.searchable-select-input option[selected]',
|
188
|
+
text: 'Travel')
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
require 'support/models'
|
4
|
+
require 'support/capybara'
|
5
|
+
require 'support/active_admin_helpers'
|
6
|
+
|
7
|
+
RSpec.describe 'form input', type: :request do
|
8
|
+
describe 'without ajax option' do
|
9
|
+
before(:each) do
|
10
|
+
ActiveAdminHelpers.setup do
|
11
|
+
ActiveAdmin.register(Post) do
|
12
|
+
form do |f|
|
13
|
+
f.input :category, as: :searchable_select
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'renders select input with searchable-select-input css class' do
|
20
|
+
get '/admin/posts/new'
|
21
|
+
|
22
|
+
expect(response.body).to have_selector('select.searchable-select-input')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'renders options statically' do
|
26
|
+
Category.create!(name: 'Travel')
|
27
|
+
Category.create!(name: 'Music')
|
28
|
+
|
29
|
+
get '/admin/posts/new'
|
30
|
+
|
31
|
+
expect(response.body).to have_selector('.searchable-select-input option', text: 'Travel')
|
32
|
+
expect(response.body).to have_selector('.searchable-select-input option', text: 'Music')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'does not set data-ajax-url attribute' do
|
36
|
+
get '/admin/posts/new'
|
37
|
+
|
38
|
+
expect(response.body).not_to have_selector('.searchable-select-input[data-ajax-url]')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
shared_examples 'renders ajax based searchable select input' do
|
43
|
+
it 'renders select input with searchable-select-input css class' do
|
44
|
+
get '/admin/posts/new'
|
45
|
+
|
46
|
+
expect(response.body).to have_selector('select.searchable-select-input')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'does not render options statically' do
|
50
|
+
Category.create!(name: 'Travel')
|
51
|
+
|
52
|
+
get '/admin/posts/new'
|
53
|
+
|
54
|
+
expect(response.body).not_to have_selector('.searchable-select-input option', text: 'Travel')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'sets data-ajax-url attribute' do
|
58
|
+
get '/admin/posts/new'
|
59
|
+
|
60
|
+
expect(response.body).to have_selector('.searchable-select-input[data-ajax-url]')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'renders selected option for current value' do
|
64
|
+
category = Category.create!(name: 'Travel')
|
65
|
+
post = Post.create!(title: 'A post', category: category)
|
66
|
+
|
67
|
+
get "/admin/posts/#{post.id}/edit"
|
68
|
+
|
69
|
+
expect(response.body).to have_selector('.searchable-select-input option[selected]',
|
70
|
+
text: 'Travel')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'with ajax option set to true' do
|
75
|
+
before(:each) do
|
76
|
+
ActiveAdminHelpers.setup do
|
77
|
+
ActiveAdmin.register(Category) do
|
78
|
+
searchable_select_options(scope: Category, text_attribute: :name)
|
79
|
+
end
|
80
|
+
|
81
|
+
ActiveAdmin.register(Post) do
|
82
|
+
form do |f|
|
83
|
+
f.input(:category,
|
84
|
+
as: :searchable_select,
|
85
|
+
ajax: true)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
include_examples 'renders ajax based searchable select input'
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'with options collection name passed in ajax option' do
|
95
|
+
before(:each) do
|
96
|
+
ActiveAdminHelpers.setup do
|
97
|
+
ActiveAdmin.register(Category) do
|
98
|
+
searchable_select_options(name: 'custom', scope: Category, text_attribute: :name)
|
99
|
+
end
|
100
|
+
|
101
|
+
ActiveAdmin.register(Post) do
|
102
|
+
form do |f|
|
103
|
+
f.input(:category,
|
104
|
+
as: :searchable_select,
|
105
|
+
ajax: {
|
106
|
+
collection_name: 'custom'
|
107
|
+
})
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
include_examples 'renders ajax based searchable select input'
|
114
|
+
end
|
115
|
+
|
116
|
+
describe 'with options resource passed in ajax option' do
|
117
|
+
before(:each) do
|
118
|
+
ActiveAdminHelpers.setup do
|
119
|
+
ActiveAdmin.register(Category) do
|
120
|
+
searchable_select_options(scope: Category, text_attribute: :name)
|
121
|
+
end
|
122
|
+
|
123
|
+
ActiveAdmin.register(Post) do
|
124
|
+
form do |f|
|
125
|
+
f.input(:category_id,
|
126
|
+
as: :searchable_select,
|
127
|
+
ajax: {
|
128
|
+
resource: Category
|
129
|
+
})
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
include_examples 'renders ajax based searchable select input'
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'with options resource and collection name passed in ajax option' do
|
139
|
+
before(:each) do
|
140
|
+
ActiveAdminHelpers.setup do
|
141
|
+
ActiveAdmin.register(Category) do
|
142
|
+
searchable_select_options(name: 'custom', scope: Category, text_attribute: :name)
|
143
|
+
end
|
144
|
+
|
145
|
+
ActiveAdmin.register(Post) do
|
146
|
+
form do |f|
|
147
|
+
f.input(:category_id,
|
148
|
+
as: :searchable_select,
|
149
|
+
ajax: {
|
150
|
+
resource: Category,
|
151
|
+
collection_name: 'custom'
|
152
|
+
})
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
include_examples 'renders ajax based searchable select input'
|
159
|
+
end
|
160
|
+
|
161
|
+
describe 'with custom class attribute' do
|
162
|
+
before(:each) do
|
163
|
+
ActiveAdminHelpers.setup do
|
164
|
+
ActiveAdmin.register(Post) do
|
165
|
+
form do |f|
|
166
|
+
f.input :category, as: :searchable_select, input_html: { class: 'custom' }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'adds searchable-select-input css class' do
|
173
|
+
get '/admin/posts/new'
|
174
|
+
|
175
|
+
expect(response.body).to have_selector('select.custom.searchable-select-input')
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|