webentwicklung-frage-antwort-db.com.de

Wie schreibe ich eine sauberere Datumsauswahl für SimpleForm

Ich liebe den simple_form Edelstein für Rails, aber ich mag diese Codezeile nicht:

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

Ich würde gerne schreiben:

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

oder schreiben Sie die :date/:datetime Matcher sogar vollständig.

Aber ich möchte nicht wirklich einen ganzen custom_simple_form schreiben

Ich denke, es muss möglich sein ...

Bitte helfen Sie danke

33
nodrog

Sie müssen eine neue DatePickerInput-Klasse definieren.

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

Und du kannst jetzt schreiben

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

Natürlich brauchen Sie auch 

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

in application.js

Dies ist sehr nützlich, um Datumsangaben zu lokalisieren. Schau dir das an:

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

Sie haben jetzt ein lokalisiertes Datum im Textfeld!

Update: ein sauberer Weg, um das gleiche zu tun

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

Vererben Sie sich von SimpleForm::Inputs::StringInput (wie @kikito gesagt hat) und fügen Sie einige HTML-Optionen hinzu. Wenn Sie auch eine bestimmte Klasse benötigen, können Sie etwas hinzufügen

def input_html_classes
  super.Push('date_picker')
end
37
vicvega

Die Antworten hier scheinen etwas veraltet zu sein, wenn Sie simple_form 2.0 verwenden.

Ich habe seit einiger Zeit damit zu kämpfen und habe es geschafft; Es verwendet Vererbung (beachten Sie, dass es sich um eine Unterklasse von StringInput, nicht um Base handelt), unterstützt i18n und fügt die datepicker css-Klasse auf reinere Weise hinzu, IMHO.

# 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

Die Verwendung ist wie oben:

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

Und das Javascript bleibt dasselbe:

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

Basierend auf der Antwort von @ kikito habe ich dies getan, um einen nativen Datepicker (d. H. Keine speziellen JS-Klassen) zu erhalten.

config/initializers/simple_form_datepicker.rb

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

Dann verwendet es wie:

f.input :paid_on, as: :datepicker

Wenn Sie auch einen simple_form_bootstrap3.rb initializer oder ein ähnliches Programm wie wir haben, sollten Sie:

  1. füge DatepickerInput zur Liste der Eingänge hinzu
  2. stellen Sie sicher, dass der Initialisierer simple_form_bootstrap3.rb (oder ähnliches) after simple_form_datepicker.rb lädt, damit die Klasse DatepickerInput verfügbar ist. Tun Sie das, indem Sie z. Umbenennen des Datepicker-Initialisierers in simple_form_0_datepicker.rb.
6
Henrik N

Eine andere Option könnte auch darin bestehen, den Standard-Helper DateTimeInput zu überschreiben. Hier ein Beispiel, das in app/inputs/date_time_input.rb platziert werden soll.

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

Bitte beachten Sie, dass diese Methode während der Verwendung dieser Methode zu einer Drop-Funktion für Ihre Formulare wird, die auch mit zukünftigen Versionen von simple_form brechen kann.

Hinweis zu lokalisierten Datumsangaben : Soweit ich weiß, interpretiert Ruby Datumsangaben, die nur einigen wenigen Formaten folgen, sollten Sie vorsichtig sein, bevor Sie sie lokalisieren, und sicherstellen, dass Ruby damit umgehen kann. Ein Versuch, die Lokalisierungsunterstützung beim Ruby Date-Parsing zu verbessern, wurde unter https://github.com/ZenCocoon/I18n-date-parser gestartet. Dies funktioniert jedoch nicht.