ruby on rails - rails - ¿Cómo escribo una entrada de selector de fecha más limpia para SimpleForm
rails forms select (5)
Me encanta la gema simple_form
para rieles pero no me gusta esta línea de código:
<%= f.input :deadline, :as => :string, :input_html => { :class => ''date_picker'' } %>
Me gustaría escribir:
<%= f.input :deadline, :as => :date_picker %>
o incluso sobre escribir las :date
/ :datetime
matchers por completo.
Pero realmente no quiero escribir una custom_simple_form
completa
Creo que debe ser posible ...
Por favor ayuda gracias
Basado en la respuesta de @kikito, hice esto para obtener un datepicker nativo (es decir, sin clases especiales de JS).
config / initializers / simple_form_datepicker.rb
class SimpleForm::Inputs::DatepickerInput < SimpleForm::Inputs::StringInput
def input
input_html_options[:type] = "date"
super
end
end
Luego lo usé como:
f.input :paid_on, as: :datepicker
Tenga en cuenta que si también tiene un inicializador simple_form_bootstrap3.rb o similar, como nosotros, debería:
- agregar
DatepickerInput
a su lista de entradas - asegúrese de que el
simple_form_bootstrap3.rb
(o similar) se carga después desimple_form_datepicker.rb
, de modo que la claseDatepickerInput
esté disponible. Hazlo, por ejemplo, cambiando el nombre del inicializador datepicker asimple_form_0_datepicker.rb
.
En las nuevas respuestas formtastic previas, las respuestas no funcionan. Ver http://justinfrench.com/notebook/formtastic-2-preview-custom-inputs Aquí hay un ejemplo de trabajo simple (guardar en 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
Crea una aplicación de archivo / assets / javascripts / date_picker.js con contenido:
$(function() {
$("input#.date_picker").datepicker();
});
También necesitas cargar jquery-ui. Para hacerlo, inserte en la línea app / assets / javascripts / application.js:
//= require jquery-ui
o simplemente use CDN, por ejemplo:
<%= 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" %>
Las hojas de estilo para jquery-ui pueden incluirse en http://babinho.net/2011/10/rails-3-1-jquery-ui/ o en CDN:
<%= stylesheet_link_tag "application", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/themes/ui-lightness/jquery-ui.css" %>
Las respuestas aquí parecen un poco desactualizadas si está utilizando simple_form 2.0.
He estado luchando con esto por un tiempo y pude inventar esto; usa herencia (observe que es una subclase de StringInput
, no Base
), admite i18n y agrega la clase datepicker
css de una manera más limpia, en mi humilde opinión.
# 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
El uso es como arriba:
<%= f.input :deadline, :as => :date_picker %>
Y el javascript sigue siendo el mismo:
$("input.date_picker").datepicker();
Otra opción también podría ser sobrescribir el ayudante DateTimeInput
predeterminado, aquí hay un ejemplo para colocar en 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
Tenga en cuenta que al utilizar este método lo convierte en una función de inserción para sus formularios, también puede romperse con las versiones futuras de simple_form.
Aviso sobre fechas localizadas : por lo que sé, Ruby interpreta las fechas siguiendo solo algunos formatos, es posible que desee tener cuidado antes de localizarlos y asegurarse de que Ruby pueda manejarlos. Un intento de mejorar el soporte de localización en el análisis Ruby Date como se inició en https://github.com/ZenCocoon/I18n-date-parser , sin embargo, esto no está funcionando.
DatePickerInput
definir una nueva clase DatePickerInput
.
module SimpleForm
module Inputs
class DatePickerInput < Base
def input
@builder.text_field(attribute_name,input_html_options)
end
end
end
end
Y ahora puedes escribir
<%= f.input :deadline, :as => :date_picker %>
Por supuesto, también necesitas
$("input.date_picker").datepicker();
en application.js
Esto es muy útil para localizar fechas. Mira este:
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
¡Ahora tiene una fecha localizada en el campo de texto!
Actualización: una manera más limpia de hacer lo mismo
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
Heredar de SimpleForm::Inputs::StringInput
(como dijo @kikito) y agregar algunas opciones html. Si también necesita una clase específica, puede agregar algo como
def input_html_classes
super.push(''date_picker'')
end