I'm trying to create my first custom FormBuilder and I'm having a bit of a problem. I'm trying to add a 'field_group' method to my builder that takes a block, but when I yield to the block I seem to be getting duplicate form field entries being produced. Maybe my code will make this clearer:
class LabelledBuilder < ActionView::Helpers::FormBuilder def self.define_labelled_field_method(method_name) src = <<-end_src def #{method_name}(label, method, options = {}) hint_text = options[:hint] @template.content_tag("tr") do @template.content_tag("td", @template.content_tag("label", label.to_s.humanize.titleize, :for => method)) + @template.content_tag("td", super(method, options) + (hint_text.nil? ? '' : @template.content_tag("div", hint_text, :class => "field_hint"))) end end end_src class_eval src, __FILE__, __LINE__ end
def check_box(label, method, options = {}) super(method, options) + @template.content_tag("label", label, :for => method) end
def field_group(label, &proc) raise ArgumentError, "Missing block" unless block_given? @template.concat(yield, proc.binding) # <--- !!!! PROBLEM SEEMS TO BE CAUSED BY THIS YIELD !!! end
(field_helpers - %w(check_box)).each do |name| define_labelled_field_method(name) end end
If I put this in my view
<% form_for :user, :url => {:controller => :user, :action => :new }, :builder => LabelledBuilder do |f| %> <table> <%= f.text_field "user name:", :user_name, :hint => "Enter user name" %> <% f.field_group "includes:" do %> <%= f.check_box "box", :terms_of_service %> <% end %> </table> <% end %>
the text field and the checkbox are emitted correctly, but then I also get an inner <form> element embedded in the outer <form> element, and the two <input> fields are repeated. Something like this:
<form action="/user/new" method="post"> <table> <tr><td><label for="user_name">User Name:</label></td><td><input hint="Enter user name" id="user_user_name" name="user[user_name]" size="30" type="text" /><div class="field_hint">Enter user name</div></
</tr>
<input id="user_terms_of_service" name="user[terms_of_service]" type="checkbox" value="1" /><input name="user[terms_of_service]" type="hidden" value="0" /><label for="terms_of_service">box</label>
<form action="/user/new" method="post"> <table>
<tr><td><label for="user_name">User Name:</label></td><td><input hint="Enter user name" id="user_user_name" name="user[user_name]" size="30" type="text" /><div class="field_hint">Enter user name</div></
</tr>
<input id="user_terms_of_service" name="user[terms_of_service]" type="checkbox" value="1" /><input name="user[terms_of_service]" type="hidden" value="0" /><label for="terms_of_service">box</label>
</table> </form>
I believe it has something to do with the call to 'yield' in my field_group method, but I'm not sure why this is happening. Can anybody explain this to me?
TIA, -- bb