Search select and multiple?
Opened this issue · 4 comments
Hello, first of all big fan of the gem, it saves a lot of headaches.
I would like to ask if there's a proper way to implement ajax search into a multiple select field while using the search_select plugin
I've tried
f.input :package_ids, as: :search_select, multiple: true,
url: admin_packages_path, fields: [:name],
minimum_input_length: 2,
order_by: 'name'
But it stays as a single selection input, now I managed to circumvent it by adding the multiple flag trough html options
f.input :package_ids, as: :search_select,
url: admin_packages_path, fields: [:name],
minimum_input_length: 2,
order_by: 'name',
input_html: { multiple: true }
And this works like a charm when the field is empty, both the multi select and ajax search work fine and it persists correctly, however as I re enter the form to edit it the field only displays one of the options, I've tried overwriting the selected values trough html options as well but it doesn't seem to work, any ideas?
hi @JoDaBaRo! Thanks for noticing that, I haven't faced this situation before, but I could confirm and reproduce the behavior you describe. I think you found a clever workaround that proves this change should not be that hard to implement if you can figure out how to deal with the "initial load" of the multiple values.
I reviewed the code and indeed, the multiple option is not supported by the search select input, however, I think it could be a worthy addition. I haven't got the time to implement it myself but I'd gladly review it if you or someone else wants to implement it.
@rjherrera I don't think I have the time to make a proper PR but I did dig around and I believe I found the culprit here, looks like the selected_item
helper method is calling first
on the selected collection. Updating this would require another helper method to be updated too, something like this:
module ActiveAdminAddons
module SelectHelpers
. . .
def initial_collection_to_select_options
initial_options = [[nil]]
selected = selected_item
unless selected.empty?
selected.each do |option|
selected_option = item_to_select_option(option)
initial_options << [selected_option[:text], selected_option[:id]]
end
end
initial_options
end
def selected_item
@selected_item ||= selected_collection
end
. . .
end
end
Right now I have these methods overwritten in an active admin concern that I'm calling on the admin form I need it for, It doesn't seem to be breaking anything but I haven't ran any specs on it so can't be certain about it
I've made it work using the default select
input, which renders as select2
when ActiveAdmin Addons is installed.
In your form:
f.input :recipients, as: :select, multiple: true, input_html: { 'data-ajax--url': list_recipients_admin_message_path(resource) }
And in your admin/messages.rb
:
member_action :list_recipients, method: :get do
term = params[:term] || ''
return render json: { results: [] } if term.size < 2
query = User.where('users.nickname ILIKE ?', "%#{term}%").uniq
select_keys = [:id, :nickname]
output_keys = [:id, :text]
results = query.pluck(*select_keys).map { |pa| Hash[output_keys.zip(pa)] }
render json: { results: results }
end
Some links that helped me :
- list of all Select2 options : https://select2.org/data-sources/ajax#jquery-ajax-options
- how to pass options to Select2 using
data
attributes : https://select2.org/configuration/data-attributes - how to do a
pluck
with column names : https://stackoverflow.com/a/27995494/1439489
This solution requires that you write you own search and you won't have as many free options as you'd have with search_select
, but it was an easy win for my simple scenario.
FYI Also facing this issue. Is there another known workaround?