如何为SimpleForm编写更清晰的日期选择器输入

nod*_*rog 33 forms ruby-on-rails ruby-on-rails-3

我喜欢simple_formrails 的gem,但我不喜欢这行代码:

<%= f.input :deadline, :as => :string, :input_html => { :class => 'date_picker' } %>
Run Code Online (Sandbox Code Playgroud)

我想写:

<%= f.input :deadline, :as => :date_picker %>
Run Code Online (Sandbox Code Playgroud)

甚至完全写出:date/ :datetime匹配器.

但我真的不想写一个整体 custom_simple_form

我认为一定有可能......

请帮助谢谢

kik*_*ito 42

如果你使用simple_form 2.0,这里的答案似乎有点过时了.

我已经和它斗争了一段时间,并且能够制造这个; 它使用继承(注意它是子类StringInput,而不是Base),支持i18n并datepicker以更干净的方式添加css类,恕我直言.

# app/inputs/date_picker_input.rb

class DatePickerInput < SimpleForm::Inputs::StringInput 
  def input                    
    value = input_html_options[:value]
    value ||= object.send(attribute_name) if object.respond_to? attribute_name
    input_html_options[:value] ||= I18n.localize(value) if value.present?
    input_html_classes << "datepicker"

    super # leave StringInput do the real rendering
  end
end
Run Code Online (Sandbox Code Playgroud)

用法如上:

<%= f.input :deadline, :as => :date_picker %>
Run Code Online (Sandbox Code Playgroud)

并且javascript保持不变:

$("input.date_picker").datepicker();
Run Code Online (Sandbox Code Playgroud)


vic*_*ega 37

你必须定义一个新DatePickerInput类.

module SimpleForm
  module Inputs
    class DatePickerInput < Base
      def input
        @builder.text_field(attribute_name,input_html_options)
      end    
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

你现在可以写了

<%= f.input :deadline, :as => :date_picker %>
Run Code Online (Sandbox Code Playgroud)

当然你也需要

 $("input.date_picker").datepicker();
Run Code Online (Sandbox Code Playgroud)

application.js

这对于本地化日期非常有用.看这个:

module SimpleForm
  module Inputs
    class DatePickerInput < Base
      def input
        @builder.text_field(attribute_name, input_html_options.merge(datepicker_options(object.send(attribute_name))))
      end

      def datepicker_options(value = nil)
        datepicker_options = {:value => value.nil?? nil : I18n.localize(value)}
      end

    end
  end
end
Run Code Online (Sandbox Code Playgroud)

您现在在文本字段中有一个本地化的日期!

更新:一种更干净的方式来做同样的事情

module SimpleForm
  module Inputs
    class DatePickerInput < SimpleForm::Inputs::StringInput
      def input_html_options
        value = object.send(attribute_name)
        options = {
          value: value.nil?? nil : I18n.localize(value),
          data: { behaviour: 'datepicker' }  # for example
        }
        # add all html option you need...
        super.merge options
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

继承自SimpleForm::Inputs::StringInput(如@kikito所说)并添加一些html选项.如果你还需要一个特定的类,你可以添加类似的东西

def input_html_classes
  super.push('date_picker')
end
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,完美的工作.几点加分.自定义输入代码的第5行应为`@ builder.text_field(attribute_name,:class =>'date_picker')'.此类需要进入app/inputs/date_picker_input.rb文件. (3认同)

Hen*_*k N 6

根据@ kikito的回答,我这样做是为了得到一个原生的日期选择器(即没有特殊的JS类).

配置/初始化/ simple_form_datepicker.rb

class SimpleForm::Inputs::DatepickerInput < SimpleForm::Inputs::StringInput 
  def input                    
    input_html_options[:type] = "date"
    super
  end
end
Run Code Online (Sandbox Code Playgroud)

然后使用它像:

f.input :paid_on, as: :datepicker
Run Code Online (Sandbox Code Playgroud)

请注意,如果您还有一个simple_form_bootstrap3.rb初始化程序或类似程序,就像我们一样,您应该:

  1. 添加DatepickerInput到其输入列表
  2. 确保simple_form_bootstrap3.rb(或类似的)初始化程序在之后 加载simple_form_datepicker.rb,以便DatepickerInput该类可用.通过例如将datepicker初始化程序重命名为simple_form_0_datepicker.rb.