为 simple_form 设置应用程序范围内的 input_html 值

Set input_html values application-wide for simple_form

我已经将 simple_form 从 2.1.0 升级到 3.0.3(是的,仍然很旧)并且 Rails 从 3.2.22 升级到 4.2.10,它看起来像结果,我丢失了与 text 列关联的 textarea 元素的设置,默认值 cols 为 40,而 rows 为 20。现在看来不是为 colsrows.

设置任何值

是否可以配置 simple_form 为 text 应用程序范围的 textarea 设置列和行?或者我必须设置类似

<%= f.input :message, input_html: {cols: 40, rows: 20} %>

对于应用程序中的每个输入?

我尝试搜索 simple_form github 存储库,但在他们的 wiki 中只提到了三个 input_html,其中 none 解决了这个问题。

问题:

在Rails 4.2中,设置textarea的全局默认值colsrows:

TL;DR:

因为 SimpleForm 3.0Rails 4.2[= 似乎都没有 public-API 94=] 能够设置默认文本区域 colsrows 值(请参阅下面我的 Debugging 为什么),然后我想出了以下内容解决方法:

解决方法 1(测试有效):

创建以下文件:

# config/initializers/text_area_extensions.rb

module TextAreaExtensions
  def render
    @options[:cols] ||= 40
    @options[:rows] ||= 20
    super
  end
end

ActionView::Helpers::Tags::TextArea.class_eval do
  prepend TextAreaExtensions
end

... 将呈现任何文本区域——简单表单生成器或 rails 表单生成器或 text_area_tag——具有如下所示的默认列和行:

<textarea class="text" cols="40" rows="20"></textarea>

注意 这是一种变通方法,不是长期稳健的解决方案,因为这只能保证适用于此特定版本的 ActionView::Helpers::Tags::TextArea class。以后 Rails 主要甚至次要版本可能无法工作!

解决方法 2:

而不是上面的 "patching" ActionView::Helpers::Tags::TextArea,如果您只想为 SimpleForm 表单设置默认的列和行但不为 [=126 设置默认值,您也可以修补 SimpleForm::Inputs::TextInput =] 形式,但因为我更喜欢上面的解决方法 1,而且我的回答已经太长了,所以我跳过了。但如果有人有兴趣知道,请告诉我,我会更新。

解决方法 3:

可能更好的方法是使用您可以调用的自定义方法(即视图辅助方法),它已经具有默认的列和行,而不是 "patching" gem 代码像上面的解决方法 1。但是,我的印象是您已经有了一个大型应用程序,您只想简单地设置一个全局代码,而不是手动 setting/updating 所有受影响的视图文件(您甚至在上面说过),因此我的上面的解决方法 1。

调试中:

我跟踪了执行代码:

  • SimpleForm "text" input:

    module SimpleForm
      module Inputs
        class TextInput < Base
          enable :placeholder, :maxlength
    
          def input
            @builder.text_area(attribute_name, input_html_options)
          end
        end
      end
    end
    
  • ... 不建议在 SimpleForm 中使用 public API 来设置全局默认列和行,因此遵循 input_html_options:

    # ...
    @input_html_options = html_options_for(:input, input_html_classes).tap do |o|
      o[:readonly]  = true if has_readonly?
      o[:disabled]  = true if has_disabled?
      o[:autofocus] = true if has_autofocus?
    end
    # ...
    
  • ...也不建议在 SimpleForm 中使用 public API 来设置全局列和行。所以跟随 Rails' @builder.text_area (见上面的代码),这导致我 here:

    def text_area(object_name, method, options = {})
      Tags::TextArea.new(object_name, method, self, options).render
    end
    
  • 其中让我 来到这里:因为 TextArea.new

    def initialize(object_name, method_name, template_object, options = {})
      @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
      @template_object = template_object
    
      @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
      @object = retrieve_object(options.delete(:object))
      @options = options
      @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match
    end
    
  • ... 也没有 public API 来设置全局列和行,因此遵循 next here: for TextArea.new.render

    def render
      options = @options.stringify_keys
      add_default_name_and_id(options)
    
      if size = options.delete("size")
        options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
      end
    
      content_tag("textarea", options.delete("value") { value_before_type_cast(object) }, options)
    end
    
  • ... 也没有 public API 来设置全局列和行,这让我别无选择,只能 "patch" 代码使用上面的解决方法 1。

琐事:

  • 当你说 Rails 4 不再为 textarea 设置默认 colsrows 值时,我证实你是对的,因为看起来 [=31] =] 仅在 Rails 版本 3.2.13 之前实现,如您所见 here

Simple Form 通过重新定义现有的 Simple Form 输入,提供了一种实现 change the default behaviour (v3.0.3) 的简单方法。这是通过创建一个具有相同名称的新 class 来完成的。例如,如果你想设置默认的 rowscols,你可以这样做:

# app/inputs/text_input.rb
class TextInput < SimpleForm::Inputs::TextInput
  def input
    input_html_options[:cols] ||= 40
    input_html_options[:rows] ||= 20
    super
  end
end