Ввод гнезда внутри f.label (генерация формы рельсов)

Однако я хочу использовать метод f.label для создания меток элементов формы - я хочу, чтобы элемент формы был вложен внутри метки. Это возможно?

-- Из W3C --

Чтобы неявно связать метку с другим элементом управления, элемент управления должен находиться в содержимом элемента LABEL. В этом случае LABEL может содержать только один управляющий элемент. Сама метка может располагаться до или после соответствующего элемента управления.

В этом примере мы неявно связываем две метки с двумя элементами управления вводом текста:

<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>

person Michael    schedule 16.03.2010    source источник


Ответы (5)


Вы можете вложить помощник формы внутрь метки, используя блок. Вот пример с использованием HAML, но он также работает с ERB.

= form_for your_resource do |f|
  = f.label :first_name do
    = f.text_field :first_name
person Dan Garland    schedule 10.01.2012
comment
Работает для Rails 3 (3.2.9) без HAML (обычный erb). - person Gavin Miller; 28.11.2012
comment
Спасибо! Работает и в rails 4.0.4 без haml. - person Subtletree; 25.03.2014

Как ранее упоминал Дэн Гарланд, вы определенно можете вкладывать входные данные в метки с помощью простого блока. Я даю этот ответ в качестве примера использования ERB и специально для того, чтобы показать, как именно вы должны заставить группы кнопок Bootstrap работать как переключатели, так как они требуют этого вложения. Мне потребовалось некоторое время, чтобы понять, так что, надеюсь, это поможет кому-то еще.

В этом примере (Rails 4.2) группа кнопок позволяет пользователю выбирать между тремя различными вариантами расстояния:

<%= form_for(@location) do |f| %>
  <div class="field form-group">
    <%= f.label :distance %><br>
    <div class="btn-group" data-toggle="buttons">
      <%= f.label :distance, class: "btn btn-primary active" do %>
        <%= f.radio_button :distance, 0.3, checked: true %>
        0.3 miles
      <% end %>
      <%= f.label :distance, class: "btn btn-primary" do %>
        <%= f.radio_button :distance, 0.5 %>
        0.5 miles
      <% end %>
      <%= f.label :distance, class: "btn btn-primary" do %>
        <%= f.radio_button :distance, 1 %>
        1 mile
      <% end %>
    </div>
  </div>
  <div class="actions">
    <%= f.submit "Submit Location", class: "btn btn-success" %>
  </div>
<% end %>

P.S. Я пока не могу публиковать скриншоты, чтобы показать, как это выглядит, но как только я наберу достаточно очков репутации, я это сделаю.

person Sia    schedule 01.09.2015

Вы можете использовать пользовательский FormBuilder, чтобы позволить помощнику надписей принимать блок. Это так просто:

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

Затем вы можете использовать свой конструктор форм следующим образом:

<% form_for(@article, :builder => SmartLabelFormBuilder) do |form| %>
  <% form.label(:title) do %>
    Title
    <%= form.text_field(:title) %>
  <% end %>
<% end %>
person Tim Riley    schedule 04.04.2010
comment
Оборачивает хорошо, но не выводит атрибут for, что, как я понимаю, делает обычный хелпер. То есть, когда я говорю <% form.label(:title) %>, он выводит <label for="title">, но когда я добавляю блок, он просто выводит <label> независимо от того, что я делаю. Я делаю что-то неправильно? - person Ben Saufley; 25.06.2012
comment
@BenSaufley: атрибут for не требуется, когда метка оборачивает элемент ввода. w3.org/TR/html401/interact/forms. html#h-17.9.1 - person rogerkk; 04.09.2013

Используйте этот небольшой обходной путь

<%= f.label(:content, "#{f.check_box(:allow_posts)}\n#{:content}\n".html_safe, :class => "checkbox") %>

даст вам это

<label class="checkbox" for="pages_content"><input name="pages[allow_posts]" type="hidden" value="0"><input id="pages_allow_posts" name="pages[allow_posts]" type="checkbox" value="1">

содержание

person Moshe    schedule 24.08.2012
comment
Извините, я думал, что это вопрос о том, как флажки заворачиваются в теги ярлыков. - person Moshe; 24.08.2012

Это невозможно при использовании встроенных помощников Rails label или label_tag, потому что они не принимают блок. Однако, если вы хотите вложенность, то почему бы вам просто не использовать элемент HTML напрямую?

<label>
  <%= f.text_field :firstname %>
</label>
person John Topley    schedule 16.03.2010
comment
только потому, что я хочу воспользоваться автоматизацией метки рельсов - person Michael; 17.03.2010
comment
Помощник Rails присваивает значение атрибута ID входного элемента атрибуту for элемента label. Это не особенно сложно. Независимо от того, используете ли вы вспомогательную функцию Rails или вкладываете элемент ввода в метку, эффект одинаков; щелчок по метке в браузере устанавливает фокус на элемент ввода. - person John Topley; 17.03.2010
comment
Это кажется мне серьезным упущением в Rails, и я действительно удивлен, что это не было исправлено. По крайней мере, у нас есть такие люди, как Тим Райли, которые помогут нам решить проблему. - person fisherwebdev; 26.06.2011
comment
Я использую более старую версию Rails. Это сработало для меня, так как иногда помощники мешают, и просто проще кодировать HTML, который вы хотите/нужен, вместо того, чтобы пытаться заставить Rails позволить вам делать то, что вы хотите. - person Phil DD; 12.04.2017