Fra*_*ehl 7 ruby forms ruby-on-rails ruby-on-rails-4 twitter-bootstrap-3
我正在使用带有Rails 4的Bootstrap 3,我想创建一个自定义的FormBuilder来处理Bootstrap的一些独特的HTML语法.具体来说,我需要一个自定义帮助器,它将form-group在表单字段周围创建div包装器,因为Bootstrap将错误状态应用于此包装器,而不是字段本身 ......
<div class="form-group has-error">
<label class="col-md-3 control-label" for="user_email">Email</label>
<div class='col-md-9'>
<input class="form-control required-input" id="user_email" name="user[email]" placeholder="peter@example.com" type="email" value="someone@example.com" />
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
注意has-error外部div中的额外类...
无论如何,我写了那个助手,它很棒!
def form_group(method, options={})
class_def = 'form-group'
class_def << ' has-error' unless @object.errors[method].blank?
class_def << " #{options[:class]}" if options[:class].present?
options[:class] = class_def
@template.content_tag(:div, options) { yield }
end
# Here's a HAML sample...
= f.form_group :email do
= f.label :email, nil, class: 'col-md-3 control-label'
.col-md-9
= f.email_field :email, class: 'form-control required-input', placeholder: t('sample.email')
Run Code Online (Sandbox Code Playgroud)
现在我想利用Bootstrap的表单帮助文本来显示错误消息.这需要我扩展Rails本机助手(text_field例如上面的例子中),然后在块中调用它们f.form_group.
解决方案似乎很简单:调用父级,并将我的span块追加到最后...
def text_field(method, options={})
@template.text_field(method, options)
if !@object.errors[method].blank?
@template.content_tag(:span, @object.errors.full_messages_for(method), class: 'help-block')
end
end
Run Code Online (Sandbox Code Playgroud)
只有它不会输出任何HTML,div只会显示为空.我尝试了一堆diff语法方法:
supervs text_fieldvstext_field_tagconcat- 结果 - @template.concat(@template.content_tag( [...] ))def text_field(method, *args)然后options = args.extract_options!.symbolize_keys!我只会得到奇怪的语法错误,或者是空的div.在某些情况下,该input字段会出现,但帮助文本span不会,或反之亦然.
我确定我搞砸了一些简单的东西,我只是没有看到它.
花了几天时间,但我最终偶然发现了正确的语法.希望它能拯救别人的理智!
Ruby的return自动化,与Rails有时复杂的范围相结合,让我感到沮丧.具体来说,@template.text_field绘制内容,但必须由辅助方法返回,以便出现在调用块中.但是我们必须返回两个调用的结果......
def text_field(method, options={})
field_errors = object.errors[method].join(', ') if !@object.errors[method].blank?
content = super
content << (@template.content_tag(:span, @object.errors.full_messages_for(method), class: 'help-block') if field_errors)
return content
end
Run Code Online (Sandbox Code Playgroud)
我们必须返回父方法(via super)和我们的自定义@template.content_tag(:span,注入的结果.我们可以使用Ruby的plus +运算符来缩短它,这会将返回结果连接起来.
def text_field(method, options={})
field_errors = object.errors[method].join(', ') if !@object.errors[method].blank?
super + (@template.content_tag(:span, @object.errors.full_messages_for(method), class: 'help-block') if field_errors)
end
Run Code Online (Sandbox Code Playgroud)
注意:表单是使用ActiveModel对象启动的,这就是我们有权访问的原因@object.在form_for不将其与模型相关联的情况下实现将需要您进行扩展text_field_tag.
这是我完成的自定义FormBuilder
class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
def form_group(method, options={})
class_def = 'form-group'
class_def << ' has-error' unless @object.errors[method].blank?
class_def << " #{options[:class]}" if options[:class].present?
options[:class] = class_def
@template.content_tag(:div, options) { yield }
end
def text_field(method, options={})
field_errors = object.errors[method].join(', ') if !@object.errors[method].blank?
super + (@template.content_tag(:span, @object.errors.full_messages_for(method), class: 'help-block') if field_errors)
end
end
Run Code Online (Sandbox Code Playgroud)
别忘了告诉form_for!
form_for(:user, :builder => BootstrapFormBuilder [, ...])
Run Code Online (Sandbox Code Playgroud)
编辑:这里有许多有用的链接,帮助我走上了启蒙的道路.Link-juice对作者赞不绝口!
| 归档时间: |
|
| 查看次数: |
3293 次 |
| 最近记录: |