From 4beb4d2fd9d8472a6fb92ea6c4bfd2463f85e460 Mon Sep 17 00:00:00 2001 From: Rob Godfrey <102856686+robertgodfrey@users.noreply.github.com> Date: Fri, 31 Mar 2023 17:10:34 -1000 Subject: [PATCH 1/6] Change time to 12-hr format --- src/css/style.scss | 11 +++++++++-- src/js/picker-base.js | 26 +++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/css/style.scss b/src/css/style.scss index 489142c..f44f60e 100644 --- a/src/css/style.scss +++ b/src/css/style.scss @@ -47,14 +47,21 @@ div.datetime-container { button > span { display: inline-block; margin: 0 -2px; } button span.week-day{ text-align: right; font-size: 14px; } - button span.month-day, button span.hours { + button span.month-day { width: 45px; text-align: center; font-size: 36px; } + button span.hours { + text-align: center; + font-size: 36px; + } button span.month-year { text-align: left; font-size: 16px; } span.month-year span { position: relative; top: 2px; font-weight: bold; font-size: 14px; } - button span.minutes { font-size: 18px; } + button span.minutes { + font-size: 18px; + margin-left: 2px; + } } diff --git a/src/js/picker-base.js b/src/js/picker-base.js index 11bda47..f63505b 100644 --- a/src/js/picker-base.js +++ b/src/js/picker-base.js @@ -568,8 +568,12 @@ export function PickerBase() { } if( if_hour ) { - let arr = o.text.split(':'); - o.hour = arr[0]; + const arr = o.text.split(/:| /); + if (arr[2] == 'AM') { + o.hour = arr[0] == 12 ? 0 : arr[0]; + } else { + o.hour = arr[0] == 12 ? 12 : parseInt(arr[0]) + 12; + } o.minute = arr[1]; // [ o.hour, o.minute ] = o.text.split(':'); } else { @@ -617,12 +621,20 @@ export function PickerBase() { const button_time = div.querySelector( 'button.time' ); if( button_time ) { const time_coll = button_time.querySelectorAll( 'span' ); - const hours = time_coll[ 0 ]; - const minutes = time_coll[ 1 ]; - // const [ hours, minutes ] = button_time.querySelectorAll( 'span' ); + const displayTime = time_coll[ 0 ]; + const displayAmPm = time_coll[ 1 ]; + let amPm = ''; + let displayHours = ''; + if (date.getHours() >= 12) { + amPm = 'PM'; + displayHours = date.getHours() == 12 ? 12 : date.getHours() - 12; + } else { + amPm = 'AM'; + displayHours = date.getHours() == 0 ? 12 : date.getHours(); + } - hours.textContent = ( '0' + date.getHours() ).slice( -2 ); - minutes.textContent = `:${ ( '0' + date.getMinutes() ).slice( -2 ) }`; + displayTime.textContent = `${displayHours}:${ ( '0' + date.getMinutes() ).slice( -2 ) }`; + displayAmPm.textContent = amPm; } From 2e23b26e123d855fa3ca3a6cb321dc5696085067 Mon Sep 17 00:00:00 2001 From: Rob Godfrey <102856686+robertgodfrey@users.noreply.github.com> Date: Fri, 31 Mar 2023 17:20:10 -1000 Subject: [PATCH 2/6] Add option to set hour range and time increment --- src/js/date-time-picker.js | 5 ++- src/js/picker-base.js | 74 ++++++++++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/js/date-time-picker.js b/src/js/date-time-picker.js index 21697c0..0909aa6 100644 --- a/src/js/date-time-picker.js +++ b/src/js/date-time-picker.js @@ -53,9 +53,12 @@ export function DateTimePicker( id, settings = {} ) { const start_date = ( settings.start_date ) ? settings.start_date : null; const first_date = ( settings.first_date ) ? settings.first_date : null; const last_date = ( settings.last_date ) ? settings.last_date : null; + const start_hour = ( settings.start_hour ) ? settings.start_hour : null; + const end_hour = ( settings.end_hour ) ? settings.end_hour : null; + const time_increment = ( settings.time_increment ) ? settings.time_increment : null; const first_day_no = ( typeof settings.first_day_no !== 'undefined' ) ? settings.first_day_no : 0; const styles = ( settings.styles ) ? settings.styles : {}; - this.setStartPickerProps( id, start_date, first_date, last_date, first_day_no ); + this.setStartPickerProps( id, start_date, first_date, last_date, first_day_no, start_hour, end_hour, time_increment ); // Start date diff --git a/src/js/picker-base.js b/src/js/picker-base.js index f63505b..baa3c23 100644 --- a/src/js/picker-base.js +++ b/src/js/picker-base.js @@ -158,6 +158,9 @@ export function PickerBase() { * - `end_date` must always be less than `last_date`. * - `start_date` plus `min_range` must always be less or equal than `end_date`; * - `end_date` minus `min_range` must always be greater or equal than `start_date`; + * - `start_hour` must be a number between 0 and 23. + * - `end_hour` must be a number between 1 and 24, and greater than end hour. + * - `time_increment` must be a number between 5 and 360. * * It's used by both {@link module:js/picker-base.PickerBase#selectDay|selectDay} * and {@link module:js/picker-base.PickerBase#selectHour|selectHour} methods. @@ -208,6 +211,25 @@ export function PickerBase() { } } } + + // Make sure the hours fall within specified range + if (this.start_hour) { + if (this.start_hour < 0) { + this.start_hour = 0; + } else if (this.start_hour > 23) { + this.start_hour = 23; + } + } + if (this.end_hour) { + if (this.end_hour < 1) { + this.start_hour = 1; + } else if (this.start_hour > 24) { + this.start_hour = 24; + } + if (this.end_hour <= this.start_hour) { + this.end_hour++; + } + } } @@ -575,7 +597,6 @@ export function PickerBase() { o.hour = arr[0] == 12 ? 12 : parseInt(arr[0]) + 12; } o.minute = arr[1]; - // [ o.hour, o.minute ] = o.text.split(':'); } else { o.prev_month = t.classList.contains('prev-month'); o.next_month = t.classList.contains('next-month'); @@ -841,12 +862,16 @@ export function PickerBase() { * @param {Date|string|null} first_date_setting First selectable date from settings * @param {Date|string|null} last_date_setting Last selectable date from settings * @param {number} first_day_no Day the week must start with. Similarly to the returned values of `Date.getDate` method, accepted range values are 0-6 where 0 means Sunday, 1 means Monday and so on + * @param {number} start_hour The first hour displayed in the time selector. Accepted range values are 0-23 where 0 means 00:00 (12AM) and 23 means 23:00 (11PM) + * @param {number} end_hour The last hour displayed in the time selector. Accepted range values are 1-24 where 1 means 01:00 (1AM) and 24 means 24:00 (12AM) + * @param {number} time_increment The length of time in minutes between times displayed in the time selector. E.g. 30 -> 30 minutes, 60 -> 1 hour. Accepted range values are 5-360 * * @see {@link module:js/picker-base.PickerBase~getDateBetween|getDateBetween} * @see {@link module:js/picker-base.PickerBase~roundMinutes|roundMinutes} * @see {@link module:js/picker-base.PickerBase~setDaysOrder|setDaysOrder} */ - this.setStartPickerProps = function( id, start_date_setting, first_date_setting, last_date_setting, first_day_no ) { + this.setStartPickerProps = function( id, start_date_setting, first_date_setting, last_date_setting, + first_day_no, start_hour, end_hour, time_increment) { const el = document.getElementById( id ); if( el == null || el.nodeName != 'DIV' ) { throw new Error( `Does div#${ id } exist? Please, check your HTML code` ); @@ -885,6 +910,9 @@ export function PickerBase() { this.start_date = start_date; this.first_date = first_date; this.last_date = last_date; + this.start_hour = start_hour; + this.end_hour = end_hour; + this.time_increment = time_increment; } @@ -1133,25 +1161,43 @@ export function PickerBase() { * @see {@link module:js/picker-base.PickerBase#addOnSelectEvent|addOnSelectEvent} */ this.showTimePicker = function( picker, day ) { - const hours = [ - '00:00', '00:30', '01:00', '01:30', '02:00', '02:30', '03:00', '03:30', '04:00', '04:30', '05:00', '05:30', '06:00', '06:30', '07:00', '07:30', - '08:00', '08:30', '09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00', '15:30', - '16:00', '16:30', '17:00', '17:30', '18:00', '18:30', '19:00', '19:30', '20:00', '20:30', '21:00', '21:30', '22:00', '22:30', '23:00', '23:30' - ]; + const times = []; + // Populate 'times' array with specified times + const start = this.start_hour * 60|| 0; + const end = this.end_hour * 60 || 1440; + const time_inc = this.time_increment || 30; + for (let i = start; i < end; i += time_inc) { + let hours = Math.floor(i / 60); + let minutes = i % 60; + let am_pm = hours >= 12 ? 'PM' : 'AM'; + if (hours > 12) { + hours -= 12; + } else if (hours == 0) { + hours = 12; + } + minutes = minutes < 10 ? '0' + minutes : minutes; + times.push(`${hours}:${minutes} ${am_pm}`); + } let i = 0, html = '', class_name; - // Nine rows - for( let j = 1; j < 9; j++ ) { + // If 12 times or less, use 4 columns. Otherwise, use 6 + const numCols = times.length > 12 ? 6 : 3; + + // Find number of rows needed + const numRows = Math.ceil(times.length / numCols) + 1; + + // Rows + for( let j = 1; j < numRows; j++ ) { html += ""; - // Six columns - for( i = 1 * i ; i < 6 * j; i++ ) { - if( hours[ i ] ) { + // Columns + for( i = 1 * i ; i < numCols * j; i++ ) { + if( times[ i ] ) { class_name = '' - class_name = this.getHourClassName( hours[ i ], day ); + class_name = this.getHourClassName( times[ i ], day ); - html += `${ hours[ i ] }`; + html += `${ times[ i ] }`; } else { html += ``; } From eebb60e888800ced99495273ba73e8e174822a57 Mon Sep 17 00:00:00 2001 From: Rob Godfrey <102856686+robertgodfrey@users.noreply.github.com> Date: Fri, 31 Mar 2023 18:39:59 -1000 Subject: [PATCH 3/6] Update error checking --- .gitignore | 2 ++ src/js/picker-base.js | 77 +++++++++++++++++++++++-------------------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 178d2cf..bf852bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /node_modules /dist /docs +.idea +.DS_STORE \ No newline at end of file diff --git a/src/js/picker-base.js b/src/js/picker-base.js index baa3c23..107993f 100644 --- a/src/js/picker-base.js +++ b/src/js/picker-base.js @@ -158,9 +158,6 @@ export function PickerBase() { * - `end_date` must always be less than `last_date`. * - `start_date` plus `min_range` must always be less or equal than `end_date`; * - `end_date` minus `min_range` must always be greater or equal than `start_date`; - * - `start_hour` must be a number between 0 and 23. - * - `end_hour` must be a number between 1 and 24, and greater than end hour. - * - `time_increment` must be a number between 5 and 360. * * It's used by both {@link module:js/picker-base.PickerBase#selectDay|selectDay} * and {@link module:js/picker-base.PickerBase#selectHour|selectHour} methods. @@ -184,52 +181,33 @@ export function PickerBase() { const end_date_ms = this.end_date.getTime(); // start mode - if( mode == 'start' ) { - if( ( start_date_ms + this.min_range ) >= end_date_ms ) { - if( ( start_date_ms + this.min_range ) >= last_date_ms ) { - this.start_date.setTime( last_date_ms - this.min_range ); + if (mode == 'start') { + if ((start_date_ms + this.min_range) >= end_date_ms) { + if ((start_date_ms + this.min_range) >= last_date_ms) { + this.start_date.setTime(last_date_ms - this.min_range); } - this.end_date.setTime( this.start_date.getTime() + this.min_range ); - this.printDateAndTime( this.end_container, this.end_date ); + this.end_date.setTime(this.start_date.getTime() + this.min_range); + this.printDateAndTime(this.end_container, this.end_date); } } // end mode else { - if( ( end_date_ms - this.min_range ) <= start_date_ms ) { - if( ( end_date_ms - this.min_range ) <= first_date_ms ) { - this.end_date.setTime( first_date_ms + this.min_range ); + if ((end_date_ms - this.min_range) <= start_date_ms) { + if ((end_date_ms - this.min_range) <= first_date_ms) { + this.end_date.setTime(first_date_ms + this.min_range); } - this.start_date.setTime( this.end_date.getTime() - this.min_range ); - this.printDateAndTime( this.start_container, this.start_date ); + this.start_date.setTime(this.end_date.getTime() - this.min_range); + this.printDateAndTime(this.start_container, this.start_date); } - if( end_date_ms >= last_date_ms ) { - this.end_date.setHours( this.last_date.getHours(), this.last_date.getMinutes(), 0, 0 ); + if (end_date_ms >= last_date_ms) { + this.end_date.setHours(this.last_date.getHours(), this.last_date.getMinutes(), 0, 0); } } } - - // Make sure the hours fall within specified range - if (this.start_hour) { - if (this.start_hour < 0) { - this.start_hour = 0; - } else if (this.start_hour > 23) { - this.start_hour = 23; - } - } - if (this.end_hour) { - if (this.end_hour < 1) { - this.start_hour = 1; - } else if (this.start_hour > 24) { - this.start_hour = 24; - } - if (this.end_hour <= this.start_hour) { - this.end_hour++; - } - } } @@ -865,6 +843,7 @@ export function PickerBase() { * @param {number} start_hour The first hour displayed in the time selector. Accepted range values are 0-23 where 0 means 00:00 (12AM) and 23 means 23:00 (11PM) * @param {number} end_hour The last hour displayed in the time selector. Accepted range values are 1-24 where 1 means 01:00 (1AM) and 24 means 24:00 (12AM) * @param {number} time_increment The length of time in minutes between times displayed in the time selector. E.g. 30 -> 30 minutes, 60 -> 1 hour. Accepted range values are 5-360 + * @param {boolean} military_time * * @see {@link module:js/picker-base.PickerBase~getDateBetween|getDateBetween} * @see {@link module:js/picker-base.PickerBase~roundMinutes|roundMinutes} @@ -906,6 +885,34 @@ export function PickerBase() { setDaysOrder( first_day_no ); + // Make sure set hours fall within specified range + if (start_hour) { + if (start_hour < 0) { + start_hour = 0; + } else if (start_hour > 23) { + start_hour = 23; + } + } + if (end_hour) { + if (end_hour < 1) { + end_hour = 1; + } else if (end_hour > 24) { + end_hour = 24; + } + if (end_hour <= start_hour) { + end_hour = start_hour + 1; + } + } + + // Make sure time_increment is in specified range + if (time_increment) { + if (time_increment < 5) { + time_increment = 5; + } else if (time_increment > 360) { + time_increment = 360; + } + } + this.start_container = el; this.start_date = start_date; this.first_date = first_date; From f4c5b89dca830b751fb3cb24ab16054df65b6dda Mon Sep 17 00:00:00 2001 From: Rob Godfrey <102856686+robertgodfrey@users.noreply.github.com> Date: Fri, 31 Mar 2023 19:01:45 -1000 Subject: [PATCH 4/6] Add time control in DateTimeRangePicker --- src/js/date-time-range-picker.js | 5 ++++- src/js/picker-base.js | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/js/date-time-range-picker.js b/src/js/date-time-range-picker.js index 7963878..618b6cc 100644 --- a/src/js/date-time-range-picker.js +++ b/src/js/date-time-range-picker.js @@ -56,9 +56,12 @@ export function DateTimeRangePicker( start_id, end_id, settings = {} ) { const start_date = ( settings.start_date ) ? settings.start_date : null; const first_date = ( settings.first_date ) ? settings.first_date : null; const last_date = ( settings.last_date ) ? settings.last_date : null; + const start_hour = ( settings.start_hour ) ? settings.start_hour : null; + const end_hour = ( settings.end_hour ) ? settings.end_hour : null; + const time_increment = ( settings.time_increment ) ? settings.time_increment : null; const first_day_no = ( typeof settings.first_day_no !== 'undefined' ) ? settings.first_day_no : 0; const styles = ( settings.styles ) ? settings.styles : {}; - this.setStartPickerProps( start_id, start_date, first_date, last_date, first_day_no ); + this.setStartPickerProps( start_id, start_date, first_date, last_date, first_day_no, start_hour, end_hour, time_increment ); const end_date = ( settings.end_date ) ? settings.end_date : null; this.setEndPickerProps( end_id, end_date ); diff --git a/src/js/picker-base.js b/src/js/picker-base.js index 107993f..67f8d6c 100644 --- a/src/js/picker-base.js +++ b/src/js/picker-base.js @@ -843,7 +843,6 @@ export function PickerBase() { * @param {number} start_hour The first hour displayed in the time selector. Accepted range values are 0-23 where 0 means 00:00 (12AM) and 23 means 23:00 (11PM) * @param {number} end_hour The last hour displayed in the time selector. Accepted range values are 1-24 where 1 means 01:00 (1AM) and 24 means 24:00 (12AM) * @param {number} time_increment The length of time in minutes between times displayed in the time selector. E.g. 30 -> 30 minutes, 60 -> 1 hour. Accepted range values are 5-360 - * @param {boolean} military_time * * @see {@link module:js/picker-base.PickerBase~getDateBetween|getDateBetween} * @see {@link module:js/picker-base.PickerBase~roundMinutes|roundMinutes} From d2ff05b25cf08122bf76e9701a5adaa0cb5f2ac9 Mon Sep 17 00:00:00 2001 From: Rob Godfrey <102856686+robertgodfrey@users.noreply.github.com> Date: Fri, 31 Mar 2023 19:13:32 -1000 Subject: [PATCH 5/6] Update .gitignore --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index bf852bc..178d2cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ /node_modules /dist /docs -.idea -.DS_STORE \ No newline at end of file From 212f92938c78072897945dc8ebb35c6faa370bfb Mon Sep 17 00:00:00 2001 From: Rob Godfrey <102856686+robertgodfrey@users.noreply.github.com> Date: Sat, 1 Apr 2023 08:28:41 -1000 Subject: [PATCH 6/6] Add time parsing to enable disabled times --- src/js/picker-base.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/js/picker-base.js b/src/js/picker-base.js index 67f8d6c..45c17d8 100644 --- a/src/js/picker-base.js +++ b/src/js/picker-base.js @@ -323,11 +323,14 @@ export function PickerBase() { this.getHourClassName = function( hour, date ) { const selected_hour = ( '0' + date.getHours() ).slice( -2 ) + ':' + ( '0' + date.getMinutes() ).slice( -2 ); - const arr = hour.split( ':' ); - const h = arr[ 0 ]; - const m = arr[ 1 ]; - // const [ h, m ] = hour.split( ':' ); - + const arr = hour.split(/:| /); + const m = arr[1]; + let h = ''; + if (arr[2] == 'AM') { + h = arr[0] == 12 ? 0 : arr[0]; + } else { + h = arr[0] == 12 ? 12 : parseInt(arr[0]) + 12; + } const _curr_day = new Date( date ); _curr_day.setHours( h, m, 0, 0 );