A Rails time_select like Google Calendar with combined hour and minute time_select
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
Gemfile First commit Dec 23, 2011
LICENSE First commit Dec 23, 2011


Combined Time Select

Compatible with Rails 5+

Written by Chris Oliver @excid3.

This is a small gem for creating Google Calendar style 12 hour AM/PM time_select fields for Rails. It's based off of simple_time_select by tamoyal.




Just add this into your Gemfile followed by a bundle install:

gem "combined_time_select", "~> 2.0.0"


Here we have a model called Event with the start_time attribute that we will be using with combined_time_select.

Because Rails time_select fields submit separate values, there is some overhead on the controller side when we combine the fields into one. We can't rely on Rails to parse the input into a valid time anymore.

In the view you can do the following:

<%= f.time_select :start_time,
  :combined => true,
  :default => Time.now.change(:hour => 11, :min => 30),
  :minute_interval => 15,
  :time_separator => "",
  :start_hour => 10,
  :start_minute => 30,
  :end_hour => 14,
  :end_minute => 30

This will create a combined time select starting at 10:30 AM and going till 2:30 PM with 15 minute intervals with a default of 11:30 AM. This will set the value for the start_time attribute on the object this form was created for.

Because combined_time_select overrides the time_select method to provide you the combined time fields, there is no need to designate a method when using libraries such as Formtastic. You will, however, need to disable the built in hour and minute labels by indicating :labels => false (though you can still give your individual field a label with :label => "Label Name") and to add in the am/pm designation for a 12 hour clock by indicating :ampm => true.

On the controller side, we need to parse this attribute before we create a new object. combined_time_select provides a nice method for this called parse_time_select!. You can use this in your create action just before you initialize the new model:

def create
  params[:event].parse_time_select! :start_time
  @event = Event.new params[:event]

def update
  params[:event].parse_time_select! :start_time
  @event = Event.find(params[:event])
  if @event.update_attributes params[:event]

And voila! You're all set.

If you would like to include a date with your time_select, you can use date_select with the same paramter name and the fields will be combined with the time.

<%= form.date_select :event_start %>
<%= form.time_select :event_start, combined: true %>

Behind The Scenes

When the form gets submitted we will recieve a params hash like so:

{"utf8"=>"✓", "event"=>{"start_time(5i)"=>"10:00:00"}, "commit"=>"Save changes"}

A normal time_select wil use start_time(4i) for the hours and start_time(5i) for the minutes. The parse_time_select! will take all the start_time(Xi) fields, parse them into a Time object and set the params[:start_time] attribute to this object. The result after a parse_time_select!(attribute) looks like this:

{"utf8"=>"✓", "event"=>{"start_time"=>Fri, 23 Dec 2011 10:00:00 UTC +00:00}, "commit"=>"Save changes"}

This allows you to also seamlessly use a date_select field in combination with combined_time_select.