0

我正在尝试创建一个 rails FormBuilder 以使用引导样式设置表单样式:

<div class="form-group has-error">
  <label for="exampleInputEmail1">Email address</label>
  <div class="input-group>
    <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
    <span class="input-group-addon glyphicon glyphicon-user"></span>
  </div>
  <p class="help-block>can't be blank</p>
</div>

当我只有一个 div 标签时,我能够让表单构建器工作(不包括传统引导表单的输入组。我的问题是我无法获得带有类“输入组”的 div 的嵌套 content_tag " 正常工作。我尝试添加元素并将 content_tag 包装在捕获中,但无济于事。

class LargeFormBuilder < ActionView::Helpers::FormBuilder
  include ActionView::Helpers::TagHelper
  include ActionView::Helpers::CaptureHelper
  include ActionView::Helpers::TextHelper

  attr_accessor :output_buffer

  %w(text_field text_area email_field password_field).each do |form_method|
    define_method(form_method) do |*args|
      attribute = args[0]
      options = args[1] || {}
      options[:label] ||= attribute
      options[:class] ||= "form-control input-lg"
      label_text ||= options.delete(:label).to_s.titleize
      content_tag(:div, class: "form-group #{'has-error' if !object.errors[attribute].empty?}") do
        concat label(attribute, label_text, class: "control-label")
        concat (
            content_tag(:div, class: "input-group") do
              concat super(attribute, options)
              concat content_tag(:span, "", class: "input-group-addon glyphicon glyphicon-user")
            end
         )
        concat errors_for_field(attribute)
      end
    end
  end

  def errors_for_field(attribute, options={})
    return "" if object.errors[attribute].empty?
    content_tag(:p, object.errors[attribute].to_sentence.capitalize, class: "help-block")
  end

end
4

2 回答 2

3

更简单的是,实际上您不需要使用concat,您可以使用+以更清晰的方式实现相同的结果,只需确保第一个字符串是html_safe

content_tag(:div, class: "form-group #{'has-error' if !object.errors[attribute].empty?}") do
  label(attribute, label_text, class: "control-label").html_safe + \
  content_tag(:div, class: "input-group") do
    concat super(attribute, options)
    concat content_tag(:span, "", class: "input-group-addon glyphicon glyphicon-user")
  end + \
  errors_for_field(attribute)
end

并提高可读性

content_tag(:div, class: "form-group #{'has-error' if !object.errors[attribute].empty?}") do
  label_html = label(attribute, label_text, class: "control-label")

  input_html = content_tag(:div, class: "input-group") do
    concat super(attribute, options)
    concat content_tag(:span, "", class: "input-group-addon glyphicon glyphicon-user")
  end

  error_html = errors_for_field(attribute)

  label_html.html_safe + input_html + error_html
end
于 2014-07-23T00:54:31.793 回答
0

我认为这是具有引导 4 样式的 3 层深度嵌套 content_tag 的一个很好的例子。这是一个表单辅助方法,它采取行动前。:new 或 :edit,并使用 bootstrap 4 的分页按钮样式输出可用的语言环境。

在此处输入图像描述

def form_lang_switcher(action)
  content_tag(:nav, :"aria-label" => 'language switch') do
    content_tag(:ul, class: 'pagination pagination-sm justify-content-end') do
      I18n.available_locales.each do |loc|
        concat content_tag(:li, (link_to loc.upcase,
                           url_for(action: :"#{action}", locale: loc), 
                           class: "page-link"), 
        class: "page-item #{(I18n.locale == loc ? "active" : "")}").html_safe
      end
    end
  end
end
于 2018-05-15T00:19:10.967 回答