views:

457

answers:

2

I want to use the f.label method to create my form element labels, however - i want to have the form element nested inside the label. Is this possible?

-- From W3C --

To associate a label with another control implicitly, the control element must be within the contents of the LABEL element. In this case, the LABEL may only contain one control element. The label itself may be positioned before or after the associated control.

In this example, we implicitly associate two labels with two text input controls:

<FORM action="..." method="post">
<P>
<LABEL>
   First Name
   <INPUT type="text" name="firstname">
</LABEL>
<LABEL>
   <INPUT type="text" name="lastname">
   Last Name
</LABEL>
</P>
</FORM>
A: 
John Topley
only because i want to take advantage of the automation of rails' label
Mike
The Rails' helper assigns the value of the input element's ID attribute to the label element's `for` attribute. It's not particularly sophisticated. Whether you use the Rails' helper or nest the input element within the label, the effect is the same; clicking the label in the browser sets the focus to the input element.
John Topley
A: 

You can use a custom FormBuilder to allow the label helper to accept a block. It's as simple as this:

class SmartLabelFormBuilder < ActionView::Helpers::FormBuilder
  def label(method, content_or_options_with_block = nil, options = {}, &block)
    if !block_given?
      super(method, content_or_options_with_block, options)
    else
      options = content_or_options_with_block.is_a?(Hash) ? content_or_options_with_block.stringify_keys : {}

      @template.content_tag(:label, options, &block)
    end
  end
end

Then you can use your form builder like this:

<% form_for(@article, :builder => SmartLabelFormBuilder) do |form| %>
  <% form.label(:title) do %>
    Title
    <%= form.text_field(:title) %>
  <% end %>
<% end %>

Done. I've actually written a blog post about label helpers with blocks that includes a little more detail, like customising how your form should display when your fields have errors (I don't like wrapping everything in fieldWithErrors divs). Check it out.

Tim Riley
Awesome, thanks!
Mike