【问题标题】:Focus first invalid field in form using Rails 5 and simple_form gem使用 Rails 5 和 simple_form gem 在表单中关注第一个无效字段
【发布时间】:2017-06-23 14:06:23
【问题描述】:

我使用 Rails 5 和 simple_form gem,在安装时预配置了 Bootstrap(如果有的话)。

问题是:在表单渲染第一个有错误的字段应该被关注。如果没有错误,让我们关注第一行。

这个 gem 可以在字段上使用autofocus: true,但是在表单视图中的每个字段上都放置这个属性会破坏“simple_form”的简单性。我找到的唯一解决方案是覆盖对自动对焦字段属性的检查,并在字段有错误且未设置自动对焦属性时强制设置它:

module SimpleForm
  module Helpers
    module Autofocus
      private

      def has_autofocus?
        options[:autofocus] == true || has_errors?
      end
    end
  end
end

对于表单没有错误的情况,我使用在第一个字段上显式设置自动对焦:

= simple_form_for object do |f|
  = f.input :to, autofocus: true
  = f.input :cc
  = f.input :subject
  = f.input :body, input_html: {rows: 10}

所以,问题是:有没有更好的方法来动态设置 autofocus 属性,而不覆盖这个 getter? (请不要使用 JS,让我们使用纯 HTML 属性)我找不到使用表单构建器(如 simple_form 在config/initializers 生成的构建器)实现此场景的方法,但也许有一个构建器组合复杂的解决方案?或者也许可以有一个更简单、危险性更低的覆盖?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-5 simple-form


    【解决方案1】:

    由于这个问题没有合适的解决方案,我想出了一个小而老套的解决方案。

    首先,您需要在您的 simple_form 初始化程序 config/initializers/simple_form.rb 中启用包含自定义组件:

    # Uncomment this and change the path if necessary to include your own
    # components.
    # See https://github.com/heartcombo/simple_form#custom-components to know
    # more about custom components.
    Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
    

    仍然在初始化器中添加autofocus_on_error 组件:

    # Use this setup block to configure all options available in SimpleForm.
    SimpleForm.setup do |config|
      ...
      config.wrappers :default, class: :input,
        ...
        # If a form has invalid fields, automatically set the focus on the first
        # field with an error
        b.use :autofocus_on_error
      end
    end
    

    现在在lib/components/autofocus_on_error_component.rb中创建实际组件:

    module AutofocusOnErrorComponent
      def autofocus_on_error(wrapper_options = nil)
        if has_errors? && !inputs_with_autofocus_present?
          input_html_options[:autofocus] = true
        end
    
        nil
      end
    
      private
    
      def inputs_with_autofocus_present?
        @builder.template.output_buffer.include?('autofocus="autofocus"')
      end
    end
    
    SimpleForm.include_component(AutofocusOnErrorComponent)
    

    最后重新启动您的网络服务器以反映更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多