Skip to content

Instantly share code, notes, and snippets.

@boie0025
Forked from frank-who/Gemfile
Last active January 9, 2018 18:37
Show Gist options
  • Save boie0025/0fbbb67fd37cb92e7a530d74e557ace6 to your computer and use it in GitHub Desktop.
Save boie0025/0fbbb67fd37cb92e7a530d74e557ace6 to your computer and use it in GitHub Desktop.
Postgres Arrays in Active Admin
// app/assets/stylesheets/active_admin.sass
=reset-aa-button
background: none
border-radius: 0
border: 0
box-shadow: none
line-height: 1
padding: 0
text-shadow: none
vertical-align: middle
&:not(.disabled)
&:hover,
&:active,
&:focus
background: none
border: 0
box-shadow: none
.array-action--add,
.array-action--remove
+reset-aa-button
font-size: rem(15)
.array-action--add
color: $alert-success-color
.array-action--remove
color: $alert-error-color
&.can-undo
color: $alert-success-color
# app/assets/javascripts/array-input.coffee
$ ->
removeFromArrayInput = (el) ->
input = $(el).siblings('input')
if input.attr('disabled') == 'disabled'
$(el)
.html('<i class="fa fa-times-circle"></i>')
.removeClass('can-undo')
$(input).removeAttr('disabled')
$(input).removeClass('text--strike')
else
$(el)
.html('<i class="fa fa-undo"></i>')
.addClass('can-undo')
$(input).attr('disabled', 'disabled')
$(input).addClass('text--strike')
$('.js-add-to-array-input').click (e) ->
e.preventDefault
if $(@).hasClass('array-action--add')
original = $(@).parent()
clone = $(original).clone(true)
clone_id = "clone_#{Math.floor((Math.random() * 100000) + 1)}"
input = $(clone).find('input')
if $(input).val() != ''
# Remove error classes from original's input
$(original)
.find('input')
.removeClass('has-error')
# Reset clone's input
$(input)
.removeClass('has-error')
.attr('id', clone_id)
.val('')
# Change action to remove
$(@)
.html('<i class="fa fa-times-circle"></i>')
.attr('class', 'array-action--remove js-remove-from-array-input')
# Add clone and focus its input
$(@).parent().parent().append $(clone)
$("##{clone_id}").focus()
else
$(original)
.find('input')
.addClass('has-error')
.focus()
else
removeFromArrayInput $(@)
$('.js-remove-from-array-input').click (e) ->
e.preventDefault
removeFromArrayInput $(@)
# based on https://gist.github.com/kivanio/2fdfaa723350d6e85c1a
class ArrayInput
include Formtastic::Inputs::Base::Choices
include Formtastic::Inputs::Base
def to_html
input_wrapping do
inputs = []
@object[method].each_with_index do |v, x|
inputs << array_input_html(v)
end
choices_wrapping do
legend_html <<
choices_group_wrapping do
template.content_tag(:div, class: 'input-group--array') do
inputs.join.html_safe << array_input_html('', false)
end
end
end
end
end
private
def array_input_html(value, remove=true)
if remove
button = template.content_tag(:button, template.fa_icon('minus-circle'), class: 'array-action--remove js-remove-from-array-input', type: 'button')
else
button = template.content_tag(:button, template.fa_icon('plus-circle'), class: 'array-action--add js-add-to-array-input', type: 'button')
end
template.content_tag(:li, class: 'choice input-group--array__item') do
template.text_field_tag("#{object_name}[#{method}][]", value, id: nil) << button
end
end
end
# app/admin/client.rb
ActiveAdmin.register Client do
permit_params email_addresses: []
form do |f|
f.inputs 'Contact Details' do
f.input :email_addresses, as: :array
end
f.actions
end
end
class Client < ActiveRecord::Base # Used with Mongoid as well.
def email_addresses=(vals)
write_attribute(:email_addresses, vals.reject(&:blank?))
end
end
ruby '2.2.0'
source 'https://rubygems.org'
...
gem 'font-awesome-rails'
class AddEmailAddressesToClients < ActiveRecord::Migration
def change
add_column :clients, :email_addresses, :text, array: true, default: []
add_index :clients, :email_addresses, using: 'gin'
end
end
@boie0025
Copy link
Author

boie0025 commented Jan 9, 2018

Updated to use the choices wrapping

@boie0025
Copy link
Author

boie0025 commented Jan 9, 2018

Added model note for removing blank entries (with AA 1.1 and mongoid, blank entries are added to the Array field on the document)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment