Как написать чистый ввод выбора даты для SimpleForm
Мне нравится жемчужина simple_form
для рельсов, но мне не нравится эта строка кода:
<%= f.input :deadline, :as => :string, :input_html => { :class => 'date_picker' } %>
Я бы хотел написать:
<%= f.input :deadline, :as => :date_picker %>
или даже полностью записать матчи :date
/:datetime
.
Но я действительно не хочу писать целые custom_simple_form
Я думаю, что это возможно...
Пожалуйста, помогите спасибо
Ответы
Ответ 1
Вы должны определить новый класс 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
Ответ 2
Ответы здесь немного устарели, если вы используете 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();
Ответ 3
Основываясь на ответе @kikito, я сделал это, чтобы получить родной datepicker (т.е. специальные классы 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 или аналогичный, как и мы, вам следует:
- добавить
DatepickerInput
в список своих входов
- убедитесь, что инициализатор
simple_form_bootstrap3.rb
(или аналогичный) загружается после simple_form_datepicker.rb
, так что доступен класс DatepickerInput
. Сделайте это, например. переименование инициализатора datepicker на simple_form_0_datepicker.rb
.
Ответ 4
Другой вариант также может состоять в том, чтобы перезаписать помощник по умолчанию 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
Обратите внимание, что, хотя использование этого метода делает его функцией drop для ваших форм, оно может также нарушаться с будущими версиями simple_form.
Уведомление о локализованных датах. Насколько я знаю, Ruby интерпретирует даты, следующие только за несколькими форматами, вы можете быть осторожны, прежде чем локализовать их и убедиться, что Ruby сможет их обработать.
Попытка улучшить поддержку локализации в синтаксическом анализе Ruby Date была начата на https://github.com/ZenCocoon/I18n-date-parser, но это не работает.
Ответ 5
В новых формах предварительный просмотр ответов не работает. См. http://justinfrench.com/notebook/formtastic-2-preview-custom-inputs
Вот простой рабочий пример (save to 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 coul будут включены 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" %>