I am using the bootstrap date picker to enable selection of dates in a form using simple_form_for. For example
<%= f.input :payment_date, as: :string, i
<%= f.input :payment_date, as: :string, input_html: { class: "datepicker", value: Time.now.strftime('%d-%m-%Y') } %>
Another format to it is: (working with active admin gem)
f.input :date, as: :date_picker, :input_html => { :value => Date.today}
You can also use this gem: https://github.com/Nerian/bootstrap-datepicker-rails
on your gemfile.rb
gem 'bootstrap-datepicker-rails'
then bundle install and restart rails server
then add this line to app/assets/stylesheets/application.css
*= require bootstrap-datepicker
and add this line to app/assets/javascripts/application.js
//= require bootstrap-datepicker
and to use this in your form:
<%= f.text_field :payment_date, :id => "datepicker", :value => Date.today %>
and add this javascript on the same view of your form
<script>
$('#datepicker').datepicker({format: 'yyyy-mm-dd'});
</script>
I also needed to get this working and support multiple locales that do not use US centric date formats, eg: en-AU (Australia) which has the date format dd/mm/yyyy.
Rails expects the date format to be yyyy-mm-dd
from the browser, yet you want to display the date in the user's locale. Whilst the date control allows you to specify the format for display it does NOT allow you to separately specify the format to be sent back to the server.
Build a hidden input field that sends the correct format back to your rails server. I do this with with a custom simple_form input control that builds both the date-picker input field and a hidden field, and use some javascript to convert to the rails date when the input control changes.
The upshot is you can have a nice bootstrap date-picker in rails and use it with simple_form as follows:
<%= f.input :date, as: :bootstrap_datepicker %>
Or to use a long date format:
<%= f.input :date, as: :bootstrap_datepicker, input_html: { format: :long } %>
Create or edit the following files:
Gemfile
gem 'bootstrap-sass'
gem 'bootstrap-datepicker-rails'
config/locales/en-AU.yml
en-AU:
date:
datepicker:
default: "dd/mm/yyyy"
long: "dd MM, yyyy"
formats:
default: ! '%d/%m/%Y'
long: ! '%d %B, %Y'
config/locales/en-US.yml
en-US:
date:
datepicker:
default: "mm/dd/yyyy"
long: "MM dd, yyyy"
formats:
default: "dd/mm/yyyy"
long: ! '%B %d, %Y'
app/assets/stylesheets/application.css.scss
@import "bootstrap-responsive";
@import "bootstrap-datepicker";
app/assets/javascripts/application.js.coffee
#= require bootstrap
#= require bootstrap-datepicker
#= require bootstrap-datepicker-rails
Alternatively, app/assets/javascripts/application.js
//= require bootstrap
//= require bootstrap-datepicker
//= require bootstrap-datepicker-rails
app/assets/javascripts/bootstrap-datepicker-rails.js.coffee
$ ->
# convert bootstrap-datepicker value to rails date format (yyyy-mm-dd) on our hidden field
$(document).on 'changeDate', '.bootstrap-datepicker', (evt) ->
rails_date = evt.date.getFullYear() + '-' + ('0' + (evt.date.getMonth() + 1)).slice(-2) + '-' + ('0' + evt.date.getDate()).slice(-2)
$(this).next("input[type=hidden]").val(rails_date)
app/inputs/bootstrap_datepicker_input.rb
class BootstrapDatepickerInput < SimpleForm::Inputs::Base
def input
text_field_options = input_html_options.with_indifferent_access
format = text_field_options.delete(:format)
hidden_field_options = text_field_options.dup
hidden_field_options[:class] = text_field_options[:class].dup # so they won't work with same array object
hidden_field_options[:id] = "#{attribute_name}_hidden"
text_field_options[:class] << 'bootstrap-datepicker'
text_field_options[:type] = 'text'
text_field_options[:value] ||= format_date(value(object), format)
set_data_option text_field_options, 'date-format', I18n.t(format, scope: [:date, :datepicker], default: :default)
default_data_option text_field_options, 'provide', 'datepicker'
return_string =
"#{@builder.text_field(attribute_name, text_field_options.to_hash)}\n" +
"#{@builder.hidden_field(attribute_name, hidden_field_options.to_hash)}\n"
return return_string.html_safe
end
protected
def default_data_option(hash, key, value)
set_data_option(hash,key,value) unless data_option(hash, key)
end
def data_option(hash, key)
hash[:data].try(:[],key) || hash["data-#{key}"]
end
def set_data_option(hash, key, value)
hash[:data].try(:[]=,key,value) || (hash["data-#{key}"] = value)
end
def value(object)
object.send @attribute_name if object
end
def format_date(value, format=nil)
value.try(:strftime, I18n.t(format, scope: [ :date, :formats ], default: :default))
end
end
Minor addition to what Andrew Hacking said: your coffeescript will also want to capture the clearDate
event.
$ ->
# convert bootstrap-datepicker value to rails date format (yyyy-mm-dd) on our hidden field
$(document).on 'changeDate clearDate', '.bootstrap-datepicker', (evt) ->
rails_date = if evt.date? then evt.date.getFullYear() + '-' + ('0' + (evt.date.getMonth() + 1)).slice(-2) + '-' + ('0' + evt.date.getDate()).slice(-2) else ''
$(this).next("input[type=hidden]").val(rails_date)$(document).on 'changeDate clearDate', '.bootstrap-datepicker', (evt) ->`