Skip to content

Check boxes, with text fields for "other"

futura edited this page Feb 20, 2012 · 5 revisions

I've run into this a lot: I need a fixed checklist of options for the user to choose, but I also need an "other" text box. In some cases, it's overkill to normalize the data and create all the necessary relationships and fields -- specifically when you'll never need to fetch the data across parent records.

I've created some custom inputs to make it easy to serialize the values into a single field:

https://gist.github.com/1869526

Put them in app/inputs or any other load path:

app/inputs/check_boxes_with_other_input.rb
app/inputs/string_as_other_input.rb

If I have a Patient model with a symptoms attribute, I can access each symptom.

# Rails 3.2 'store' provides easy top-level accessors; otherwise, you need to define them manually
class Patient < ActiveRecord::Base
  store :symptoms, accessors: [ 'attention', 'anxiety', 'depressive' ]
end

Then I use CheckBoxesWithOther and StringAsOther to split the serialized hash into :checks and :other. I can define as many "other" fields as I want by passing in the :attr:

<%= f.input 'attention', :as => :check_boxes_with_other, :collection => my_predefined_values %>
<%= f.input 'attention', :as => :string_as_other %>
<%= f.input 'attention', :as => :string_as_other, :attr => 'duration' %>

Gives:

@patient.symptoms['attention']
# { :checks => ['inattentive','fidgety'], :other => "Does not stay focused.", :duration => "Symptoms began 1 year ago." }

Caveats:

  1. Haven't tested this extensively yet.
  2. You'll still need to define a top-level method to access each sub-attribute.
  3. Currently works for only one nested level.