Ruby-on-rails 我如何为 SimpleForm 编写更清晰的日期选择器输入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5007785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:25:55  来源:igfitidea点击:

How do i write a cleaner date picker input for SimpleForm

ruby-on-railsruby-on-rails-3forms

提问by nodrog

I love the simple_formgem for rails but i dont like this line of code:

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

<%= f.input :deadline, :as => :string, :input_html => { :class => 'date_picker' } %>

I would like to write:

我想写:

<%= f.input :deadline, :as => :date_picker %>

or even over write the :date/ :datetimematchers completely.

甚至完全覆盖:date/:datetime匹配器。

But i dont really want to write a whole custom_simple_form

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

I think it must be possible...

我觉得应该是可以的...

Please help thanks

请帮忙谢谢

回答by kikito

The answers here seem a bit out of date if you are using simple_form 2.0.

如果您使用的是 simple_form 2.0,这里的答案似乎有点过时。

I've been fighting with this for a while and was able to concoct this; it uses inheritance (notice that it is a subclass of StringInput, not Base), supports i18n and adds the datepickercss class in a more clean way, IMHO.

我已经与这个斗争了一段时间并且能够炮制这个;它使用继承(请注意,它是 的子类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

The usage is like above:

用法如上:

<%= f.input :deadline, :as => :date_picker %>

And the javascript remains the same:

并且 javascript 保持不变:

$("input.date_picker").datepicker();

回答by vicvega

You have to define a new DatePickerInputclass.

您必须定义一个新DatePickerInput类。

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

And you can now write

你现在可以写

<%= f.input :deadline, :as => :date_picker %>

Off course you also need

当然你也需要

 $("input.date_picker").datepicker();

in application.js

application.js

This is very useful to localize dates. Look at this:

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

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

You have now a localized date in the text field!

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

Update: a cleaner way to do the same

更新:一种更简洁的方法来做同样的事情

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

Inherit from SimpleForm::Inputs::StringInput(as @kikito said) and add some html options. If you need also a specific class you can add something like

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

def input_html_classes
  super.push('date_picker')
end

回答by Henrik N

Based on @kikito's answer, I did this to get a native datepicker (i.e. no special JS classes).

基于@kikito 的回答,我这样做是为了获得一个本地日期选择器(即没有特殊的 JS 类)。

config/initializers/simple_form_datepicker.rb

配置/初始化程序/simple_form_datepicker.rb

class SimpleForm::Inputs::DatepickerInput < SimpleForm::Inputs::StringInput 
  def input                    
    input_html_options[:type] = "date"
    super
  end
end

Then used it like:

然后像这样使用它:

f.input :paid_on, as: :datepicker

Note that if you also have a simple_form_bootstrap3.rbinitializer or similar, like we did, you should:

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

  1. add DatepickerInputto its list of inputs
  2. make sure the simple_form_bootstrap3.rb(or similar) initializer loads aftersimple_form_datepicker.rb, so that the DatepickerInputclass is available. Do that by e.g. renaming the datepicker initializer to simple_form_0_datepicker.rb.
  1. 添加DatepickerInput到其输入列表
  2. 确保simple_form_bootstrap3.rb(或类似的)初始化程序在 之后加载simple_form_datepicker.rb,以便DatepickerInput该类可用。通过例如将日期选择器初始值设定项重命名为simple_form_0_datepicker.rb.

回答by Sébastien Grosjean - ZenCocoon

An other option could also be to overwrite the default DateTimeInputhelper, here's an example to be placed in app/inputs/date_time_input.rb

另一个选项也可以是覆盖默认DateTimeInput帮助程序,这是一个放置在的示例app/inputs/date_time_input.rb

class DateTimeInput < SimpleForm::Inputs::DateTimeInput
  def input
    add_autocomplete!
    @builder.text_field(attribute_name, input_html_options.merge(datetime_options(object.send(attribute_name))))
  end

  def label_target
    attribute_name
  end

  private

    def datetime_options(value = nil)
      return {} if value.nil?

      current_locale = I18n.locale
      I18n.locale = :en

      result = []
      result.push(I18n.localize(value, { :format => "%a %d %b %Y" })) if input_type =~ /date/
      if input_type =~ /time/
        hours_format = options[:"24hours"] ? "%H:%M" : "%I:%M %p"
        result.push(I18n.localize(value, { :format => hours_format }))
      end

      I18n.locale = current_locale

      { :value => result.join(', ').html_safe }
    end

    def has_required?
      options[:required]
    end

    def add_autocomplete!
      input_html_options[:autocomplete] ||= 'off'
    end
end

Please notice than while using this method makes it a drop feature for your forms, it might also break with future versions of simple_form.

请注意,虽然使用此方法使其成为表单的删除功能,但它也可能会与 simple_form 的未来版本中断。

Notice about localized dates: As far as I know Ruby interprets dates following only a few formats, you might want to be careful before localizing them and make sure Ruby can handle them. An attempt to better localization support on the Ruby Date parsing as been started at https://github.com/ZenCocoon/I18n-date-parser, yet, this is not working.

关于本地化日期的注意事项:据我所知,Ruby 只按照几种格式解释日期,在本地化它们之前你可能要小心,并确保 Ruby 可以处理它们。尝试在https://github.com/ZenCocoon/I18n-date-parser开始对 Ruby 日期解析提供更好的本地化支持,但是,这不起作用。

回答by Lukas Svoboda

In new formtastic previews answers doesn't work. See http://justinfrench.com/notebook/formtastic-2-preview-custom-inputsHere is a simple working example (save to app/inputs/date_picker_input.rb):

在新的 formtastic 预览中,答案不起作用。请参阅http://justinfrench.com/notebook/formtastic-2-preview-custom-inputs这是一个简单的工作示例(保存到 app/inputs/date_picker_input.rb):

class DatePickerInput < Formtastic::Inputs::StringInput
  def input_html_options
    {
      :class => 'date_picker',
    }.merge(super).merge({
      :size => '11'
    })
  end
end

Create a file app/assets/javascripts/date_picker.js with content:

创建一个包含内容的文件 app/assets/javascripts/date_picker.js:

$(function() {
  $("input#.date_picker").datepicker();
});

You also need to load jquery-ui. To do so, insert to app/assets/javascripts/application.js line:

您还需要加载 jquery-ui。为此,插入 app/assets/javascripts/application.js 行:

//= require jquery-ui

or simply use CDN eg:

或者干脆使用 CDN 例如:

<%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js" %>
<%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js" %>

Stylesheets for jquery-ui coul be inclded http://babinho.net/2011/10/rails-3-1-jquery-ui/or from CDN:

jquery-ui 的样式表可以包含在 http://babinho.net/2011/10/rails-3-1-jquery-ui/或来自 CDN:

<%= stylesheet_link_tag    "application", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/themes/ui-lightness/jquery-ui.css" %>