33 votes

Comment écrire une entrée de sélecteur de date plus propre pour SimpleForm

J'adore le bijou simple_form pour les rails mais je n'aime pas cette ligne de code:

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

Je voudrais écrire:

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

ou même écraser complètement les égaliseurs: date /: datetime.

Mais je ne veux pas vraiment écrire tout un custom_simple_form

Je pense que ça doit être possible ...

S'il vous plaît aider merci

42voto

kikito Points 23229

Les réponses ici sembler un peu en dehors de la date si vous utilisez simple_form 2.0.

Je me bats depuis un certain temps et a été en mesure de concocter de cela, il utilise l'héritage (remarquez que c'est une sous-classe de StringInput, pas Base), prend en charge l'i18n et ajoute l' datepicker classe css dans un plus propre, à mon humble avis.

# 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

L'utilisation est comme ci-dessus:

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

Et le javascript reste la même:

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

38voto

vicvega Points 2009

Vous devez définir un nouveau DatePickerInput classe.

module SimpleForm
  module Inputs
    class DatePickerInput < Base
      def input
        @builder.text_field(attribute_name,input_html_options)
      end    
    end
  end
end

Et vous pouvez maintenant écrire

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

Bien sûr vous devez également

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

en application.js

Ceci est très utile pour localiser les dates. Regardez ceci:

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

Vous avez maintenant une date localisés dans le champ de texte!

Mise à jour: une le moyen le plus propre à faire de même

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

Hériter d' SimpleForm::Inputs::StringInput (comme @kikito dit), et d'ajouter certaines options html. Si vous avez besoin également d'une classe spécifique, vous pouvez ajouter quelque chose comme

def input_html_classes
  super.push('date_picker')
end

8voto

Henrik N Points 4447

Basé sur @kikito réponse, j'ai fait cela pour obtenir un natif datepicker (c'est à dire rien de spécial à JS classes).

config/initializers/simple_form_datepicker.rb

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

Ensuite utilisés comme:

f.input :paid_on, as: :datepicker

Notez que si vous avez aussi un simple_form_bootstrap3.rb initialiseur ou similaire, comme nous l'avons fait, vous devriez:

  1. ajouter DatepickerInput à la liste des entrées
  2. assurez-vous que l' simple_form_bootstrap3.rb (ou similaire) initialiseur de charges après l' simple_form_datepicker.rb, de sorte que l' DatepickerInput classe est disponible. Le faire, par exemple en renommant le datepicker de l'initialiseur d' simple_form_0_datepicker.rb.

0voto

Une autre option pourrait également être de remplacer la valeur par défaut DateTimeInput helper, voici un exemple pour être placé dans 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

Veuillez noter que tout en utilisant cette méthode, il est un déposer vos formes, il peut également rompre avec les futures versions de simple_form.

Avis sur localisé dates: autant Que je sache, Ruby interprète des dates suivantes à seulement quelques formats, vous voudrez peut-être prudent avant de localisation et assurez-vous que Ruby est capable de les traiter. Pour tenter de mieux le support de localisation sur le Ruby Date de l'analyse a été commencé à https://github.com/ZenCocoon/I18n-date-parseret, pourtant, ce n'est pas de travail.

-1voto

Lukas Svoboda Points 306

Dans les nouvelles formtastic aperçus réponses ne fonctionne pas. Voir http://justinfrench.com/notebook/formtastic-2-preview-custom-inputs Voici un simple exemple de travail (enregistrer app/entrées/date_picker_input.rb):

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

Créer un fichier app/assets/javascripts/date_picker.js avec comme contenu:

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

Vous devez également charger jquery-ui. Pour ce faire, insérez à app/assets/javascripts/application.js ligne:

//= require jquery-ui

ou tout simplement utiliser les CDN par exemple:

<%= 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" %>

Les feuilles de style pour jquery-ui coul être inclded http://babinho.net/2011/10/rails-3-1-jquery-ui/ou de CA:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X