Как мне написать более чистый ввод выбора даты для SimpleForm - PullRequest
33 голосов
/ 15 февраля 2011

Я люблю камень simple_form для рельсов, но мне не нравится эта строка кода:

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

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

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

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

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

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

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

Ответы [ 5 ]

42 голосов
/ 08 мая 2012

Ответы здесь кажутся немного устаревшими, если вы используете 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

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

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

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

$("input.date_picker").datepicker();
37 голосов
/ 22 февраля 2011

Вы должны определить новый 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();

in 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
6 голосов
/ 16 октября 2013

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

конфиг / Инициализаторы / 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 или аналогичный, как у нас, вы должны:

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

В новых формах предварительного просмотра ответы не работают.См. http://justinfrench.com/notebook/formtastic-2-preview-custom-inputs Вот простой рабочий пример (сохранить в app / input / date_picker_input.rb):

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

Создать файл app / assets / javascripts / date_picker.js с содержимым:

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

Вам также нужно загрузить jquery-ui.Для этого вставьте в строку app / assets / javascripts / application.js строку:

//= require jquery-ui

или просто используйте 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" %>

Таблицы стилей для 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" %>
0 голосов
/ 07 ноября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...