simple_form rails form for ruby-on-rails ruby-on-rails-3 forms

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:

  1. agregar DatepickerInput a su lista de entradas
  2. asegúrese de que el simple_form_bootstrap3.rb (o similar) se carga después de simple_form_datepicker.rb , de modo que la clase DatepickerInput esté disponible. Hazlo, por ejemplo, cambiando el nombre del inicializador datepicker a simple_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