Skip to content

Commit

Permalink
Add a custom form helper for displaying collection options
Browse files Browse the repository at this point in the history
**ISSUE**
We want to be able to provide a collection drop-down selection list
in our collection and item edit forms, but we want it to handle
multivalue fields by displaying individual inputs that aggregate
as an array valued parameter - i.e. each takes a single value and the
field name ends in '[]' - instead of a multi-value select box.

**SOLUTION**
Implement a custom input that provides the desired behaviors for our
forms.
  • Loading branch information
mark-dce committed Apr 14, 2024
1 parent b1d41ff commit 9f8ab02
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ Style/FrozenStringLiteralComment:
Style/HashSyntax:
EnforcedShorthandSyntax: never

Style/OpenStructUse:
Exclude:
- 'spec/helpers/t3_form_builder_spec.rb'

Style/SymbolProc:
AllowedPatterns: ['map', 'select']

Expand Down
15 changes: 15 additions & 0 deletions app/helpers/t3_form_builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Custom form controls to support T3 field-specific data types
# e.g. #vacabulary provides a customized select populated with a defined vocabulary
class T3FormBuilder < ActionView::Helpers::FormBuilder
def vocabulary(method, options = {})
multiple = options.delete(:multiple)
selected = options.delete(:value) || ''
select_options = options.except(:multiple)
.reverse_merge(
{ name: @template.field_name(@object_name, method, multiple: multiple) }
)
.merge({ selected: selected })
option_tags = @template.options_from_collection_for_select(Collection.order(:created_at), :id, :id, selected)
select(method, option_tags, { prompt: 'Select one', selected: '', disabled: true }, select_options)
end
end
50 changes: 50 additions & 0 deletions spec/helpers/t3_form_builder_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'rails_helper'

RSpec.describe T3FormBuilder do
let(:form_builder) do
described_class.new('item[metadata]',
OpenStruct.new({ 'Title' => 'Working Papers' }),
Object.extend(ActionView::Helpers::FormHelper,
ActionView::Helpers::FormTagHelper, ActionView::Helpers::FormOptionsHelper),
{})
end
let(:tag_options) { {} }

describe '#vocabulary' do
let(:vocabulary_helper) { Capybara.string(form_builder.vocabulary(:collection, tag_options)) }

it 'renders a select with the expected id' do
expect(vocabulary_helper).to have_select('item[metadata][collection]')
end

it 'displays a prompt when no value is selected' do
expect(vocabulary_helper).to have_selector('select option[selected]', text: 'Select one')
end

context 'with options {multipe: true}' do
let(:tag_options) { { multiple: true } }

it 'renders as an array instead of a multi-select' do
expect(vocabulary_helper).to have_select('item[metadata][collection][]')
end
end

describe 'displays options' do
let(:tag_options) { { value: 'Green' } }

before do
collections = [OpenStruct.new({ id: 'Red' }), OpenStruct.new({ id: 'Green' }), OpenStruct.new({ id: 'Blue' })]
allow(Collection).to receive(:order).and_return(collections)
end

example 'showing available collections' do
select_options = vocabulary_helper.all('option').map(&:text)
expect(select_options).to eq ['Select one', 'Red', 'Green', 'Blue']
end

example 'with a selection' do
expect(vocabulary_helper).to have_selector('select option[selected]', text: 'Green')
end
end
end
end

0 comments on commit 9f8ab02

Please sign in to comment.