2011-02-15 11 views
33

Me encanta la joya simple_form para los carriles, pero no me gusta esta línea de código:¿Cómo se escribe una entrada de un selector de fechas más limpio para SimpleForm

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

me gustaría escribir:

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

o incluso más escriba :date/:datetime matchers completamente.

Pero yo realmente no quiero escribir un todo custom_simple_form

Creo que debe ser posible ...

favor ayudarme gracias

Respuesta

37

tiene que 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 se puede escribir

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

¡Por supuesto también necesita

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

en application.js

Esto es muy útil para localizar fechas. Mira esto:

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 

¡Ya tienes una fecha localizada en el campo de texto!

Actualización: una forma 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 del SimpleForm::Inputs::StringInput (como se dijo @kikito) y añadir algunas opciones html. Si necesita también una clase específica se puede añadir algo así como

def input_html_classes 
    super.push('date_picker') 
end 
+3

Gran respuesta, funcionó a la perfección. Un par de puntos extra. La 5ª línea del código de entrada personalizada debe ser '@ builder.text_field (attribute_name,: class => 'date_picker') '. Y esta clase necesita ir a la aplicación de archivo/inputs/date_picker_input.rb. – phatmann

+0

Consulte mi respuesta a continuación si está utilizando simple_form 2.x – kikito

+0

Gracias. Una pequeña falta de ortografía, hay dos 'clases' en su código actualizado – Frankel

0

Otra opción también podría ser sobrescribir el ayudante por defecto DateTimeInput, esto es un ejemplo para ser colocado 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 mientras usa este método lo convierte en una función de soltar para sus formularios, también podría romperse con versiones futuras de simple_form.

Aviso sobre las fechas localizadas: Por lo que yo sé Rubí interpreta las fechas siguientes sólo unos pocos formatos, puede que desee tener cuidado antes de localización de ellos y asegurarse de que Ruby puede 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.

-1

En las nuevas respuestas de formtastic previews no funciona. 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 

crear una aplicación de archivos/activos/javascript/date_picker.js con contenido:

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

También es necesario cargar jquery-ui. Para ello, insertar a app/activos/javascripts/application.js línea:

//= require jquery-ui 

o simplemente utilizar 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" %> 

hojas de estilo para jquery-ui coul ser inclded http://babinho.net/2011/10/rails-3-1-jquery-ui/ o de CDN :

<%= stylesheet_link_tag "application", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/themes/ui-lightness/jquery-ui.css" %> 
+0

gracias @LukasSvoboda pero la pregunta era para la forma simple no formtastic – nodrog

41

Las respuestas aquí parecen un poco obsoletas 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 css datepicker 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 la de arriba:

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

Y el javascript sigue siendo el mismo:

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

gracias por la sugerencia. Actualicé mi respuesta – vicvega

+0

No funcionó para mí. Mi fecha se formatea así "mer 06 nov 2013, 00:00:00 +0000". No sé por qué. – AgostinoX

+0

@AgostinoX su configuración regional debe ser francesa. El método 'I18n.localize' utiliza la clave' time.formats.default' para formatear las fechas. Ver https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/fr.yml#L66 – kikito

6

Sobre la base de la respuesta de @ kikito, que lo hacían para tener un selector de fechas nativo (es decir, sin clases especiales de JS).

config/inicializadores/simple_form_datepicker.rb

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

Luego lo utilizaron gustaría:

f.input :paid_on, as: :datepicker 

Tenga en cuenta que si usted también tiene un simple_form_bootstrap3.rb inicializador o similares, al igual que sí, debe:

  1. añadir DatepickerInput a su lista de entradas
  2. Asegúrese de que el simple_form_bootstrap3.rb (o similares) cargas de inicializador despuéssimple_form_datepicker.rb, por lo que la clase DatepickerInput está disponible. Haz eso por ej. cambiar el nombre del inicializador datepicker al simple_form_0_datepicker.rb.
+0

esto funciona muy bien y no requiere gemas o complementos externos, ya que utiliza la capacidad moderna de visualización de navegadores construido en datapickers. ¡Recomendado! –

Cuestiones relacionadas