Created
October 13, 2015 09:24
-
-
Save fabn/f084ac6aa572d4055588 to your computer and use it in GitHub Desktop.
ActiveAdmin completion inputs for huge associations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Vendored javascript files | |
#= require select2 | |
# Configure defaults for all select2 inputs | |
$.fn.select2.defaults.set 'theme', 'classic' | |
$.fn.select2.defaults.set 'placeholder', 'Type to search' | |
# document ready function | |
jQuery -> | |
$('.ajax-select').select2 | |
ajax: | |
dataType: 'json' | |
delay: 250 | |
data: (params)-> q: params.term, locale: currentLocale() | |
processResults: (data)-> results: _.map data, (t)-> t.disabled = (t.data? && t.data.disabled); t | |
cache: true | |
minimumInputLength: 2 | |
# Custom formatters omitted since they are pretty specific. | |
templateResult: formatResult | |
templateSelection: formatResult |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Used to show an ajax select/multiselect using select2 javascript plugin | |
class AjaxSelectInput < Formtastic::Inputs::SelectInput | |
def input_html_options | |
html_options = super # Get options passed via input_html | |
html_options[:placeholder] ||= 'Type to search' | |
# Css classes for input element | |
html_options[:class] = ['ajax-select'] | |
# Add data with object type we need to complete, make them overridable using html_options | |
html_options[:data] ||= {} | |
html_options[:data][:'allow-clear'] ||= !required? | |
# Allow shortcut when using with formtastic, i.e. f.input :foo, as: :ajax_select, completion_path: '/foo' | |
html_options[:data][:'ajax-url'] ||= options[:completion_path] || template.completion_path(type: data_type) | |
# Return built options | |
html_options | |
end | |
# Always override collection option, this method is important to select2 since its result will be used | |
# to initialize the selection. When resource has no value the collection should be an empty array, in this | |
# way no options are given to select2. When value is present it should be returned to populate the initial | |
# selection of select2 input, this is useful when form is in edit mode | |
def collection_from_options | |
# Allow to be overridden in some cases | |
return super if options.has_key?(:collection) | |
# Retrieve the association collection or single element as array if belongs to | |
multiple? ? object.send(method) : Array(object.send(method)) | |
end | |
# Return data type for the current method, i.e. author => person, categories => category | |
def data_type | |
reflection_for(method).klass.model_name.to_s | |
end | |
# If the form object has any value for the field, works with single and multiple fields | |
def has_value? | |
object.send(method).present? | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CompletionsController < ApplicationController | |
respond_to :json | |
before_action :authenticate_admin_user! | |
before_action :check_requested_type! | |
# Mapped in routes with get '/complete', to: 'completions#index', as: :completion | |
def index | |
respond_with @model.completions(params[:q], locale: params[:locale].presence) | |
end | |
private | |
def check_requested_type! | |
@model = params[:type].camelize.constantize rescue nil | |
head :not_found unless @model.try(:respond_to?, :completions) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FilterAjaxInput < ActiveAdmin::Inputs::FilterSelectInput | |
# Add select2 css classes | |
def input_html_options | |
ajax_options = { | |
class: 'ajax-select', | |
data: { | |
:'ajax-url' => template.completion_path(type: data_type), | |
:'allow-clear' => multiple? | |
} | |
} | |
super.merge(ajax_options) | |
end | |
# Return input name used by metasearch | |
def input_name | |
multiple? ? "#{method}_id_in" : super() | |
end | |
# Do not return any item when building select, values are loaded by ajax | |
def collection | |
value = template.params[:q].try(:[], input_name) | |
return [] unless value.present? | |
klass = reflection_for(method).klass | |
klass.where(id: value).map { |o| [send_or_call(label_method, o), send_or_call(value_method, o)] } | |
end | |
def data_type | |
options[:complete_as] || reflection_for(method).klass.model_name.to_s | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment