calendar_date_select 1.12 → 1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt CHANGED
@@ -1,3 +1,15 @@
1
+ == Version 1.13
2
+ * Lots of code clean up!
3
+ * Moved test suite over to rspec
4
+ * CalendarDateSelect.default_options implemented. Use CalendarDateSelect.default_options.update(...) to set the default_options for your app.
5
+ * calendar_date_select and calendar_date_select_tag accept an :image parameter.
6
+ * Backwards compatibility hook for Rails 2.1
7
+ * RDOC!
8
+ * Don't try to focus a hidden or disabled element (closes #129 - thanks Bruno)
9
+ * Call onchange callback when clearing the calendar (closes #137 - thanks Chewi)
10
+ * Fixed issue that made :db format worthless (closes #135, thanks Andreas Zecher)
11
+ * dramatic optimization for calendar initial-rendering (thanks Yehudab, Bompus)
12
+
1
13
  == Version 1.12 ==
2
14
  * Updated for compatibility with Rails 2.2
3
15
 
data/Manifest.txt CHANGED
@@ -7,6 +7,7 @@ js_test/unit/cds_helper_methods.html
7
7
  js_test/unittest.js
8
8
  lib/calendar_date_select/calendar_date_select.rb
9
9
  lib/calendar_date_select/includes_helper.rb
10
+ lib/calendar_date_select/form_helpers.rb
10
11
  lib/calendar_date_select.rb
11
12
  Manifest.txt
12
13
  MIT-LICENSE
@@ -34,6 +35,8 @@ public/stylesheets/calendar_date_select/red.css
34
35
  public/stylesheets/calendar_date_select/silver.css
35
36
  Rakefile
36
37
  Readme.txt
37
- test/functional/calendar_date_select_test.rb
38
- test/functional/helper_methods_test.rb
39
- test/test_helper.rb
38
+ spec/
39
+ spec/calendar_date_select
40
+ spec/calendar_date_select/calendar_date_select_spec.rb
41
+ spec/calendar_date_select/form_helpers_spec.rb
42
+ spec/spec_helper.rb
@@ -1,17 +1,26 @@
1
1
  require "calendar_date_select/calendar_date_select.rb"
2
+ require "calendar_date_select/form_helpers.rb"
2
3
  require "calendar_date_select/includes_helper.rb"
3
4
 
4
5
  if Object.const_defined?(:Rails) && File.directory?(Rails.root + "/public")
5
- ActionView::Helpers::FormHelper.send(:include, CalendarDateSelect::FormHelper)
6
- ActionView::Base.send(:include, CalendarDateSelect::FormHelper)
6
+ ActionView::Helpers::FormHelper.send(:include, CalendarDateSelect::FormHelpers)
7
+ ActionView::Base.send(:include, CalendarDateSelect::FormHelpers)
7
8
  ActionView::Base.send(:include, CalendarDateSelect::IncludesHelper)
8
-
9
+
10
+ # Filthy backwards compatibility hooks... grumble
9
11
  if ([Rails::VERSION::MAJOR, Rails::VERSION::MINOR] <=> [2, 2]) == -1
10
- puts "This version of calendar date select (#{CalendarDateSelect.version}) requires Rails 2.2"
11
- puts "To use an earlier version of rails, use calendar_date_select version 1.11.x"
12
- exit
13
- end
12
+ ActionView::Helpers::InstanceTag.class_eval do
13
+ def self.new_with_backwards_compatibility(object_name, method_name, template_object, object = nil)
14
+ new(object_name, method_name, template_object, nil, object)
15
+ end
16
+ end
14
17
 
18
+ else
19
+ ActionView::Helpers::InstanceTag.class_eval do
20
+ class << self; alias new_with_backwards_compatibility new; end
21
+ end
22
+ end
23
+
15
24
  # install files
16
25
  unless File.exists?(RAILS_ROOT + '/public/javascripts/calendar_date_select/calendar_date_select.js')
17
26
  ['/public', '/public/javascripts/calendar_date_select', '/public/stylesheets/calendar_date_select', '/public/images/calendar_date_select', '/public/javascripts/calendar_date_select/locale'].each do |dir|
@@ -1,5 +1,5 @@
1
- class CalendarDateSelect
2
- VERSION = '1.12'
1
+ module CalendarDateSelect
2
+ VERSION = '1.13'
3
3
  FORMATS = {
4
4
  :natural => {
5
5
  :date => "%B %d, %Y",
@@ -11,10 +11,10 @@ class CalendarDateSelect
11
11
  :javascript_include => "format_hyphen_ampm"
12
12
  },
13
13
  :iso_date => {
14
- :date => "%Y-%m-%d",
14
+ :date => "%Y-%m-%d",
15
15
  :time => " %H:%M",
16
16
  :javascript_include => "format_iso_date"
17
- },
17
+ },
18
18
  :finnish => {
19
19
  :date => "%d.%m.%Y",
20
20
  :time => " %H:%M",
@@ -27,12 +27,12 @@ class CalendarDateSelect
27
27
  },
28
28
  :euro_24hr => {
29
29
  :date => "%d %B %Y",
30
- :time => " %H:%M",
30
+ :time => " %H:%M",
31
31
  :javascript_include => "format_euro_24hr"
32
32
  },
33
33
  :euro_24hr_ymd => {
34
34
  :date => "%Y.%m.%d",
35
- :time => " %H:%M",
35
+ :time => " %H:%M",
36
36
  :javascript_include => "format_euro_24hr_ymd"
37
37
  },
38
38
  :italian => {
@@ -42,182 +42,75 @@ class CalendarDateSelect
42
42
  },
43
43
  :db => {
44
44
  :date => "%Y-%m-%d",
45
- :time => "%H:%M",
45
+ :time => " %H:%M",
46
46
  :javascript_include => "format_db"
47
47
  }
48
48
  }
49
-
50
- cattr_accessor :image
51
- @@image = "calendar_date_select/calendar.gif"
52
-
53
- cattr_reader :format
54
- @@format = FORMATS[:natural]
55
-
56
- class << self
57
- def format=(format)
58
- raise "CalendarDateSelect: Unrecognized format specification: #{format}" unless FORMATS.has_key?(format)
59
- @@format = FORMATS[format]
60
- end
61
-
62
- def javascript_format_include
63
- @@format[:javascript_include] && "calendar_date_select/#{@@format[:javascript_include]}"
64
- end
65
-
66
- def date_format_string(time=false)
67
- @@format[:date] + ( time ? @@format[:time] : "" )
68
- end
69
-
70
- def format_date(date)
71
- if Date===date
72
- date.strftime(date_format_string(false))
73
- else
74
- date.strftime(date_format_string(true))
75
- end
76
- end
77
-
78
- def has_time?(value)
79
- /[0-9]:[0-9]{2}/.match(value.to_s)
80
- end
49
+
50
+ # Returns the default_options hash. These options are by default provided to every calendar_date_select control, unless otherwise overrided.
51
+ #
52
+ # Example:
53
+ # # At the bottom of config/environment.rb:
54
+ # CalendarDateSelect.default_options.update(
55
+ # :popup => "force",
56
+ # :month_year => "label",
57
+ # :image => "custom_calendar_picker.png"
58
+ # )
59
+ def self.default_options
60
+ @default_options ||= { :image => "calendar_date_select/calendar.gif" }
81
61
  end
82
-
83
- module FormHelper
84
- def calendar_date_select_tag( name, value = nil, options = {})
85
- calendar_options = calendar_date_select_process_options(options)
86
- value = format_time(value, calendar_options)
87
-
88
- calendar_options.delete(:format)
89
-
90
- options[:id] ||= name
91
- tag = calendar_options[:hidden] || calendar_options[:embedded] ?
92
- hidden_field_tag(name, value, options) :
93
- text_field_tag(name, value, options)
94
-
95
- calendar_date_select_output(tag, calendar_options)
96
- end
97
-
98
- def format_time(value, options = {})
99
- if value.respond_to?("strftime")
100
- if options[:format]
101
- value = value.strftime(options[:format])
102
- else
103
- if options.has_key? :time
104
- value = value.strftime(CalendarDateSelect.date_format_string(options[:time]))
105
- else
106
- value = CalendarDateSelect.format_date(value)
107
- end
108
- end
109
- end
110
- value
111
- end
112
-
113
- # extracts any options passed into calendar date select, appropriating them to either the Javascript call or the html tag.
114
- def calendar_date_select_process_options(options)
115
- calendar_options = {}
116
- callbacks = [:before_show, :before_close, :after_show, :after_close, :after_navigate]
117
- for key in [:time, :valid_date_check, :embedded, :buttons, :clear_button, :format, :year_range, :month_year, :popup, :hidden, :minute_interval] + callbacks
118
- calendar_options[key] = options.delete(key) if options.has_key?(key)
119
- end
120
-
121
- # if passing in mixed, pad it with single quotes
122
- calendar_options[:time] = "'mixed'" if calendar_options[:time].to_s=="mixed"
123
- calendar_options[:month_year] = "'#{calendar_options[:month_year]}'" if calendar_options[:month_year]
124
-
125
- # if we are forcing the popup, automatically set the readonly property on the input control.
126
- if calendar_options[:popup].to_s == "force"
127
- calendar_options[:popup] = "'force'"
128
- options[:readonly] = true
129
- end
130
-
131
- if (vdc=calendar_options.delete(:valid_date_check))
132
- if vdc.include?(";") || vdc.include?("function")
133
- throw ":valid_date_check function is missing a 'return' statement. Try something like: :valid_date_check => 'if (date > new(Date)) return true; else return false;'" unless vdc.include?("return");
134
- end
135
-
136
- vdc = "return(#{vdc})" unless vdc.include?("return")
137
- vdc = "function(date) { #{vdc} }" unless vdc.include?("function")
138
- calendar_options[:valid_date_check] = vdc
139
- end
140
-
141
- calendar_options[:popup_by] ||= "this" if calendar_options[:hidden]
142
-
143
- # surround any callbacks with a function, if not already done so
144
- for key in callbacks
145
- calendar_options[key] = "function(param) { #{calendar_options[key]} }" unless calendar_options[key].include?("function") if calendar_options[key]
146
- end
147
-
148
- calendar_options[:year_range] = format_year_range(calendar_options[:year_range] || 10)
149
- calendar_options
150
- end
151
-
152
- def calendar_date_select(object, method, options={})
153
- obj = options[:object] || instance_variable_get("@#{object}")
154
-
155
- if !options.include?(:time) && obj.class.respond_to?("columns_hash")
156
- column_type = (obj.class.columns_hash[method.to_s].type rescue nil)
157
- options[:time] = true if column_type == :datetime
158
- end
159
-
160
- use_time = options[:time]
161
-
162
- if options[:time].to_s=="mixed"
163
- use_time = false if Date===(obj.respond_to?(method) && obj.send(method))
164
- end
165
-
166
- calendar_options = calendar_date_select_process_options(options)
167
-
168
- options[:value] ||=
169
- if(obj.respond_to?(method) && obj.send(method).respond_to?(:strftime))
170
- obj.send(method).strftime(CalendarDateSelect.date_format_string(use_time))
171
- elsif obj.respond_to?("#{method}_before_type_cast")
172
- obj.send("#{method}_before_type_cast")
173
- elsif obj.respond_to?(method)
174
- obj.send(method).to_s
175
- else
176
- nil
177
- end
178
62
 
179
- tag = ActionView::Helpers::InstanceTag.new(object, method, self, options.delete(:object))
180
- calendar_date_select_output(
181
- tag.to_input_field_tag( (calendar_options[:hidden] || calendar_options[:embedded]) ? "hidden" : "text", options),
182
- calendar_options
183
- )
184
- end
185
-
186
- def calendar_date_select_output(input, calendar_options = {})
187
- out = input
188
- if calendar_options[:embedded]
189
- uniq_id = "cds_placeholder_#{(rand*100000).to_i}"
190
- # we need to be able to locate the target input element, so lets stick an invisible span tag here we can easily locate
191
- out << content_tag(:span, nil, :style => "display: none; position: absolute;", :id => uniq_id)
192
-
193
- out << javascript_tag("new CalendarDateSelect( $('#{uniq_id}').previous(), #{options_for_javascript(calendar_options)} ); ")
194
- else
195
- out << " "
196
-
197
- out << image_tag(CalendarDateSelect.image,
198
- :onclick => "new CalendarDateSelect( $(this).previous(), #{options_for_javascript(calendar_options)} );",
199
- :style => 'border:0px; cursor:pointer;')
200
- end
201
-
202
- out
203
- end
204
-
205
- private
206
- def format_year_range(year) # nodoc
207
- return year unless year.respond_to?(:first)
208
- return "[#{year.first}, #{year.last}]" unless year.first.respond_to?(:strftime)
209
- return "[#{year.first.year}, #{year.last.year}]"
63
+ # Set the picker image. Provide the image url the same way you would provide it to image_tag
64
+ def self.image=(value)
65
+ default_options[:image] = value
66
+ end
67
+
68
+ # Returns the options for the given format
69
+ #
70
+ # Example:
71
+ # CalendarDateSelect.format = :italian
72
+ # puts CalendarDateSelect.format[:date]
73
+ # => "%d/%m/%Y"
74
+ def self.format
75
+ @format ||= FORMATS[:natural]
76
+ end
77
+
78
+ # Set the format. To see a list of available formats, CalendarDateSelect::FORMATS.keys, or open lib/calendar_date_select/calendar_date_select.rb
79
+ #
80
+ # (e.g. CalendarDateSelect.format = :italian)
81
+ def self.format=(format)
82
+ raise "CalendarDateSelect: Unrecognized format specification: #{format}" unless FORMATS.has_key?(format)
83
+ @format = FORMATS[format]
84
+ end
85
+
86
+ def self.date_format_string(time = false)
87
+ format[:date] + (time ? format[:time] : "")
88
+ end
89
+
90
+ def self.format_date(date)
91
+ if date.is_a?(Date)
92
+ date.strftime(date_format_string(false))
93
+ else
94
+ date.strftime(date_format_string(true))
210
95
  end
211
96
  end
212
- end
213
97
 
98
+ def self.format_time(value, options = {})
99
+ return value unless value.respond_to?("strftime")
100
+ if options[:time]
101
+ format_date(value)
102
+ else
103
+ format_date(value.to_date)
104
+ end
105
+ end
214
106
 
215
- module ActionView
216
- module Helpers
217
- class FormBuilder
218
- def calendar_date_select(method, options = {})
219
- @template.calendar_date_select(@object_name, method, options.merge(:object => @object))
220
- end
107
+ # Detects the presence of time in a date, string
108
+ def self.has_time?(value)
109
+ case value
110
+ when DateTime, Time then true
111
+ when Date then false
112
+ else
113
+ /[0-9]:[0-9]{2}/.match(value.to_s) ? true : false
221
114
  end
222
115
  end
223
116
  end
@@ -0,0 +1,222 @@
1
+ # Various helpers available for use in your view
2
+ module CalendarDateSelect::FormHelpers
3
+
4
+ # Similar to text_field_tag, but adds a calendar picker, naturally.
5
+ #
6
+ # == Arguments
7
+ #
8
+ # +name+ - the html name of the tag
9
+ # +value+ - When specified as a string, uses value verbatim. When Date, DateTime, Time, it converts it to a string basd off the format set by CalendarDateSelect#format=
10
+ # +options+ - ...
11
+ #
12
+ # == Options
13
+ #
14
+ # === :embedded
15
+ #
16
+ # Put the calendar straight into the form, rather than using a popup type of form.
17
+ #
18
+ # <%= calendar_date_select_tag "name", "2007-01-01", :embedded => true %>
19
+ #
20
+ # === :hidden
21
+ #
22
+ # Use a hidden element instead of a text box for a pop up calendar. Not compatible with :embedded => true. You'll probably want to use an onchange callback to do something with the value.
23
+ #
24
+ # <span id='cds_value' />
25
+ # <%= calendar_date_select_tag "hidden_date_selector", "", :hidden => "true", :onchange => "$('cds_value').update($F(this));" %>
26
+ #
27
+ # === :image
28
+ #
29
+ # Specify an alternative icon to use for the date picker.
30
+ #
31
+ # To use /images/groovy.png:
32
+ #
33
+ # <%= calendar_date_select_tag "altered_image", "", :image => "groovy.png" %>
34
+ #
35
+ # === :minute_interval
36
+ #
37
+ # Specifies the minute interval used in the hour/minute selector. Default is 5.
38
+ #
39
+ # <%= calendar_date_select_tag "month_year_selector_label", "", :minute_interval => 15 %>
40
+ #
41
+ # === :month_year
42
+ #
43
+ # Customize the month and year selectors at the top of the control.
44
+ #
45
+ # Valid values:
46
+ # * "dropdowns" (default) - Use a separate dropdown control for both the month and year
47
+ # * "label" - Use static text to show the month and the year.
48
+ #
49
+ # <%= calendar_date_select_tag "month_year_selector_label", "", :month_year => "label" %>
50
+ #
51
+ # === :popup => 'force'
52
+ #
53
+ # Forces the user to use the popup calendar by making it's text-box read-only and causing calendar_date_select to override it's default behavior of not allowing selection of a date on a target element that is read-only.
54
+ #
55
+ # <%= calendar_date_select_tag "name", "2007-01-01", :popup => "force" %>
56
+ #
57
+ # === :time
58
+ #
59
+ # Show time in the controls. There's three options:
60
+ #
61
+ # * +true+ - show an hour/minute selector.
62
+ # * +false+ - don't show an hour/minute selector.
63
+ # * +"mixed"+ - Show an hour/minute selector, but include a "all day" option - allowing them to choose whether or not to specify a time.
64
+ #
65
+ # === :year_range
66
+ #
67
+ # Limit the year range. You can pass in an array or range of ruby Date/Time objects or FixNum's.
68
+ #
69
+ # <%= calendar_date_select_tag "e_date", nil, :year_range => 10.years.ago..0.years.from_now %>
70
+ # <%= calendar_date_select_tag "e_date", nil, :year_range => [0.years.ago, 10.years.from_now] %>
71
+ # <%= calendar_date_select_tag "e_date", nil, :year_range => 2000..2007 %>
72
+ # <%= calendar_date_select_tag "e_date", nil, :year_range => [2000, 2007] %>
73
+ #
74
+ # == CALLBACKS
75
+ #
76
+ # The following callbacks are available:
77
+ #
78
+ # * before_show / after_show
79
+ # * before_close / after_close
80
+ # * after_navigate - Called when navigating to a different month. Passes first parameter as a date object refering to the current month viewed
81
+ # * onchange - Called when the form input value changes
82
+ #
83
+ # <%= calendar_date_select_tag "event_demo", "",
84
+ # :before_show => "log('Calendar Showing');" ,
85
+ # :after_show => "log('Calendar Shown');" ,
86
+ # :before_close => "log('Calendar closing');" ,
87
+ # :after_close => "log('Calendar closed');",
88
+ # :after_navigate => "log('Current month is ' + (param.getMonth()+1) + '/' + (param.getFullYear()));",
89
+ # :onchange => "log('value changed to - ' + $F(this));"
90
+ #
91
+ # }}}
92
+ #
93
+ # All callbacks are executed within the context of the target input element. If you'd like to access the CalendarDateSelect object itself, you can access it via "this.calendar_date_select".
94
+ #
95
+ # For example:
96
+ #
97
+ # <%= calendar_date_select_tag "event_demo", "", :after_navigate => "alert('The current selected month is ' + this.calendar_date_select.selected_date.getMonth());" ,
98
+ def calendar_date_select_tag( name, value = nil, options = {})
99
+ options, javascript_options = calendar_date_select_process_options(options)
100
+ value = CalendarDateSelect.format_time(value, javascript_options)
101
+
102
+ javascript_options.delete(:format)
103
+
104
+ options[:id] ||= name
105
+ tag = javascript_options[:hidden] || javascript_options[:embedded] ?
106
+ hidden_field_tag(name, value, options) :
107
+ text_field_tag(name, value, options)
108
+
109
+ calendar_date_select_output(tag, options, javascript_options)
110
+ end
111
+
112
+ # Similar to the difference between +text_field_tag+ and +text_field+, this method behaves like +text_field+
113
+ #
114
+ # It receives the same options as +calendar_date_select_tag+. Need for time selection is automatically detected by checking the corresponding column meta information of Model#columns_hash
115
+ def calendar_date_select(object, method, options={})
116
+ obj = options[:object] || instance_variable_get("@#{object}")
117
+
118
+ if !options.include?(:time) && obj.class.respond_to?("columns_hash")
119
+ column_type = (obj.class.columns_hash[method.to_s].type rescue nil)
120
+ options[:time] = true if column_type == :datetime
121
+ end
122
+
123
+ use_time = options[:time]
124
+
125
+ if options[:time].to_s=="mixed"
126
+ use_time = false if Date===(obj.respond_to?(method) && obj.send(method))
127
+ end
128
+
129
+ options, javascript_options = calendar_date_select_process_options(options)
130
+
131
+ options[:value] ||=
132
+ if(obj.respond_to?(method) && obj.send(method).respond_to?(:strftime))
133
+ obj.send(method).strftime(CalendarDateSelect.date_format_string(use_time))
134
+ elsif obj.respond_to?("#{method}_before_type_cast")
135
+ obj.send("#{method}_before_type_cast")
136
+ elsif obj.respond_to?(method)
137
+ obj.send(method).to_s
138
+ else
139
+ nil
140
+ end
141
+
142
+ tag = ActionView::Helpers::InstanceTag.new_with_backwards_compatibility(object, method, self, options.delete(:object))
143
+ calendar_date_select_output(
144
+ tag.to_input_field_tag( (javascript_options[:hidden] || javascript_options[:embedded]) ? "hidden" : "text", options),
145
+ options,
146
+ javascript_options
147
+ )
148
+ end
149
+
150
+ private
151
+ # extracts any options passed into calendar date select, appropriating them to either the Javascript call or the html tag.
152
+ def calendar_date_select_process_options(options)
153
+ options, javascript_options = CalendarDateSelect.default_options.merge(options), {}
154
+ callbacks = [:before_show, :before_close, :after_show, :after_close, :after_navigate]
155
+ for key in [:time, :valid_date_check, :embedded, :buttons, :clear_button, :format, :year_range, :month_year, :popup, :hidden, :minute_interval] + callbacks
156
+ javascript_options[key] = options.delete(key) if options.has_key?(key)
157
+ end
158
+
159
+ # if passing in mixed, pad it with single quotes
160
+ javascript_options[:time] = "'mixed'" if javascript_options[:time].to_s=="mixed"
161
+ javascript_options[:month_year] = "'#{javascript_options[:month_year]}'" if javascript_options[:month_year]
162
+
163
+ # if we are forcing the popup, automatically set the readonly property on the input control.
164
+ if javascript_options[:popup].to_s == "force"
165
+ javascript_options[:popup] = "'force'"
166
+ options[:readonly] = true
167
+ end
168
+
169
+ if (vdc=javascript_options.delete(:valid_date_check))
170
+ if vdc.include?(";") || vdc.include?("function")
171
+ raise ArgumentError, ":valid_date_check function is missing a 'return' statement. Try something like: :valid_date_check => 'if (date > new(Date)) return true; else return false;'" unless vdc.include?("return");
172
+ end
173
+
174
+ vdc = "return(#{vdc})" unless vdc.include?("return")
175
+ vdc = "function(date) { #{vdc} }" unless vdc.include?("function")
176
+ javascript_options[:valid_date_check] = vdc
177
+ end
178
+
179
+ javascript_options[:popup_by] ||= "this" if javascript_options[:hidden]
180
+
181
+ # surround any callbacks with a function, if not already done so
182
+ for key in callbacks
183
+ javascript_options[key] = "function(param) { #{javascript_options[key]} }" unless javascript_options[key].include?("function") if javascript_options[key]
184
+ end
185
+
186
+ javascript_options[:year_range] = format_year_range(javascript_options[:year_range] || 10)
187
+ [options, javascript_options]
188
+ end
189
+
190
+ def calendar_date_select_output(input, options = {}, javascript_options = {})
191
+ out = input
192
+ if javascript_options[:embedded]
193
+ uniq_id = "cds_placeholder_#{(rand*100000).to_i}"
194
+ # we need to be able to locate the target input element, so lets stick an invisible span tag here we can easily locate
195
+ out << content_tag(:span, nil, :style => "display: none; position: absolute;", :id => uniq_id)
196
+ out << javascript_tag("new CalendarDateSelect( $('#{uniq_id}').previous(), #{options_for_javascript(javascript_options)} ); ")
197
+ else
198
+ out << " "
199
+ out << image_tag(options[:image],
200
+ :onclick => "new CalendarDateSelect( $(this).previous(), #{options_for_javascript(javascript_options)} );",
201
+ :style => 'border:0px; cursor:pointer;')
202
+ end
203
+ out
204
+ end
205
+
206
+ def format_year_range(year) # nodoc
207
+ return year unless year.respond_to?(:first)
208
+ return "[#{year.first}, #{year.last}]" unless year.first.respond_to?(:strftime)
209
+ return "[#{year.first.year}, #{year.last.year}]"
210
+ end
211
+ end
212
+
213
+ # Helper method for form builders
214
+ module ActionView
215
+ module Helpers
216
+ class FormBuilder
217
+ def calendar_date_select(method, options = {})
218
+ @template.calendar_date_select(@object_name, method, options.merge(:object => @object))
219
+ end
220
+ end
221
+ end
222
+ end
@@ -1,38 +1,29 @@
1
- class CalendarDateSelect
2
- module IncludesHelper
3
- def calendar_date_select_stylesheets(options = {})
4
- options.assert_valid_keys(:style, :format, :locale)
5
-
6
- style = options[:style]
7
- cds_css_file = style ? "calendar_date_select/#{style}" : "calendar_date_select/default"
8
- return cds_css_file
9
- end
10
-
11
- def calendar_date_select_javascripts(options = {})
12
- options.assert_valid_keys(:style, :format, :locale)
13
-
14
- style = options[:style]
15
- locale = options[:locale]
16
- cds_css_file = style ? "calendar_date_select/#{style}" : "calendar_date_select/default"
17
-
18
- output = []
19
- output << "calendar_date_select/calendar_date_select"
20
- output << "calendar_date_select/locale/#{locale}" if locale
21
- output << CalendarDateSelect.javascript_format_include if CalendarDateSelect.javascript_format_include
22
- return output
23
- end
1
+ module CalendarDateSelect::IncludesHelper
2
+ # returns the selected calendar_date_select stylesheet (not an array)
3
+ def calendar_date_select_stylesheets(options = {})
4
+ options.assert_valid_keys(:style)
5
+ "calendar_date_select/#{options[:style] || "default"}"
6
+ end
24
7
 
25
- def calendar_date_select_includes(*args)
26
- return "" if @cds_already_included
27
- @cds_already_included=true
28
-
29
- options = (Hash === args.last) ? args.pop : {}
30
- options.assert_valid_keys(:style, :format, :locale)
31
- options[:style] ||= args.shift
8
+ # returns an array of javascripts needed for the selected locale, date_format, and calendar control itself.
9
+ def calendar_date_select_javascripts(options = {})
10
+ options.assert_valid_keys(:format, :locale)
11
+ files = ["calendar_date_select/calendar_date_select"]
12
+ files << "calendar_date_select/locale/#{options[:locale]}" if options[:locale]
13
+ files << "calendar_date_select/#{CalendarDateSelect.format[:javascript_include]}" if CalendarDateSelect.format[:javascript_include]
14
+ files
15
+ end
32
16
 
33
- js = javascript_include_tag(*calendar_date_select_javascripts(options))
34
- css = stylesheet_link_tag(*calendar_date_select_stylesheets(options))
35
- "#{js}\n#{css}\n"
36
- end
17
+ # returns html necessary to load javascript and css to make calendar_date_select work
18
+ def calendar_date_select_includes(*args)
19
+ return "" if @cds_already_included
20
+ @cds_already_included=true
21
+
22
+ options = (Hash === args.last) ? args.pop : {}
23
+ options.assert_valid_keys(:style, :format, :locale)
24
+ options[:style] ||= args.shift
25
+
26
+ javascript_include_tag(*calendar_date_select_javascripts(:locale => options[:locale], :format => options[:format])) + "\n" +
27
+ stylesheet_link_tag(*calendar_date_select_stylesheets(:style => options[:style])) + "\n"
37
28
  end
38
29
  end
@@ -1,4 +1,4 @@
1
- // CalendarDateSelect version 1.12 - a prototype based date picker
1
+ // CalendarDateSelect version 1.13 - a prototype based date picker
2
2
  // Questions, comments, bugs? - see the project page: http://code.google.com/p/calendardateselect
3
3
  if (typeof Prototype == 'undefined') alert("CalendarDateSelect Error: Prototype could not be found. Please make sure that your application's layout includes prototype.js (.g. <%= javascript_include_tag :defaults %>) *before* it includes calendar_date_select.js (.g. <%= calendar_date_select_includes %>).");
4
4
  if (Prototype.Version < "1.6") alert("Prototype 1.6.0 is required. If using earlier version of prototype, please use calendar_date_select version 1.8.3");
@@ -15,9 +15,8 @@ Element.addMethods({
15
15
  Element.buildAndAppend = function(type, options, style)
16
16
  {
17
17
  var e = $(document.createElement(type));
18
- $H(options).each(function(pair) { eval("e." + pair.key + " = pair.value" ); });
19
- if (style)
20
- $H(style).each(function(pair) { eval("e.style." + pair.key + " = pair.value" ); });
18
+ $H(options).each(function(pair) { e[pair.key] = pair.value });
19
+ if (style) e.setStyle(style);
21
20
  return e;
22
21
  };
23
22
  nil = null;
@@ -345,9 +344,11 @@ CalendarDateSelect.prototype = {
345
344
  updateFooter:function(text) { if (!text) text = this.dateString(); this.footer_div.purgeChildren(); this.footer_div.build("span", {innerHTML: text }); },
346
345
  clearDate:function() {
347
346
  if ((this.target_element.disabled || this.target_element.readOnly) && this.options.get("popup") != "force") return false;
347
+ var last_value = this.target_element.value;
348
348
  this.target_element.value = "";
349
349
  this.clearSelectedClass();
350
350
  this.updateFooter('&#160;');
351
+ if (last_value!=this.target_element.value) this.callback("onchange");
351
352
  },
352
353
  updateSelectedDate:function(partsOrElement, via_click) {
353
354
  var parts = $H(partsOrElement);
@@ -429,7 +430,7 @@ CalendarDateSelect.prototype = {
429
430
  Event.stopObserving(document, "keypress", this.keyPress_handler);
430
431
  this.calendar_div.remove(); this.closed = true;
431
432
  if (this.iframe) this.iframe.remove();
432
- if (this.target_element.type!="hidden") this.target_element.focus();
433
+ if (this.target_element.type != "hidden" && ! this.target_element.disabled) this.target_element.focus();
433
434
  this.callback("after_close");
434
435
  },
435
436
  closeIfClickedOut: function(e) {
@@ -6,5 +6,6 @@ Date.first_day_of_week = 1;
6
6
  _translations = {
7
7
  "OK": "OK",
8
8
  "Now": "Jetzt",
9
- "Today": "Heute"
9
+ "Today": "Heute",
10
+ "Clear": "Löschen"
10
11
  }
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe CalendarDateSelect do
4
+ it "should detect presence of time in a string" do
5
+ CalendarDateSelect.has_time?("January 7, 2007").should == false
6
+ CalendarDateSelect.has_time?("January 7, 2007 5:50pm").should == true
7
+ CalendarDateSelect.has_time?("January 7, 2007 5:50 pm").should == true
8
+ CalendarDateSelect.has_time?("January 7, 2007 16:30 pm").should == true
9
+
10
+ CalendarDateSelect.has_time?(Date.parse("January 7, 2007 3:00 pm")).should == false
11
+ CalendarDateSelect.has_time?(Time.parse("January 7, 2007 3:00 pm")).should == true
12
+ CalendarDateSelect.has_time?(DateTime.parse("January 7, 2007 3:00 pm")).should == true
13
+ end
14
+ end
@@ -0,0 +1,156 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe CalendarDateSelect::FormHelpers do
4
+ include ActionView::Helpers::FormHelper
5
+ include ActionView::Helpers::JavaScriptHelper
6
+ include ActionView::Helpers::AssetTagHelper
7
+ include ActionView::Helpers::TagHelper
8
+ include ActionView::Helpers::FormTagHelper
9
+
10
+ include CalendarDateSelect::FormHelpers
11
+
12
+ before(:each) do
13
+ @controller = ActionController::Base.new
14
+ @request = OpenStruct.new
15
+ @controller.request = @request
16
+
17
+ @model = OpenStruct.new
18
+ end
19
+
20
+ describe "mixed mode" do
21
+ it "should not output a time when the value is a Date" do
22
+ @model.start_datetime = Date.parse("January 2, 2007")
23
+ output = calendar_date_select(:model, :start_datetime, :time => "mixed")
24
+ output.should_not match(/12:00 AM/)
25
+ end
26
+
27
+ it "should output a time when the value is a Time" do
28
+ @model.start_datetime = Time.parse("January 2, 2007 12:00 AM")
29
+ output = calendar_date_select(:model, :start_datetime, :time => "mixed")
30
+ output.should match(/12:00 AM/)
31
+ end
32
+ end
33
+
34
+ it "should render a time when time is passed as 'true'" do
35
+ @model.start_datetime = Date.parse("January 2, 2007")
36
+ output = calendar_date_select(:model, :start_datetime, :time => "true")
37
+ output.should match(/12:00 AM/)
38
+ end
39
+
40
+ it "should time_false__model_returns_time__should_render_without_time" do
41
+ @model.start_datetime = Time.parse("January 2, 2007 12:00 AM")
42
+ output = calendar_date_select(:model, :start_datetime)
43
+ output.should_not match(/12:00 AM/)
44
+ end
45
+
46
+ it "should _nil_model__shouldnt_populate_value" do
47
+ @model = nil
48
+ output = calendar_date_select(:model, :start_datetime)
49
+
50
+ output.should_not match(/value/)
51
+ end
52
+
53
+ it "should _vdc__should_auto_format_function" do
54
+ @model.start_datetime = Time.parse("January 2, 2007 12:00 AM")
55
+ output = calendar_date_select(:model,
56
+ :start_datetime,
57
+ :valid_date_check => "date < new Date()"
58
+ )
59
+ output.should include("valid_date_check:function(date) { return(date &lt; new Date()) }")
60
+
61
+ output = calendar_date_select(:model,
62
+ :start_datetime,
63
+ :valid_date_check => "return(date < new Date())"
64
+ )
65
+ output.should include("valid_date_check:function(date) { return(date &lt; new Date()) }")
66
+ output = calendar_date_select(:model,
67
+ :start_datetime,
68
+ :valid_date_check => "function(p) { return(date < new Date()) }"
69
+ )
70
+ output.should include("valid_date_check:function(p) { return(date &lt; new Date()) }")
71
+ end
72
+
73
+ it "should raise an error if the valid_date_check function is missing a return statement" do
74
+ message = ":valid_date_check function is missing a 'return' statement. Try something like: :valid_date_check => 'if (date > new(Date)) return true; else return false;'"
75
+ lambda {
76
+ output = calendar_date_select(:model,
77
+ :start_datetime,
78
+ :valid_date_check => "date = 5; date < new Date());"
79
+ )
80
+ }.should raise_error(ArgumentError, message)
81
+
82
+ lambda {
83
+ output = calendar_date_select(:model,
84
+ :start_datetime,
85
+ :valid_date_check => "function(p) { date = 5; date < new Date()); }"
86
+ )
87
+ }.should raise_error(ArgumentError, message)
88
+ end
89
+
90
+ it "should render the year_range argument correctly" do
91
+ output = calendar_date_select(:model, :start_datetime)
92
+ output.should include("year_range:10")
93
+ output = calendar_date_select(:model, :start_datetime, :year_range => 2000..2010)
94
+ output.should include("year_range:[2000, 2010]")
95
+ output = calendar_date_select(:model, :start_datetime, :year_range => (15.years.ago..5.years.ago))
96
+ output.should include("year_range:[#{15.years.ago.year}, #{5.years.ago.year}]")
97
+ end
98
+
99
+ it "should disregard the :object parameter when nil" do
100
+ @model.start_datetime = Time.parse("January 2, 2007 12:00 AM")
101
+ output = calendar_date_select(:model, :start_datetime, :time => true, :object => nil)
102
+ output.should include(CalendarDateSelect.format_date(@model.start_datetime))
103
+ end
104
+
105
+ it "should regard :object parameter" do
106
+ @model.start_datetime = Time.parse("January 2, 2007 12:00 AM")
107
+ output = calendar_date_select(:lame_o, :start_datetime, :time => true, :object => @model)
108
+ output.should include(CalendarDateSelect.format_date(@model.start_datetime))
109
+ end
110
+
111
+ it "should respect parameters provided in default_options" do
112
+ new_options = CalendarDateSelect.default_options.merge(:popup => "force")
113
+ CalendarDateSelect.stub!(:default_options).and_return(new_options)
114
+ calendar_date_select_tag(:name, "").should include("popup:'force'")
115
+ end
116
+
117
+ it "should respect the :image option" do
118
+ output = calendar_date_select_tag(:name, "Some String", :image => "boogy.png")
119
+ output.should include("boogy.png")
120
+ end
121
+
122
+ it "should not pass the :image option as a javascript option" do
123
+ output = calendar_date_select_tag(:name, "Some String", :image => "boogy.png")
124
+ output.should_not include("image:")
125
+ end
126
+
127
+ describe "calendar_date_select_tag" do
128
+ it "should use the string verbatim when provided" do
129
+ output = calendar_date_select_tag(:name, "Some String")
130
+
131
+ output.should include("Some String")
132
+ end
133
+
134
+ it "should not render the time when time is false (or nil)" do
135
+ time = Time.parse("January 2, 2007 12:01:23 AM")
136
+ output = calendar_date_select_tag(:name, time, :time => false)
137
+
138
+ output.should_not match(/12:01 AM/)
139
+ output.should include(CalendarDateSelect.format_date(time.to_date))
140
+ end
141
+
142
+ it "should render the time when :time => true" do
143
+ time = Time.parse("January 2, 2007 12:01:23 AM")
144
+ output = calendar_date_select_tag(:name, time, :time => true)
145
+
146
+ output.should include(CalendarDateSelect.format_date(time))
147
+ end
148
+
149
+ it "should render the time when :time => 'mixed'" do
150
+ time = Time.parse("January 2, 2007 12:01:23 AM")
151
+ output = calendar_date_select_tag(:name, time, :time => 'mixed')
152
+
153
+ output.should include(CalendarDateSelect.format_date(time))
154
+ end
155
+ end
156
+ end
@@ -1,6 +1,9 @@
1
1
  require "rubygems"
2
2
 
3
- require 'test/unit'
3
+ require 'spec'
4
+
5
+ gem 'activesupport', ">= 2.2.0"
6
+ gem 'actionpack', ">= 2.2.0"
4
7
 
5
8
  require 'active_support'
6
9
  require 'action_pack'
@@ -9,10 +12,14 @@ require 'action_view'
9
12
 
10
13
  require 'ostruct'
11
14
 
15
+ ActionView::Helpers::InstanceTag.class_eval do
16
+ class << self; alias new_with_backwards_compatibility new; end
17
+ end
18
+
12
19
  $: << (File.dirname(__FILE__) + "/../lib")
13
20
  require "calendar_date_select"
14
21
 
15
- class Object
22
+ class String
16
23
  def to_regexp
17
24
  is_a?(Regexp) ? self : Regexp.new(Regexp.escape(self.to_s))
18
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calendar_date_select
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.12"
4
+ version: "1.13"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Harper
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-29 00:00:00 -07:00
12
+ date: 2008-11-30 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -43,6 +43,7 @@ files:
43
43
  - js_test/unittest.js
44
44
  - lib/calendar_date_select/calendar_date_select.rb
45
45
  - lib/calendar_date_select/includes_helper.rb
46
+ - lib/calendar_date_select/form_helpers.rb
46
47
  - lib/calendar_date_select.rb
47
48
  - Manifest.txt
48
49
  - MIT-LICENSE
@@ -70,9 +71,11 @@ files:
70
71
  - public/stylesheets/calendar_date_select/silver.css
71
72
  - Rakefile
72
73
  - Readme.txt
73
- - test/functional/calendar_date_select_test.rb
74
- - test/functional/helper_methods_test.rb
75
- - test/test_helper.rb
74
+ - spec/
75
+ - spec/calendar_date_select
76
+ - spec/calendar_date_select/calendar_date_select_spec.rb
77
+ - spec/calendar_date_select/form_helpers_spec.rb
78
+ - spec/spec_helper.rb
76
79
  has_rdoc: true
77
80
  homepage: http://code.google.com/p/calendardateselect/
78
81
  post_install_message:
@@ -96,9 +99,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
99
  requirements: []
97
100
 
98
101
  rubyforge_project: calendar_date_select
99
- rubygems_version: 1.3.0
102
+ rubygems_version: 1.3.1
100
103
  signing_key:
101
104
  specification_version: 2
102
105
  summary: ""
103
- test_files:
104
- - test/test_helper.rb
106
+ test_files: []
107
+
@@ -1,157 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '../test_helper.rb')
2
-
3
- class HelperMethodsTest < Test::Unit::TestCase
4
- include ActionView::Helpers::FormHelper
5
- include ActionView::Helpers::JavaScriptHelper
6
- include ActionView::Helpers::AssetTagHelper
7
- include ActionView::Helpers::TagHelper
8
- include ActionView::Helpers::FormTagHelper
9
-
10
- include CalendarDateSelect::FormHelper
11
-
12
- def setup
13
- @controller = ActionController::Base.new
14
- @request = OpenStruct.new
15
- @controller.request = @request
16
-
17
- @model = OpenStruct.new
18
- end
19
-
20
- def test_mixed_time__model_returns_date__should_render_without_time
21
- @model.start_datetime = Date.parse("January 2, 2007")
22
- output = calendar_date_select(:model, :start_datetime, :time => "mixed")
23
- assert_no_match(/12:00 AM/, output, "Shouldn't have outputted a time")
24
- end
25
-
26
- def test_mixed_time__model_returns_time__should_render_with_time
27
- @model.start_datetime = Time.parse("January 2, 2007 12:00 AM")
28
- output = calendar_date_select(:model, :start_datetime, :time => "mixed")
29
- assert_match(/12:00 AM/, output, "Should have outputted a time")
30
- end
31
-
32
- def test_time_true__model_returns_date__should_render_with_time
33
- @model.start_datetime = Date.parse("January 2, 2007")
34
- output = calendar_date_select(:model, :start_datetime, :time => "true")
35
- assert_match(/12:00 AM/, output, "Should have outputted a time")
36
- end
37
-
38
- def test_time_false__model_returns_time__should_render_without_time
39
- @model.start_datetime = Time.parse("January 2, 2007 12:00 AM")
40
- output = calendar_date_select(:model, :start_datetime)
41
- assert_no_match(/12:00 AM/, output, "Shouldn't have outputted a time")
42
- end
43
-
44
- def test__nil_model__shouldnt_populate_value
45
- @model = nil
46
- output = calendar_date_select(:model, :start_datetime)
47
-
48
- assert_no_match(/value/, output)
49
- end
50
-
51
- def test__vdc__should_auto_format_function
52
- @model.start_datetime = Time.parse("January 2, 2007 12:00 AM")
53
- output = calendar_date_select(:model,
54
- :start_datetime,
55
- :valid_date_check => "date < new Date()"
56
- )
57
- assert_match("valid_date_check:function(date) { return(date &lt; new Date()) }", output)
58
-
59
- output = calendar_date_select(:model,
60
- :start_datetime,
61
- :valid_date_check => "return(date < new Date())"
62
- )
63
- assert_match("valid_date_check:function(date) { return(date &lt; new Date()) }", output)
64
- output = calendar_date_select(:model,
65
- :start_datetime,
66
- :valid_date_check => "function(p) { return(date < new Date()) }"
67
- )
68
- assert_match("valid_date_check:function(p) { return(date &lt; new Date()) }", output)
69
- end
70
-
71
- def test__vdc__excluded_return__should_raise_error
72
- throw_message = ":valid_date_check function is missing a 'return' statement. Try something like: :valid_date_check => 'if (date > new(Date)) return true; else return false;'"
73
- assert_throws throw_message.to_sym do
74
- output = calendar_date_select(:model,
75
- :start_datetime,
76
- :valid_date_check => "date = 5; date < new Date());"
77
- )
78
- end
79
-
80
- assert_throws throw_message.to_sym do
81
- output = calendar_date_select(:model,
82
- :start_datetime,
83
- :valid_date_check => "function(p) { date = 5; date < new Date()); }"
84
- )
85
- end
86
- end
87
-
88
- def test__year_range__formats_correctly
89
- output = calendar_date_select(:model, :start_datetime)
90
- assert_match("year_range:10", output)
91
- output = calendar_date_select(:model, :start_datetime, :year_range => 2000..2010)
92
- assert_match("year_range:[2000, 2010]", output)
93
- output = calendar_date_select(:model, :start_datetime, :year_range => (15.years.ago..5.years.ago))
94
- assert_match("year_range:[#{15.years.ago.year}, #{5.years.ago.year}]", output)
95
- end
96
-
97
- def test__tag__formats_text_correctly_string
98
- time = "January 2, 2007 12:01:23 AM"
99
- output = calendar_date_select_tag(:name, time)
100
-
101
- assert_match(time, output, "Should have outputted a correctly formatted time")
102
- end
103
-
104
- def test__tag__formats_text_correctly_date
105
- time = Date.new(2007, 01, 02)
106
- output = calendar_date_select_tag(:name, time)
107
-
108
- assert_no_match(/12:01 AM/, output, "Should not have outputted a time")
109
- assert_match(CalendarDateSelect.format_date(time), output, "Should have outputted a correctly formatted time")
110
- end
111
-
112
- def test__tag__formats_text_correctly_time
113
- time = Time.parse("January 2, 2007 12:01:23 AM")
114
- output = calendar_date_select_tag(:name, time)
115
-
116
- assert_match(CalendarDateSelect.format_date(time), output, "Should have outputted a correctly formatted time")
117
- end
118
-
119
- def test__tag__formats_text_correctly_with_time_option
120
- time = Time.parse("January 2, 2007 12:01:23 AM")
121
- output = calendar_date_select_tag(:name, time, :time => true)
122
-
123
- assert_match(CalendarDateSelect.format_date(time), output, "Should have outputted a correctly formatted time")
124
- end
125
-
126
- def test__tag__formats_text_correctly_with_mixed_option
127
- time = Time.parse("January 2, 2007 12:01:23 AM")
128
- output = calendar_date_select_tag(:name, time, :time => 'mixed')
129
-
130
- assert_match(CalendarDateSelect.format_date(time), output, "Should have outputted a correctly formatted time")
131
- end
132
-
133
- def test__tag__formats_text_correctly_time_as_date
134
- time = Time.parse("January 2, 2007 12:01:23 AM")
135
- output = calendar_date_select_tag(:name, time, :time => false)
136
-
137
- assert_no_match(/12:01 AM/, output, "Should not have outputted a time")
138
- assert_match(time.strftime(CalendarDateSelect.date_format_string(false)), output, "Should have outputted a correctly formatted time")
139
- end
140
-
141
- def test__tag__formats_text_correctly_time_with_format
142
- time = Time.parse("January 2, 2007 12:01:00 AM")
143
- output = calendar_date_select_tag(:name, time, :format => "%Y-%m-%d")
144
-
145
- assert_no_match(/12:01 AM/, output, "Should not have outputted a time")
146
- assert_match('2007-01-02', output, "Should have outputted a correctly formatted time")
147
- end
148
-
149
- def test__nil_object_option__should_disregard
150
- @model.start_datetime = Time.parse("January 2, 2007 12:00 AM")
151
- output = calendar_date_select(:model, :start_datetime, :time => true, :object => nil)
152
- assert_match(CalendarDateSelect.format_date(@model.start_datetime), output, "Should have outputted a time")
153
- end
154
-
155
- end
156
-
157
-
@@ -1,15 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '../test_helper.rb')
2
-
3
- class HelperMethodsTest < Test::Unit::TestCase
4
- def setup
5
-
6
- end
7
-
8
- def test_has_time
9
- assert( ! CalendarDateSelect.has_time?("January 7, 2007"))
10
- assert(CalendarDateSelect.has_time?("January 7, 2007 5:50pm"))
11
- assert(CalendarDateSelect.has_time?("January 7, 2007 5:50 pm"))
12
- assert(CalendarDateSelect.has_time?("January 7, 2007 16:30 pm"))
13
- end
14
-
15
- end