可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I love the simple_form
gem for rails but i dont like this line of code:
<%= f.input :deadline, :as => :string, :input_html => { :class => 'date_picker' } %>
I would like to write:
<%= f.input :deadline, :as => :date_picker %>
or even over write the :date
/ :datetime
matchers completely.
But i dont really want to write a whole custom_simple_form
I think it must be possible...
Please help thanks
回答1:
You have to define a new DatePickerInput
class.
module SimpleForm
module Inputs
class DatePickerInput < Base
def input
@builder.text_field(attribute_name,input_html_options)
end
end
end
end
And you can now write
<%= f.input :deadline, :as => :date_picker %>
Off course you also need
$("input.date_picker").datepicker();
in application.js
This is very useful to localize dates. Look at this:
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
You have now a localized date in the text field!
Update: a cleaner way to do the same
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
Inherit from SimpleForm::Inputs::StringInput
(as @kikito said) and add some html options.
If you need also a specific class you can add something like
def input_html_classes
super.push('date_picker')
end
回答2:
The answers here seem a bit out of date if you are using simple_form 2.0.
I've been fighting with this for a while and was able to concoct this; it uses inheritance (notice that it is a subclass of StringInput
, not Base
), supports i18n and adds the datepicker
css class in a more clean way, 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
The usage is like above:
<%= f.input :deadline, :as => :date_picker %>
And the javascript remains the same:
$("input.date_picker").datepicker();
回答3:
Based on @kikito's answer, I did this to get a native datepicker (i.e. no special 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
Then used it like:
f.input :paid_on, as: :datepicker
Note that if you also have a simple_form_bootstrap3.rb initializer or similar, like we did, you should:
- add
DatepickerInput
to its list of inputs
- make sure the
simple_form_bootstrap3.rb
(or similar) initializer loads after simple_form_datepicker.rb
, so that the DatepickerInput
class is available. Do that by e.g. renaming the datepicker initializer to simple_form_0_datepicker.rb
.
回答4:
An other option could also be to overwrite the default DateTimeInput
helper, here's an example to be placed in 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
Please notice than while using this method makes it a drop feature for your forms, it might also break with future versions of simple_form.
Notice about localized dates: As far as I know Ruby interprets dates following only a few formats, you might want to be careful before localizing them and make sure Ruby can handle them.
An attempt to better localization support on the Ruby Date parsing as been started at https://github.com/ZenCocoon/I18n-date-parser, yet, this is not working.
回答5:
In new formtastic previews answers doesn't work. See http://justinfrench.com/notebook/formtastic-2-preview-custom-inputs
Here is a simple working example (save to 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
Create a file app/assets/javascripts/date_picker.js with content:
$(function() {
$("input#.date_picker").datepicker();
});
You also need to load jquery-ui. To do so, insert to app/assets/javascripts/application.js line:
//= require jquery-ui
or simply use CDN eg:
<%= 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" %>
Stylesheets for jquery-ui coul be inclded http://babinho.net/2011/10/rails-3-1-jquery-ui/ or
from CDN:
<%= stylesheet_link_tag "application", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/themes/ui-lightness/jquery-ui.css" %>