platanus / activeadmin_addons

Extends ActiveAdmin to enable a set of great optional UX improving add-ons
MIT License
763 stars 288 forks source link

Search select and multiple? #385

Open JoDaBaRo opened 2 years ago

JoDaBaRo commented 2 years ago

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?

rjherrera commented 2 years ago

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.

JoDaBaRo commented 2 years ago

@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

dvkch commented 2 years ago

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 :

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.

letiesperon commented 5 months ago

FYI Also facing this issue. Is there another known workaround?