Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First commit

  • Loading branch information...
commit 2fa1ce9994520c78bf609c9a1d43916c32c44070 0 parents
@excid3 authored
4 .gitignore
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
4 Gemfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in combined_time_select.gemspec
+gemspec
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Anthony Amoyal
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
60 README.md
@@ -0,0 +1,60 @@
+Combined Time Select
+====================
+
+This is a small gem for creating Google Calendar style 12 hour AM/PM
+time_select fields for Rails 3. It's based off of [simple_time_select](https://github.com/tamoyal/simple_time_select) by tamoyal.
+
+Usage
+-----
+
+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,
+ :end_hour => 14 } %>
+
+This will create a combined time select starting at 10 AM and going till
+2 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.
+
+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]
+ end
+
+And voila! You're all set.
+
+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 with
+combined_time_select.
1  Rakefile
@@ -0,0 +1 @@
+require "bundler/gem_tasks"
24 combined_time_select.gemspec
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "combined_time_select/version"
+
+Gem::Specification.new do |s|
+ s.name = "combined_time_select"
+ s.version = CombinedTimeSelect::VERSION
+ s.authors = ["Chris Oliver"]
+ s.email = ["excid3@gmail.com"]
+ s.homepage = "https://github.com/excid3/combined_time_select"
+ s.summary = %q{A Rails time_select like Google Calendar with combined hour and minute time_select}
+ s.description = %q{Generates a time_select field like Google calendar.}
+
+ s.rubyforge_project = "combined_time_select"
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+
+ # specify any dependencies here; for example:
+ # s.add_development_dependency "rspec"
+ # s.add_runtime_dependency "rest-client"
+end
120 lib/combined_time_select.rb
@@ -0,0 +1,120 @@
+require "combined_time_select/version"
+
+module CombinedTimeSelect
+ # Your code goes here...
+end
+
+
+module ActiveSupport
+ class HashWithIndifferentAccess < Hash
+ def parse_time_select!(attribute)
+ self[attribute] = Time.zone.parse("#{self["#{attribute}(1i)"]}-#{self["#{attribute}(2i)"]}-#{self["#{attribute}(3i)"]} #{self["#{attribute}(5i)"]}")
+ (1..5).each { |i| self.delete "#{attribute}(#{i}i)" }
+ self
+ end
+ end
+end
+
+
+module ActionView::Helpers
+ class DateTimeSelector
+ def select_minute_with_simple_time_select
+ return select_minute_without_simple_time_select unless @options[:combined].eql? true
+
+ # Although this is a datetime select, we only care about the time. Assume that the date will
+ # be set by some other control, and the date represented here will be overriden
+
+ val_minutes = @datetime.kind_of?(Time) ? @datetime.min + @datetime.hour*60 : @datetime
+
+ @options[:time_separator] = ""
+
+ # Default is 15 minute intervals
+ minute_interval = 15
+ if @options[:minute_interval]
+ minute_interval = @options[:minute_interval]
+ end
+
+ start_minute = 0
+ # @options[:start_hour] should be specified in military
+ # i.e. 0-23
+ if @options[:start_hour]
+ start_minute = @options[:start_hour] * 60
+ end
+
+ end_minute = 1439
+ # @options[:end_hour] should be specified in military
+ # i.e. 0-23
+ if @options[:end_hour]
+ end_minute = ( @options[:end_hour] + 1 ) * 60 - 1
+ end
+
+ if @options[:use_hidden] || @options[:discard_minute]
+ build_hidden(:minute, val)
+ else
+ minute_options = []
+ start_minute.upto(end_minute) do |minute|
+ if minute%minute_interval == 0
+ ampm = minute < 720 ? ' AM' : ' PM'
+ hour = minute/60
+ minute_padded = zero_pad_num(minute%60)
+ hour_padded = zero_pad_num(hour)
+ ampm_hour = ampm_hour(hour)
+
+ val = "#{hour_padded}:#{minute_padded}:00"
+ minute_options << ((val_minutes == minute) ?
+ %(<option value="#{val}" selected="selected">#{ampm_hour}:#{minute_padded}#{ampm}</option>\n) :
+ %(<option value="#{val}">#{ampm_hour}:#{minute_padded}#{ampm}</option>\n)
+ )
+ end
+ end
+ build_select(:minute, minute_options.join(' '))
+ end
+ end
+ alias_method_chain :select_minute, :simple_time_select
+
+
+ def select_hour_with_simple_time_select
+ return select_hour_without_simple_time_select unless @options[:combined].eql? true
+ # Don't build the hour select
+ #build_hidden(:hour, val)
+ end
+ alias_method_chain :select_hour, :simple_time_select
+
+ def select_second_with_simple_time_select
+ return select_second_without_simple_time_select unless @options[:combined].eql? true
+ # Don't build the seconds select
+ #build_hidden(:second, val)
+ end
+ alias_method_chain :select_second, :simple_time_select
+
+ def select_year_with_simple_time_select
+ return select_year_without_simple_time_select unless @options[:combined].eql? true
+ # Don't build the year select
+ #build_hidden(:year, val)
+ end
+ alias_method_chain :select_year, :simple_time_select
+
+ def select_month_with_simple_time_select
+ return select_month_without_simple_time_select unless @options[:combined].eql? true
+ # Don't build the month select
+ #build_hidden(:month, val)
+ end
+ alias_method_chain :select_month, :simple_time_select
+
+ def select_day_with_simple_time_select
+ return select_day_without_simple_time_select unless @options[:combined].eql? true
+ # Don't build the day select
+ #build_hidden(:day, val)
+ end
+ alias_method_chain :select_day, :simple_time_select
+
+ end
+end
+
+def ampm_hour(hour)
+ return hour == 12 ? 12 : (hour == 0 ? 12 : (hour / 12 == 1 ? hour % 12 : hour))
+end
+
+def zero_pad_num(num)
+ return num < 10 ? '0' + num.to_s : num.to_s
+end
3  lib/combined_time_select/version.rb
@@ -0,0 +1,3 @@
+module CombinedTimeSelect
+ VERSION = "0.0.1"
+end
Please sign in to comment.
Something went wrong with that request. Please try again.