TimeSplitter
Setting DateTimes can be a difficult or ugly thing, especially through a web form. Finding a good DatePicker or TimePicker is easy, but getting them to work on both can be difficult. TimeSplitter automatically generates accessors for date, time, hour, and min on your datetime or time attributes, making it trivial to use different form inputs to set different parts of a datetime field.
This gem is based on SplitDatetime by Michi Huber. TimeSplitter improves on the gem, updating for Rails 4, adding time accessors, and providing a safer and more consistent default setting.
Install
Standalone
$ gem install time_splitter
Gemfile
In your Gemfile:
gem "time_splitter"
After bundling, assuming you have an Event model with a starts_at attribute, add this to your model:
class Event < ActiveRecord::Base
extend TimeSplitter::Accessors
split_accessor :starts_at
end
In your view:
<%= simple_form_for @event do |f| %>
<%= f.input :starts_at_date, as: :string, input_html: { class: 'datepicker' } %>
<%= f.input :starts_at_hour, collection: 0..24 %>
<%= f.input :starts_at_min, collection: [0, 15, 30, 45] %>
<%= f.input :starts_at_time, as: :time_select
<%= ... %>
<% end %>
Add your js datepicker and you're good to go. (Of course, this also works with standard Rails form helpers).
If you are using Rails < 4.0 and/or are not using StrongParameters, you must add the attr_accessor for any of the split attributes you want to permit mass-assignment. TimeSplitter provides the methods that can be directly accessed, but will not automatically whitelist any of them for mass-assignment.
Options
You can specify the date format for the view:
split_accessor :starts_at, format: "%D"
See Time#strftime for formats. Default is "%F".
You can specify multiple datetime fields to split:
split_accessor :starts_at, :ends_at, :expires_at, format: "%D"
You can specify a default timey object to write. If starts_at is nil, which it would be at the time of a new or create call, TimeSplitter will use the default value as the basepoint for modification.
split_accessor :starts_at, default: -> { DateTime.current }
# model = Model.new(starts_at_time: '09:00')
# model.starts_at
# => Thu, 10 Oct 2013 09:00:00 -0400
The default time object is Time.new(0, 1, 1, 0, 0, 0, '+00:00').
Note that TimeSplitter does not handle seconds at this time, and from testing it appears they are set to zero when modifying them.


