Skip to content

Instantly share code, notes, and snippets.

@stephancom
Last active August 21, 2019 14:48
Show Gist options
  • Save stephancom/64515f783e770c68ff80 to your computer and use it in GitHub Desktop.
Save stephancom/64515f783e770c68ff80 to your computer and use it in GitHub Desktop.
polyPicker - allows for picking a polymorphic object in ActiveAdmin formtastic with select
/ _ ___ _ _
/ _ __ ___| |_ _| _ (_)__| |_____ _ _
/ | '_ \/ _ \ | || | _/ / _| / / -_) '_|
/ | .__/\___/_|\_, |_| |_\__|_\_\___|_|
/ |_| |__/ s.c14
/ This partial is meant to allow for picking an object of polymorphic type, returning both a type and id
/ It is comprised of two select elements, the first of which controls the available choices in the second
/ It relies on the poly_picker.js.coffee script on the front end
/ It expects to find these locals:
/ f: a form builder
/ field: the target field for the picker
/ types: an array of classes which may be selected
/ There must be a collection_action :options defined in ActiveAdmin for each potential type,
/ which returns a collection of options corresponding to that type.
/ Failure to do this will return a method_not_found for the path to this action.
/ A hash of these paths is attached to the source select element
- type_field = "#{field}_type".to_sym
- id_field = "#{field}_id".to_sym
- unpicked = f.object.send(field).nil? # has this field been picked already?
- empty_message = 'Select a type'
- path_collection = types.inject({}) { |hash, type| hash[type] = polymorphic_path([:options, :admin, type.name.underscore.pluralize]); hash}
- id_collection = unpicked ? [[empty_message, nil]] : Object.const_get(f.object.send(type_field)).all
- f.inputs field, class: 'inputs poly-picker' do
- f.input type_field, as: :select, collection: types, input_html: {class: 'poly-picker-source', data: {poly_picker_empty: content_tag(:option, empty_message), poly_picker_paths: path_collection}}
- f.input id_field, as: :select, collection: id_collection, input_html: {class: 'poly-picker-target', disabled: unpicked}
include ActionView::Helpers::FormOptionsHelper
ActiveAdmin.register Ordinary do
collection_action :options, method: :get do
render text: options_from_collection_for_select(Ordinary.all, :id, :name)
end
end
# _ ___ _ _
# _ __ ___| |_ _| _ (_)__| |_____ _ _
# | '_ \/ _ \ | || | _/ / _| / / -_) '_|
# | .__/\___/_|\_, |_| |_\__|_\_\___|_|
# |_| |__/ s.c14
# see documentation in poly_picker.html.slim
jQuery ->
loading_option = ->
$("<option>").text("Loading...").val null
$(".poly-picker .poly-picker-source").on 'change', ->
target = $(this).closest(".poly-picker").find(".poly-picker-target")
target.attr "disabled", "disabled"
targetPath = $(this).data('poly-picker-paths')[$(this).val()]
if targetPath
target.html(loading_option()).load targetPath, ->
target.removeAttr "disabled"
else
target.html $(this).data("poly-picker-empty")
# target.removeAttr "disabled"
ActiveAdmin.register Typical do
form do |f|
f.template.render partial: 'admin/shared/poly_picker', locals: {f: f, field: :pickee, types: [Ordinary]}
f.actions
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment