web-dev-qa-db-fra.com

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

J'adore le joyau simple_form pour Rails mais je n'aime pas cette ligne de code:

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

J'aimerais écrire:

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

ou même écrasez complètement les correspondants :date/:datetime.

Mais je ne veux pas vraiment écrire un custom_simple_form entier

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

S'il vous plaît aider merci

33
nodrog

Les réponses ici semblent un peu dépassées si vous utilisez simple_form 2.0.

Je me bats avec ça depuis un moment et j'ai pu le concocter; il utilise l'héritage (notez qu'il s'agit d'une sous-classe de StringInput et non de Base), prend en charge i18n et ajoute la classe datepicker css d'une manière 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 le même:

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

Sur la base de la réponse de @ kikito, je l’ai fait pour obtenir un datepicker natif (c’est-à-dire aucune classe JS spéciale).

config/initializers/simple_form_datepicker.rb

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

Puis utilisé comme:

f.input :paid_on, as: :datepicker

Notez que si vous avez également un simple_form_bootstrap3.rb initializer ou similaire, comme nous l’avons fait, vous devriez:

  1. ajoutez DatepickerInput à sa liste d'entrées
  2. assurez-vous que l'initialiseur simple_form_bootstrap3.rb (ou similaire) charge aprèssimple_form_datepicker.rb, afin que la classe DatepickerInput soit disponible. Faites-le par exemple renommer l'initialiseur datepicker en simple_form_0_datepicker.rb.
6
Henrik N

Une autre option pourrait également consister à écraser l’assistant DateTimeInput par défaut. Voici un exemple à placer 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 l'utilisation de cette méthode en fait une fonctionnalité de suppression pour vos formulaires, mais qu'elle pourrait également rompre avec les futures versions de simple_form.

Remarque concernant les dates localisées: Autant que je sache, Ruby interprète les dates en respectant seulement quelques formats. Soyez prudent avant de les localiser et assurez-vous que Ruby puisse les gérer . Une tentative d'amélioration la prise en charge de la localisation sur l'analyse Ruby Date a été démarrée à https://github.com/ZenCocoon/I18n-date-parser , mais cela ne fonctionne toujours pas.