I’m currently working on a Ruby on Rails application where I need lots of text fields that have the same properties. I decided to override text_field and have it output all of the extra attribues automatically. This helps keep the view code cleaner, lets me change all of these text fields in one place, and also helps me avoid typing mistakes (at least in this section of the code). Thanks to Ruby on Rails core team member Rick Olson (aka technoweenie) for pointing me to his LabeledFormHelper plugin, which taught me this technique.
Before the custom FormBuilder my initial view code looked something like:
<% form_for(:spreadsheet, @spreadsheet, :url => { :action => 'create' }) do |s| %>
<% fields_for :numbers, @spreadsheet.numbers do |f| %>
<%= f.text_field :field1, :onkeypress => 'return isNumberKey(event);', :maxlength => 3 %>
<%= f.text_field :field2, :onkeypress => 'return isNumberKey(event);', :maxlength => 3 %>
... and so on
<% end %>
<% end %>
So I created a custom FormBuilder in my helper to do the extra text_field work for me:
module SpeadsheetsHelper
# tell all of these methods to use my custom FormBuilder
[:form_for, :fields_for, :form_remote_for, :remote_form_for].each do |meth|
src = <<-end_src
def speadsheets_#{meth}(object_name, *args, &proc)
options = args.last.is_a?(Hash) ? args.pop : {}
options.update(:builder => SpeadsheetsFormBuilder)
#{meth}(object_name, *(args << options), &proc)
end
end_src
module_eval src, __FILE__, __LINE__
end
# the custom FormBuilder
class SpeadsheetsFormBuilder < ActionView::Helpers::FormBuilder
# add onkeypress and set maxlength of field to 3 to all text fields
def text_field(method, options={})
super(method, options.merge(:onkeypress => 'return isNumberKey(event);', :maxlength => 3))
end
end
end
Now my view code is much simpler and helps avoid goofups:
<% spreadsheets_form_for(:spreadsheet, @spreadsheet, :url => { :action => 'create' }) do |s| %>
<% spreadsheets_fields_for :numbers, @spreadsheet.numbers do |f| %>
<%= f.text_field :field1 %>
<%= f.text_field :field2 %>
... and so on
<% end %>
<% end %>
Notice in the view that instead of using form_for and fields_for you need to use the custom methods spreadsheets_form_for and spreadsheets_fields_for which were created in SpeadsheetsHelper.