it-swarm-ru.tech

Как мне написать более чистый ввод выбора даты для SimpleForm

Мне нравится самоцвет simple_form для Rails, но мне не нравится эта строка кода:

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

Я хотел бы написать:

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

или даже перепишите полностью :date/:datetime.

Но я действительно не хочу писать целый custom_simple_form

Я думаю, что это должно быть возможно ...

Пожалуйста, помогите спасибо

33
nodrog

Вы должны определить новый класс DatePickerInput.

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

И теперь вы можете написать

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

Конечно, вам также нужно 

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

в 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

Теперь у вас есть локализованная дата в текстовом поле!

Обновление: более чистый способ сделать то же самое

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

Унаследуйте от SimpleForm::Inputs::StringInput (как сказал @kikito) и добавьте несколько опций html . Если вам нужен также определенный класс, вы можете добавить что-то вроде

def input_html_classes
  super.Push('date_picker')
end
37
vicvega

Ответы здесь кажутся немного устаревшими, если вы используете simple_form 2.0.

Я боролся с этим некоторое время и смог придумать это; он использует наследование (обратите внимание, что это подкласс StringInput, а не Base), поддерживает i18n и добавляет класс datepicker css более чистым способом, IMHO.

# 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

Использование как выше:

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

И JavaScript остается прежним:

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

Основываясь на ответе @ kikito, я сделал это, чтобы получить нативный сборщик дат (то есть никаких специальных классов JS).

config/initializers/simple_form_datepicker.rb

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

Тогда использовал это как:

f.input :paid_on, as: :datepicker

Обратите внимание, что если у вас также есть simple_form_bootstrap3.rb initializer или аналогичный, как у нас, вы должны:

  1. добавить DatepickerInput в свой список входов
  2. убедитесь, что инициализатор simple_form_bootstrap3.rb (или аналогичный) загружает послеsimple_form_datepicker.rb, чтобы класс DatepickerInput был доступен. Сделайте это, например, переименование инициализатора DatePicker в simple_form_0_datepicker.rb.
6
Henrik N

Другим вариантом может быть также перезаписать помощник по умолчанию 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

Обратите внимание, что использование этого метода делает его опущенным для ваших форм, оно также может нарушить будущие версии simple_form.

Уведомление о локализованных датах: насколько я знаю, Ruby интерпретирует даты по нескольким форматам, вы можете быть осторожны перед их локализацией и убедиться, что Ruby может их обработать . поддержка локализации при разборе даты Ruby, как было начато с https://github.com/ZenCocoon/I18n-date-parser , но это не работает.

0