diff --git a/src/calendar/calendar.css b/src/calendar/calendar.css index a322e8f..adc2873 100644 --- a/src/calendar/calendar.css +++ b/src/calendar/calendar.css @@ -189,6 +189,9 @@ div.right-calendar-month table td.right-calendar-day-disabled { } div.right-calendar-time { + border-top: 1px solid #ccc; + margin-top: .3em; + padding-top: .5em; text-align: center; } div.right-calendar-time select { diff --git a/src/calendar/calendar.js b/src/calendar/calendar.js index c26c2c3..66e73dd 100644 --- a/src/calendar/calendar.js +++ b/src/calendar/calendar.js @@ -19,7 +19,8 @@ var Calendar = new Class(Observer, { numberOfMonths: 1, // a number or [x, y] greed definition timePeriod: 1, // the timepicker minimal periods (in minutes, might be bigger than 60) checkTags: '*', - relName: 'calendar' + relName: 'calendar', + twentyFourHour: true }, Formats: { @@ -91,7 +92,10 @@ var Calendar = new Class(Observer, { // format catching up this.options.format = (this.constructor.Formats[this.options.format] || this.options.format).trim(); - + if (this.options.timePeriod < 60) { + this.inspectFormat(this.options); + } + return this; }, diff --git a/src/calendar/calendar/builder.js b/src/calendar/calendar/builder.js index 6157eb5..7ea2789 100644 --- a/src/calendar/calendar/builder.js +++ b/src/calendar/calendar/builder.js @@ -155,27 +155,67 @@ Calendar.include({ buildTime: function() { if (!this.options.showTime) return; + var now = new Date(); this.hours = $E('select'); this.minutes = $E('select'); - var minute_options_number = 60 / this.options.timePeriod; - + + var minute_selected = false; + var first_minute_option_properties; (minute_options_number == 0 ? 1 : minute_options_number).times(function(i) { i = i * this.options.timePeriod; var c = i < 10 ? '0'+i : i; - this.minutes.insert($E('option', {value: i, html: c})); + var option_properties = {value: i, html: c}; + if (!first_minute_option_properties) { + first_minute_option_properties = option_properties; + } + if (!minute_selected && i >= now.getMinutes()) { + minute_selected = true; + option_properties['selected'] = 'selected'; + } + this.minutes.insert($E('option', option_properties)); }, this); - - var hour_options_number = this.options.timePeriod > 59 ? (24 * 60 / this.options.timePeriod) : 24; + + // roll over the hour when the minute falls within the final period + if (!minute_selected) { + first_minute_option_properties['selected'] = 'selected'; + } + + var hour_basis = this.options.twentyFourHour ? 24 : 12; + var hour_options_number = this.options.timePeriod > 59 ? (24 * 60 / this.options.timePeriod) : hour_basis; + + var hour_selected = false; + var hour_to_select = now.getHours() + (minute_selected ? 0 : 1); (hour_options_number == 0 ? 1 : hour_options_number).times(function(i) { if (this.options.timePeriod > 59) i = (i * this.options.timePeriod / 60).floor(); - var c = i < 10 ? '0'+i : i; - this.hours.insert($E('option', {value: i, html: c})); + var c = i < 10 ? '0' + i : i; + var option_properties = {value: c, html: c == 0 && !this.options.twentyFourHour ? 12 : c}; + if ((this.options.twentyFourHour && i == hour_to_select) + || (!this.options.twentyFourHour && i == (hour_to_select % 12)) + || (!hour_selected && i > hour_to_select)) { + hour_selected = true; + option_properties['selected'] = 'selected'; + } + this.hours.insert($E('option', option_properties)); }, this); - - $E('div', {'class': 'right-calendar-time'}).insertTo(this.element) - .insert([this.hours, document.createTextNode(":"), this.minutes]); + + var children = $A([this.hours, document.createTextNode(":"), this.minutes]); + if (!this.options.twentyFourHour) { + var meridian = $E('select'); + var entries = this.options.format.search(/%P/) >= 0 ? ['am', 'pm'] : ['AM', 'PM']; + entries.each(function(entry, i) { + var option_properties = {value: entry.toLowerCase(), html: entry}; + if ((hour_to_select >= 12 && option_properties.value == 'pm') + || (hour_to_select < 12 && option_properties.value == 'am')) { + option_properties['selected'] = 'selected'; + } + meridian.insert($E('option', option_properties)); + }); + children.push(meridian); + this.meridian = meridian; + } + $E('div', {'class': 'right-calendar-time'}).insertTo(this.element).insert(children); }, // builds the bottom buttons block diff --git a/src/calendar/calendar/events.js b/src/calendar/calendar/events.js index cbbf357..10b6ebd 100644 --- a/src/calendar/calendar/events.js +++ b/src/calendar/calendar/events.js @@ -76,6 +76,9 @@ Calendar.include({ if (this.hours) { this.hours.on('change', this.setTime.bind(this)); this.minutes.on('change', this.setTime.bind(this)); + if (!this.options.twentyFourHour) { + this.meridian.on('change', this.setTime.bind(this)); + } } // connecting the bottom buttons @@ -99,8 +102,11 @@ Calendar.include({ }, setTime: function() { - this.date.setHours(this.hours.value); + var hour = new Number(this.hours.value) + + (!this.options.twentyFourHour && this.meridian.value == 'pm' ? 12 : 0); + this.date.setHours(hour); this.date.setMinutes(this.minutes.value); + return this.select(this.date); } diff --git a/src/calendar/calendar/formats.js b/src/calendar/calendar/formats.js index 7ce4941..1ca0504 100644 --- a/src/calendar/calendar/formats.js +++ b/src/calendar/calendar/formats.js @@ -26,6 +26,7 @@ * Copyright (C) 2009 Nikolay V. Nemshilov aka St. */ Calendar.include({ + /** * Parses out the given string based on the current date formatting * @@ -136,5 +137,17 @@ Calendar.include({ } return result; + }, + + /** + * Inspects the format string and updates any corresponding options. + * + * @param Associative Array mandatory options + */ + inspectFormat: function(options) { + if (options.format.search(/%[IL]/) >= 0) { + options.twentyFourHour = false; + } } + }); \ No newline at end of file diff --git a/test/calendar/index.html b/test/calendar/index.html index 48958f1..94c41c6 100644 --- a/test/calendar/index.html +++ b/test/calendar/index.html @@ -22,7 +22,7 @@

Some calendar use-cases

- +

Single

@@ -146,7 +146,48 @@ // ]]>

- + +

With Meridian Dropdown Due to 12 Hour Format

+

+ 12 hour format, with a meridian dropdown menu that is sensitive to the time format that was supplied to the + Calendar options. Note that the time should reflect the time that the page was loaded. +

+

+ + + + +

+ +

Future Time Period

+

+ Showing calendars configured with different time periods. The calendar should automatically pick + the time period that is equivalent to now or as close as possible in the future. +

+

+ + + + + + +

Just Some Text To Make The Page Long Enough