/** * ===================================================================================================================== * includes/__js/cal/wpbc_cal.js * ===================================================================================================================== */ /** * Order or child booking resources saved here: _wpbc.booking__get_param_value( resource_id, * 'resources_id_arr__in_dates' ) [2,10,12,11] */ /** * How to check booked times on specific date: ? * _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21'); console.log( _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[2].booked_time_slots.merged_seconds, _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[10].booked_time_slots.merged_seconds, _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[11].booked_time_slots.merged_seconds, _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[12].booked_time_slots.merged_seconds ); * OR console.log( _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[2].booked_time_slots.merged_readable, _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[10].booked_time_slots.merged_readable, _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[11].booked_time_slots.merged_readable, _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[12].booked_time_slots.merged_readable ); * */ /** * Days selection: * wpbc_calendar__unselect_all_dates( resource_id ); * * var resource_id = 1; * Example 1: var num_selected_days = wpbc_auto_select_dates_in_calendar( resource_id, '2024-05-15', * '2024-05-25' ); Example 2: var num_selected_days = wpbc_auto_select_dates_in_calendar( resource_id, * ['2024-05-09','2024-05-19','2024-05-25'] ); * */ /** * C A L E N D A R --------------------------------------------------------------------------------------------------- */ /** * Show WPBC Calendar * * @param resource_id - resource ID * @returns {boolean} */ function wpbc_calendar_show( resource_id ){ // If no calendar HTML tag, then exit if ( 0 === jQuery( '#calendar_booking' + resource_id ).length ){ return false; } // If the calendar with the same Booking resource is activated already, then exit. But in Elementor the class can be stale, so verify instance. if ( jQuery( '#calendar_booking' + resource_id ).hasClass( 'hasDatepick' ) ) { var existing_inst = null; try { existing_inst = jQuery.datepick._getInst( jQuery( '#calendar_booking' + resource_id ).get( 0 ) ); } catch ( e ) { existing_inst = null; } if ( existing_inst ) { return false; } // Stale marker: remove and continue with init. jQuery( '#calendar_booking' + resource_id ).removeClass( 'hasDatepick' ); } // ----------------------------------------------------------------------------------------------------------------- // Days selection // ----------------------------------------------------------------------------------------------------------------- var local__is_range_select = false; var local__multi_days_select_num = 365; // multiple | fixed if ( 'dynamic' === _wpbc.calendar__get_param_value( resource_id, 'days_select_mode' ) ){ local__is_range_select = true; local__multi_days_select_num = 0; } if ( 'single' === _wpbc.calendar__get_param_value( resource_id, 'days_select_mode' ) ){ local__multi_days_select_num = 0; } // ----------------------------------------------------------------------------------------------------------------- // Min - Max days to scroll/show // ----------------------------------------------------------------------------------------------------------------- var local__min_date = 0; local__min_date = new Date( _wpbc.get_other_param( 'today_arr' )[ 0 ], (parseInt( _wpbc.get_other_param( 'today_arr' )[ 1 ] ) - 1), _wpbc.get_other_param( 'today_arr' )[ 2 ], 0, 0, 0 ); // FixIn: 9.9.0.17. //console.log( local__min_date ); var local__max_date = _wpbc.calendar__get_param_value( resource_id, 'booking_max_monthes_in_calendar' ); //local__max_date = new Date(2024, 5, 28); It is here issue of not selectable dates, but some dates showing in calendar as available, but we can not select it. //// Define last day in calendar (as a last day of month (and not date, which is related to actual 'Today' date). //// E.g. if today is 2023-09-25, and we set 'Number of months to scroll' as 5 months, then last day will be 2024-02-29 and not the 2024-02-25. // var cal_last_day_in_month = jQuery.datepick._determineDate( null, local__max_date, new Date() ); // cal_last_day_in_month = new Date( cal_last_day_in_month.getFullYear(), cal_last_day_in_month.getMonth() + 1, 0 ); // local__max_date = cal_last_day_in_month; // FixIn: 10.0.0.26. // Get start / end dates from the Booking Calendar shortcode. Example: [booking calendar_dates_start='2026-01-01' calendar_dates_end='2026-12-31' resource_id=1] // FixIn: 10.13.1.4. if ( false !== wpbc_calendar__get_dates_start( resource_id ) ) { local__min_date = wpbc_calendar__get_dates_start( resource_id ); // E.g. - local__min_date = new Date( 2025, 0, 1 ); } if ( false !== wpbc_calendar__get_dates_end( resource_id ) ) { local__max_date = wpbc_calendar__get_dates_end( resource_id ); // E.g. - local__max_date = new Date( 2025, 11, 31 ); } // In case we edit booking in past or have specific parameter in URL. if ( ( location.href.indexOf('page=wpbc-new') != -1 ) && ( ( location.href.indexOf('booking_hash') != -1 ) // Comment this line for ability to add booking in past days at Booking > Add booking page. || ( location.href.indexOf('allow_past') != -1 ) // FixIn: 10.7.1.2. ) ){ // local__min_date = null; // FixIn: 10.14.1.4. local__min_date = new Date( _wpbc.get_other_param( 'time_local_arr' )[0], ( parseInt( _wpbc.get_other_param( 'time_local_arr' )[1] ) - 1), _wpbc.get_other_param( 'time_local_arr' )[2], _wpbc.get_other_param( 'time_local_arr' )[3], _wpbc.get_other_param( 'time_local_arr' )[4], 0 ); local__max_date = null; } var local__start_weekday = _wpbc.calendar__get_param_value( resource_id, 'booking_start_day_weeek' ); var local__number_of_months = parseInt( _wpbc.calendar__get_param_value( resource_id, 'calendar_number_of_months' ) ); jQuery( '#calendar_booking' + resource_id ).text( '' ); // Remove all HTML in calendar tag // ----------------------------------------------------------------------------------------------------------------- // Show calendar // ----------------------------------------------------------------------------------------------------------------- jQuery('#calendar_booking'+ resource_id).datepick( { beforeShowDay: function ( js_date ){ return wpbc__calendar__apply_css_to_days( js_date, {'resource_id': resource_id}, this ); }, onSelect: function ( string_dates, js_dates_arr ){ /** * string_dates = '23.08.2023 - 26.08.2023' * | '23.08.2023 - 23.08.2023' | * '19.09.2023, 24.08.2023, 30.09.2023' * js_dates_arr = range: [ Date (Aug 23 2023), * Date (Aug 25 2023)] | multiple: [ * Date(Oct 24 2023), Date(Oct 20 2023), Date(Oct * 16 2023) ] */ return wpbc__calendar__on_select_days( string_dates, {'resource_id': resource_id}, this ); }, onHover: function ( string_date, js_date ){ return wpbc__calendar__on_hover_days( string_date, js_date, {'resource_id': resource_id}, this ); }, onChangeMonthYear: function ( year, real_month, js_date__1st_day_in_month ){ }, showOn : 'both', numberOfMonths: local__number_of_months, stepMonths : 1, // prevText : '«', // nextText : '»', prevText : '‹', nextText : '›', dateFormat : 'dd.mm.yy', changeMonth : false, changeYear : false, minDate : local__min_date, maxDate : local__max_date, // '1Y', // minDate: new Date(2020, 2, 1), maxDate: new Date(2020, 9, 31), // Ability to set any start and end date in calendar showStatus : false, multiSeparator : ', ', closeAtTop : false, firstDay : local__start_weekday, gotoCurrent : false, hideIfNoPrevNext: true, multiSelect : local__multi_days_select_num, rangeSelect : local__is_range_select, // showWeeks: true, useThemeRoller: false } ); // ----------------------------------------------------------------------------------------------------------------- // Clear today date highlighting // ----------------------------------------------------------------------------------------------------------------- setTimeout( function (){ wpbc_calendars__clear_days_highlighting( resource_id ); }, 500 ); // FixIn: 7.1.2.8. // ----------------------------------------------------------------------------------------------------------------- // Scroll calendar to specific month // ----------------------------------------------------------------------------------------------------------------- var start_bk_month = _wpbc.calendar__get_param_value( resource_id, 'calendar_scroll_to' ); if ( false !== start_bk_month ){ wpbc_calendar__scroll_to( resource_id, start_bk_month[ 0 ], start_bk_month[ 1 ] ); } } /** * Apply CSS to calendar date cells * * @param date - JavaScript Date Obj: Mon Dec 11 2023 00:00:00 * GMT+0200 (Eastern European Standard Time) * @param calendar_params_arr - Calendar Settings Object: { * "resource_id": 4 * } * @param datepick_this - this of datepick Obj * @returns {(*|string)[]|(boolean|string)[]} - [ {true -available | false - unavailable}, 'CSS classes for * calendar day cell' ] */ function wpbc__calendar__apply_css_to_days( date, calendar_params_arr, datepick_this ){ var today_date = new Date( _wpbc.get_other_param( 'today_arr' )[ 0 ], (parseInt( _wpbc.get_other_param( 'today_arr' )[ 1 ] ) - 1), _wpbc.get_other_param( 'today_arr' )[ 2 ], 0, 0, 0 ); // Today JS_Date_Obj. var class_day = wpbc__get__td_class_date( date ); // '1-9-2023' var sql_class_day = wpbc__get__sql_class_date( date ); // '2023-01-09' var resource_id = ( 'undefined' !== typeof(calendar_params_arr[ 'resource_id' ]) ) ? calendar_params_arr[ 'resource_id' ] : '1'; // '1' // Get Selected dates in calendar var selected_dates_sql = wpbc_get__selected_dates_sql__as_arr( resource_id ); // Get Data -------------------------------------------------------------------------------------------------------- var date_bookings_obj = _wpbc.bookings_in_calendar__get_for_date( resource_id, sql_class_day ); // Array with CSS classes for date --------------------------------------------------------------------------------- var css_classes__for_date = []; css_classes__for_date.push( 'sql_date_' + sql_class_day ); // 'sql_date_2023-07-21' css_classes__for_date.push( 'cal4date-' + class_day ); // 'cal4date-7-21-2023' css_classes__for_date.push( 'wpbc_weekday_' + date.getDay() ); // 'wpbc_weekday_4' // Define Selected Check In/Out dates in TD ----------------------------------------------------------------------- if ( ( selected_dates_sql.length ) //&& ( selected_dates_sql[ 0 ] !== selected_dates_sql[ (selected_dates_sql.length - 1) ] ) ){ if ( sql_class_day === selected_dates_sql[ 0 ] ){ css_classes__for_date.push( 'selected_check_in' ); css_classes__for_date.push( 'selected_check_in_out' ); } if ( ( selected_dates_sql.length > 1 ) && ( sql_class_day === selected_dates_sql[ (selected_dates_sql.length - 1) ] ) ) { css_classes__for_date.push( 'selected_check_out' ); css_classes__for_date.push( 'selected_check_in_out' ); } } var is_day_selectable = false; // If something not defined, then this date closed --------------------------------------------------------------- // FixIn: 10.12.4.6. if ( (false === date_bookings_obj) || ('undefined' === typeof (date_bookings_obj[resource_id])) ) { css_classes__for_date.push( 'date_user_unavailable' ); return [ is_day_selectable, css_classes__for_date.join(' ') ]; } // ----------------------------------------------------------------------------------------------------------------- // date_bookings_obj - Defined. Dates can be selectable. // ----------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------- // Add season names to the day CSS classes -- it is required for correct work of conditional fields -------------- var season_names_arr = _wpbc.seasons__get_for_date( resource_id, sql_class_day ); for ( var season_key in season_names_arr ){ css_classes__for_date.push( season_names_arr[ season_key ] ); // 'wpdevbk_season_september_2023' } // ----------------------------------------------------------------------------------------------------------------- // Cost Rate ------------------------------------------------------------------------------------------------------- css_classes__for_date.push( 'rate_' + date_bookings_obj[ resource_id ][ 'date_cost_rate' ].toString().replace( /[\.\s]/g, '_' ) ); // 'rate_99_00' -> 99.00 if ( parseInt( date_bookings_obj[ 'day_availability' ] ) > 0 ){ is_day_selectable = true; css_classes__for_date.push( 'date_available' ); css_classes__for_date.push( 'reserved_days_count' + parseInt( date_bookings_obj[ 'max_capacity' ] - date_bookings_obj[ 'day_availability' ] ) ); } else { is_day_selectable = false; css_classes__for_date.push( 'date_user_unavailable' ); } switch ( date_bookings_obj[ 'summary']['status_for_day' ] ){ case 'available': break; case 'time_slots_booking': css_classes__for_date.push( 'timespartly', 'times_clock' ); break; case 'full_day_booking': css_classes__for_date.push( 'full_day_booking' ); break; case 'season_filter': css_classes__for_date.push( 'date_user_unavailable', 'season_unavailable' ); date_bookings_obj[ 'summary']['status_for_bookings' ] = ''; // Reset booking status color for possible old bookings on this date break; case 'resource_availability': css_classes__for_date.push( 'date_user_unavailable', 'resource_unavailable' ); date_bookings_obj[ 'summary']['status_for_bookings' ] = ''; // Reset booking status color for possible old bookings on this date break; case 'weekday_unavailable': css_classes__for_date.push( 'date_user_unavailable', 'weekday_unavailable' ); date_bookings_obj[ 'summary']['status_for_bookings' ] = ''; // Reset booking status color for possible old bookings on this date break; case 'from_today_unavailable': css_classes__for_date.push( 'date_user_unavailable', 'from_today_unavailable' ); date_bookings_obj[ 'summary']['status_for_bookings' ] = ''; // Reset booking status color for possible old bookings on this date break; case 'limit_available_from_today': css_classes__for_date.push( 'date_user_unavailable', 'limit_available_from_today' ); date_bookings_obj[ 'summary']['status_for_bookings' ] = ''; // Reset booking status color for possible old bookings on this date break; case 'change_over': /* * // check_out_time_date2approve check_in_time_date2approve // check_out_time_date2approve check_in_time_date_approved // check_in_time_date2approve check_out_time_date_approved // check_out_time_date_approved check_in_time_date_approved */ css_classes__for_date.push( 'timespartly', 'check_in_time', 'check_out_time' ); // FixIn: 10.0.0.2. if ( date_bookings_obj[ 'summary' ][ 'status_for_bookings' ].indexOf( 'approved_pending' ) > -1 ){ css_classes__for_date.push( 'check_out_time_date_approved', 'check_in_time_date2approve' ); } if ( date_bookings_obj[ 'summary' ][ 'status_for_bookings' ].indexOf( 'pending_approved' ) > -1 ){ css_classes__for_date.push( 'check_out_time_date2approve', 'check_in_time_date_approved' ); } break; case 'check_in': css_classes__for_date.push( 'timespartly', 'check_in_time' ); // FixIn: 9.9.0.33. if ( date_bookings_obj[ 'summary' ][ 'status_for_bookings' ].indexOf( 'pending' ) > -1 ){ css_classes__for_date.push( 'check_in_time_date2approve' ); } else if ( date_bookings_obj[ 'summary' ][ 'status_for_bookings' ].indexOf( 'approved' ) > -1 ){ css_classes__for_date.push( 'check_in_time_date_approved' ); } break; case 'check_out': css_classes__for_date.push( 'timespartly', 'check_out_time' ); // FixIn: 9.9.0.33. if ( date_bookings_obj[ 'summary' ][ 'status_for_bookings' ].indexOf( 'pending' ) > -1 ){ css_classes__for_date.push( 'check_out_time_date2approve' ); } else if ( date_bookings_obj[ 'summary' ][ 'status_for_bookings' ].indexOf( 'approved' ) > -1 ){ css_classes__for_date.push( 'check_out_time_date_approved' ); } break; default: // mixed statuses: 'change_over check_out' .... variations.... check more in function wpbc_get_availability_per_days_arr() date_bookings_obj[ 'summary']['status_for_day' ] = 'available'; } if ( 'available' != date_bookings_obj[ 'summary']['status_for_day' ] ){ var is_set_pending_days_selectable = _wpbc.calendar__get_param_value( resource_id, 'pending_days_selectable' ); // set pending days selectable // FixIn: 8.6.1.18. switch ( date_bookings_obj[ 'summary']['status_for_bookings' ] ){ case '': // Usually it's means that day is available or unavailable without the bookings break; case 'pending': css_classes__for_date.push( 'date2approve' ); is_day_selectable = (is_day_selectable) ? true : is_set_pending_days_selectable; break; case 'approved': css_classes__for_date.push( 'date_approved' ); break; // Situations for "change-over" days: ---------------------------------------------------------------------- case 'pending_pending': css_classes__for_date.push( 'check_out_time_date2approve', 'check_in_time_date2approve' ); is_day_selectable = (is_day_selectable) ? true : is_set_pending_days_selectable; break; case 'pending_approved': css_classes__for_date.push( 'check_out_time_date2approve', 'check_in_time_date_approved' ); is_day_selectable = (is_day_selectable) ? true : is_set_pending_days_selectable; break; case 'approved_pending': css_classes__for_date.push( 'check_out_time_date_approved', 'check_in_time_date2approve' ); is_day_selectable = (is_day_selectable) ? true : is_set_pending_days_selectable; break; case 'approved_approved': css_classes__for_date.push( 'check_out_time_date_approved', 'check_in_time_date_approved' ); break; default: } } return [ is_day_selectable, css_classes__for_date.join( ' ' ) ]; } /** * Mouseover calendar date cells * * @param string_date * @param date - JavaScript Date Obj: Mon Dec 11 2023 00:00:00 * GMT+0200 (Eastern European Standard Time) * @param calendar_params_arr - Calendar Settings Object: { * "resource_id": 4 * } * @param datepick_this - this of datepick Obj * @returns {boolean} */ function wpbc__calendar__on_hover_days( string_date, date, calendar_params_arr, datepick_this ) { if ( null === date ) { wpbc_calendars__clear_days_highlighting( ('undefined' !== typeof (calendar_params_arr[ 'resource_id' ])) ? calendar_params_arr[ 'resource_id' ] : '1' ); // FixIn: 10.5.2.4. return false; } var class_day = wpbc__get__td_class_date( date ); // '1-9-2023' var sql_class_day = wpbc__get__sql_class_date( date ); // '2023-01-09' var resource_id = ( 'undefined' !== typeof(calendar_params_arr[ 'resource_id' ]) ) ? calendar_params_arr[ 'resource_id' ] : '1'; // '1' // Get Data -------------------------------------------------------------------------------------------------------- var date_booking_obj = _wpbc.bookings_in_calendar__get_for_date( resource_id, sql_class_day ); // {...} if ( ! date_booking_obj ){ return false; } // T o o l t i p s ------------------------------------------------------------------------------------------------- var tooltip_text = ''; if ( date_booking_obj[ 'summary']['tooltip_availability' ].length > 0 ){ tooltip_text += date_booking_obj[ 'summary']['tooltip_availability' ]; } if ( date_booking_obj[ 'summary']['tooltip_day_cost' ].length > 0 ){ tooltip_text += date_booking_obj[ 'summary']['tooltip_day_cost' ]; } if ( date_booking_obj[ 'summary']['tooltip_times' ].length > 0 ){ tooltip_text += date_booking_obj[ 'summary']['tooltip_times' ]; } if ( date_booking_obj[ 'summary']['tooltip_booking_details' ].length > 0 ){ tooltip_text += date_booking_obj[ 'summary']['tooltip_booking_details' ]; } wpbc_set_tooltip___for__calendar_date( tooltip_text, resource_id, class_day ); // U n h o v e r i n g in UNSELECTABLE_CALENDAR ------------------------------------------------------------ var is_unselectable_calendar = ( jQuery( '#calendar_booking_unselectable' + resource_id ).length > 0); // FixIn: 8.0.1.2. var is_booking_form_exist = ( jQuery( '#booking_form_div' + resource_id ).length > 0 ); if ( ( is_unselectable_calendar ) && ( ! is_booking_form_exist ) ){ /** * Un Hover all dates in calendar (without the booking form), if only Availability Calendar here and we do * not insert Booking form by mistake. */ wpbc_calendars__clear_days_highlighting( resource_id ); // Clear days highlighting var css_of_calendar = '.wpbc_only_calendar #calendar_booking' + resource_id; jQuery( css_of_calendar + ' .datepick-days-cell, ' + css_of_calendar + ' .datepick-days-cell a' ).css( 'cursor', 'default' ); // Set cursor to Default return false; } // D a y s H o v e r i n g ------------------------------------------------------------------------------------ if ( ( location.href.indexOf( 'page=wpbc' ) == -1 ) || ( location.href.indexOf( 'page=wpbc-new' ) > 0 ) || ( location.href.indexOf( 'page=wpbc-setup' ) > 0 ) || ( location.href.indexOf( 'page=wpbc-availability' ) > 0 ) || ( ( location.href.indexOf( 'page=wpbc-settings' ) > 0 ) && ( location.href.indexOf( '&tab=form' ) > 0 ) ) ){ // The same as dates selection, but for days hovering if ( 'function' == typeof( wpbc__calendar__do_days_highlight__bs ) ){ wpbc__calendar__do_days_highlight__bs( sql_class_day, date, resource_id ); } } } /** * Select calendar date cells * * @param date - JavaScript Date Obj: Mon Dec 11 2023 00:00:00 * GMT+0200 (Eastern European Standard Time) * @param calendar_params_arr - Calendar Settings Object: { * "resource_id": 4 * } * @param datepick_this - this of datepick Obj * */ function wpbc__calendar__on_select_days( date, calendar_params_arr, datepick_this ){ var resource_id = ( 'undefined' !== typeof(calendar_params_arr[ 'resource_id' ]) ) ? calendar_params_arr[ 'resource_id' ] : '1'; // '1' // Set unselectable, if only Availability Calendar here (and we do not insert Booking form by mistake). var is_unselectable_calendar = ( jQuery( '#calendar_booking_unselectable' + resource_id ).length > 0); // FixIn: 8.0.1.2. var is_booking_form_exist = ( jQuery( '#booking_form_div' + resource_id ).length > 0 ); if ( ( is_unselectable_calendar ) && ( ! is_booking_form_exist ) ){ wpbc_calendar__unselect_all_dates( resource_id ); // Unselect Dates jQuery('.wpbc_only_calendar .popover_calendar_hover').remove(); // Hide all opened popovers return false; } jQuery( '#date_booking' + resource_id ).val( date ); // Add selected dates to hidden textarea if ( 'function' === typeof (wpbc__calendar__do_days_select__bs) ){ wpbc__calendar__do_days_select__bs( date, resource_id ); } wpbc_disable_time_fields_in_booking_form( resource_id ); // Hook -- trigger day selection ----------------------------------------------------------------------------------- var mouse_clicked_dates = date; // Can be: "05.10.2023 - 07.10.2023" | "10.10.2023 - 10.10.2023" | var all_selected_dates_arr = wpbc_get__selected_dates_sql__as_arr( resource_id ); // Can be: [ "2023-10-05", "2023-10-06", "2023-10-07", … ] jQuery( ".booking_form_div" ).trigger( "date_selected", [ resource_id, mouse_clicked_dates, all_selected_dates_arr ] ); } // Mark middle selected dates with 0.5 opacity // FixIn: 10.3.0.9. jQuery( document ).ready( function (){ jQuery( ".booking_form_div" ).on( 'date_selected', function ( event, resource_id, date ){ if ( ( 'fixed' === _wpbc.calendar__get_param_value( resource_id, 'days_select_mode' )) || ('dynamic' === _wpbc.calendar__get_param_value( resource_id, 'days_select_mode' )) ){ var closed_timer = setTimeout( function (){ var middle_days_opacity = _wpbc.get_other_param( 'calendars__days_selection__middle_days_opacity' ); jQuery( '#calendar_booking' + resource_id + ' .datepick-current-day' ).not( ".selected_check_in_out" ).css( 'opacity', middle_days_opacity ); }, 10 ); } } ); } ); /** * -- T i m e F i e l d s start -------------------------------------------------------------------------- */ /** * Disable time slots in booking form depend on selected dates and booked dates/times * * @param resource_id */ function wpbc_disable_time_fields_in_booking_form( resource_id ){ /** * 1. Get all time fields in the booking form as array of objects * [ * { jquery_option: jQuery_Object {} * name: 'rangetime2[]' * times_as_seconds: [ 21600, 23400 ] * value_option_24h: '06:00 - 06:30' * } * ... * { jquery_option: jQuery_Object {} * name: 'starttime2[]' * times_as_seconds: [ 21600 ] * value_option_24h: '06:00' * } * ] */ var time_fields_obj_arr = wpbc_get__time_fields__in_booking_form__as_arr( resource_id ); // 2. Get all selected dates in SQL format like this [ "2023-08-23", "2023-08-24", "2023-08-25", ... ] var selected_dates_arr = wpbc_get__selected_dates_sql__as_arr( resource_id ); // 3. Get child booking resources or single booking resource that exist in dates var child_resources_arr = wpbc_clone_obj( _wpbc.booking__get_param_value( resource_id, 'resources_id_arr__in_dates' ) ); var sql_date; var child_resource_id; var merged_seconds; var time_fields_obj; var is_intersect; var is_check_in; var today_time__real = new Date( _wpbc.get_other_param( 'time_local_arr' )[0], ( parseInt( _wpbc.get_other_param( 'time_local_arr' )[1] ) - 1), _wpbc.get_other_param( 'time_local_arr' )[2], _wpbc.get_other_param( 'time_local_arr' )[3], _wpbc.get_other_param( 'time_local_arr' )[4], 0 ); var today_time__shift = new Date( _wpbc.get_other_param( 'today_arr' )[0], ( parseInt( _wpbc.get_other_param( 'today_arr' )[1] ) - 1), _wpbc.get_other_param( 'today_arr' )[2], _wpbc.get_other_param( 'today_arr' )[3], _wpbc.get_other_param( 'today_arr' )[4], 0 ); // 4. Loop all time Fields options // FixIn: 10.3.0.2. for ( let field_key = 0; field_key < time_fields_obj_arr.length; field_key++ ){ time_fields_obj_arr[ field_key ].disabled = 0; // By default, this time field is not disabled. time_fields_obj = time_fields_obj_arr[ field_key ]; // { times_as_seconds: [ 21600, 23400 ], value_option_24h: '06:00 - 06:30', name: 'rangetime2[]', jquery_option: jQuery_Object {}} // Loop all selected dates. for ( var i = 0; i < selected_dates_arr.length; i++ ) { // Get Date: '2023-08-18'. sql_date = selected_dates_arr[i]; var is_time_in_past = wpbc_check_is_time_in_past( today_time__shift, sql_date, time_fields_obj ); // Exception for 'End Time' field, when selected several dates. // FixIn: 10.14.1.5. if ( ('On' !== _wpbc.calendar__get_param_value( resource_id, 'booking_recurrent_time' )) && (-1 !== time_fields_obj.name.indexOf( 'endtime' )) && (selected_dates_arr.length > 1) ) { is_time_in_past = wpbc_check_is_time_in_past( today_time__shift, selected_dates_arr[(selected_dates_arr.length - 1)], time_fields_obj ); } if ( is_time_in_past ) { // This time for selected date already in the past. time_fields_obj_arr[field_key].disabled = 1; break; // exist from Dates LOOP. } // FixIn: 9.9.0.31. if ( ( 'Off' === _wpbc.calendar__get_param_value( resource_id, 'booking_recurrent_time' ) ) && ( selected_dates_arr.length>1 ) ){ //TODO: skip some fields checking if it's start / end time for mulple dates selection mode. //TODO: we need to fix situation for entimes, when user select several dates, and in start time booked 00:00 - 15:00 , but systsme block untill 15:00 the end time as well, which is wrong, because it 2 or 3 dates selection and end date can be fullu available if ( (0 == i) && (time_fields_obj[ 'name' ].indexOf( 'endtime' ) >= 0) ){ break; } if ( ( (selected_dates_arr.length-1) == i ) && (time_fields_obj[ 'name' ].indexOf( 'starttime' ) >= 0) ){ break; } } var how_many_resources_intersected = 0; // Loop all resources ID // for ( var res_key in child_resources_arr ){ // FixIn: 10.3.0.2. if ( null === child_resources_arr ) { child_resources_arr = []; } for ( let res_key = 0; res_key < child_resources_arr.length; res_key++ ){ child_resource_id = child_resources_arr[ res_key ]; // _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[12].booked_time_slots.merged_seconds = [ "07:00:11 - 07:30:02", "10:00:11 - 00:00:00" ] // _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[2].booked_time_slots.merged_seconds = [ [ 25211, 27002 ], [ 36011, 86400 ] ] if ( false !== _wpbc.bookings_in_calendar__get_for_date( resource_id, sql_date ) ){ merged_seconds = _wpbc.bookings_in_calendar__get_for_date( resource_id, sql_date )[ child_resource_id ].booked_time_slots.merged_seconds; // [ [ 25211, 27002 ], [ 36011, 86400 ] ] } else { merged_seconds = []; } if ( time_fields_obj.times_as_seconds.length > 1 ){ is_intersect = wpbc_is_intersect__range_time_interval( [ [ ( parseInt( time_fields_obj.times_as_seconds[0] ) + 20 ), ( parseInt( time_fields_obj.times_as_seconds[1] ) - 20 ) ] ] , merged_seconds ); } else { is_check_in = (-1 !== time_fields_obj.name.indexOf( 'start' )); is_intersect = wpbc_is_intersect__one_time_interval( ( ( is_check_in ) ? parseInt( time_fields_obj.times_as_seconds ) + 20 : parseInt( time_fields_obj.times_as_seconds ) - 20 ) , merged_seconds ); } if (is_intersect){ how_many_resources_intersected++; // Increase } } if ( child_resources_arr.length == how_many_resources_intersected ) { // All resources intersected, then it's means that this time-slot or time must be Disabled, and we can exist from selected_dates_arr LOOP time_fields_obj_arr[ field_key ].disabled = 1; break; // exist from Dates LOOP } } } // 5. Now we can disable time slot in HTML by using ( field.disabled == 1 ) property wpbc__html__time_field_options__set_disabled( time_fields_obj_arr ); jQuery( ".booking_form_div" ).trigger( 'wpbc_hook_timeslots_disabled', [resource_id, selected_dates_arr] ); // Trigger hook on disabling timeslots. Usage: jQuery( ".booking_form_div" ).on( 'wpbc_hook_timeslots_disabled', function ( event, bk_type, all_dates ){ ... } ); // FixIn: 8.7.11.9. } /** * Check if specific time(-slot) already in the past for selected date * * @param js_current_time_to_check - JS Date * @param sql_date - '2025-01-26' * @param time_fields_obj - Object * @returns {boolean} */ function wpbc_check_is_time_in_past( js_current_time_to_check, sql_date, time_fields_obj ) { // FixIn: 10.9.6.4 var sql_date_arr = sql_date.split( '-' ); var sql_date__midnight = new Date( parseInt( sql_date_arr[0] ), ( parseInt( sql_date_arr[1] ) - 1 ), parseInt( sql_date_arr[2] ), 0, 0, 0 ); var sql_date__midnight_miliseconds = sql_date__midnight.getTime(); var is_intersect = false; if ( time_fields_obj.times_as_seconds.length > 1 ) { if ( js_current_time_to_check.getTime() > (sql_date__midnight_miliseconds + (parseInt( time_fields_obj.times_as_seconds[0] ) + 20) * 1000) ) { is_intersect = true; } if ( js_current_time_to_check.getTime() > (sql_date__midnight_miliseconds + (parseInt( time_fields_obj.times_as_seconds[1] ) - 20) * 1000) ) { is_intersect = true; } } else { var is_check_in = (-1 !== time_fields_obj.name.indexOf( 'start' )); var times_as_seconds_check = (is_check_in) ? parseInt( time_fields_obj.times_as_seconds ) + 20 : parseInt( time_fields_obj.times_as_seconds ) - 20; times_as_seconds_check = sql_date__midnight_miliseconds + times_as_seconds_check * 1000; if ( js_current_time_to_check.getTime() > times_as_seconds_check ) { is_intersect = true; } } return is_intersect; } /** * Is number inside /intersect of array of intervals ? * * @param time_A - 25800 * @param time_interval_B - [ [ 25211, 27002 ], [ 36011, 86400 ] ] * @returns {boolean} */ function wpbc_is_intersect__one_time_interval( time_A, time_interval_B ){ for ( var j = 0; j < time_interval_B.length; j++ ){ if ( (parseInt( time_A ) > parseInt( time_interval_B[ j ][ 0 ] )) && (parseInt( time_A ) < parseInt( time_interval_B[ j ][ 1 ] )) ){ return true } // if ( ( parseInt( time_A ) == parseInt( time_interval_B[ j ][ 0 ] ) ) || ( parseInt( time_A ) == parseInt( time_interval_B[ j ][ 1 ] ) ) ) { // // Time A just at the border of interval // } } return false; } /** * Is these array of intervals intersected ? * * @param time_interval_A - [ [ 21600, 23400 ] ] * @param time_interval_B - [ [ 25211, 27002 ], [ 36011, 86400 ] ] * @returns {boolean} */ function wpbc_is_intersect__range_time_interval( time_interval_A, time_interval_B ){ var is_intersect; for ( var i = 0; i < time_interval_A.length; i++ ){ for ( var j = 0; j < time_interval_B.length; j++ ){ is_intersect = wpbc_intervals__is_intersected( time_interval_A[ i ], time_interval_B[ j ] ); if ( is_intersect ){ return true; } } } return false; } /** * Get all time fields in the booking form as array of objects * * @param resource_id * @returns [] * * Example: * [ * { * value_option_24h: '06:00 - 06:30' * times_as_seconds: [ 21600, 23400 ] * jquery_option: jQuery_Object {} * name: 'rangetime2[]' * } * ... * { * value_option_24h: '06:00' * times_as_seconds: [ 21600 ] * jquery_option: jQuery_Object {} * name: 'starttime2[]' * } * ] */ function wpbc_get__time_fields__in_booking_form__as_arr( resource_id ){ /** * Fields with [] like this select[name="rangetime1[]"] * it's when we have 'multiple' in shortcode: [select* rangetime multiple "06:00 - 06:30" ... ] */ var time_fields_arr=[ 'select[name="rangetime' + resource_id + '"]', 'select[name="rangetime' + resource_id + '[]"]', 'select[name="starttime' + resource_id + '"]', 'select[name="starttime' + resource_id + '[]"]', 'select[name="endtime' + resource_id + '"]', 'select[name="endtime' + resource_id + '[]"]' ]; var time_fields_obj_arr = []; // Loop all Time Fields for ( var ctf= 0; ctf < time_fields_arr.length; ctf++ ){ var time_field = time_fields_arr[ ctf ]; var time_option = jQuery( time_field + ' option' ); // Loop all options in time field for ( var j = 0; j < time_option.length; j++ ){ var jquery_option = jQuery( time_field + ' option:eq(' + j + ')' ); var value_option_seconds_arr = jquery_option.val().split( '-' ); var times_as_seconds = []; // Get time as seconds if ( value_option_seconds_arr.length ){ // FixIn: 9.8.10.1. for ( let i = 0; i < value_option_seconds_arr.length; i++ ){ // FixIn: 10.0.0.56. // value_option_seconds_arr[i] = '14:00 ' | ' 16:00' (if from 'rangetime') and '16:00' if (start/end time) var start_end_times_arr = value_option_seconds_arr[ i ].trim().split( ':' ); var time_in_seconds = parseInt( start_end_times_arr[ 0 ] ) * 60 * 60 + parseInt( start_end_times_arr[ 1 ] ) * 60; times_as_seconds.push( time_in_seconds ); } } time_fields_obj_arr.push( { 'name' : jQuery( time_field ).attr( 'name' ), 'value_option_24h': jquery_option.val(), 'jquery_option' : jquery_option, 'times_as_seconds': times_as_seconds } ); } } return time_fields_obj_arr; } /** * Disable HTML options and add booked CSS class * * @param time_fields_obj_arr - this value is from the func: * wpbc_get__time_fields__in_booking_form__as_arr( resource_id ) * [ * { jquery_option: jQuery_Object {} * name: 'rangetime2[]' * times_as_seconds: [ 21600, 23400 ] * value_option_24h: '06:00 - 06:30' * disabled = 1 * } * ... * { jquery_option: jQuery_Object {} * name: 'starttime2[]' * times_as_seconds: [ 21600 ] * value_option_24h: '06:00' * disabled = 0 * } * ] * */ function wpbc__html__time_field_options__set_disabled( time_fields_obj_arr ){ var jquery_option; for ( var i = 0; i < time_fields_obj_arr.length; i++ ){ var jquery_option = time_fields_obj_arr[ i ].jquery_option; if ( 1 == time_fields_obj_arr[ i ].disabled ){ jquery_option.prop( 'disabled', true ); // Make disable some options jquery_option.addClass( 'booked' ); // Add "booked" CSS class // if this booked element selected --> then deselect it if ( jquery_option.prop( 'selected' ) ){ jquery_option.prop( 'selected', false ); jquery_option.parent().find( 'option:not([disabled]):first' ).prop( 'selected', true ).trigger( "change" ); } } else { jquery_option.prop( 'disabled', false ); // Make active all times jquery_option.removeClass( 'booked' ); // Remove class "booked" } } } /** * Check if this time_range | Time_Slot is Full Day booked * * @param timeslot_arr_in_seconds - [ 36011, 86400 ] * @returns {boolean} */ function wpbc_is_this_timeslot__full_day_booked( timeslot_arr_in_seconds ){ if ( ( timeslot_arr_in_seconds.length > 1 ) && ( parseInt( timeslot_arr_in_seconds[ 0 ] ) < 30 ) && ( parseInt( timeslot_arr_in_seconds[ 1 ] ) > ( (24 * 60 * 60) - 30) ) ){ return true; } return false; } // ----------------------------------------------------------------------------------------------------------------- /* == S e l e c t e d D a t e s / T i m e - F i e l d s == // ----------------------------------------------------------------------------------------------------------------- */ /** * Get all selected dates in SQL format like this [ "2023-08-23", "2023-08-24" , ... ] * * @param resource_id * @returns {[]} [ "2023-08-23", "2023-08-24", "2023-08-25", "2023-08-26", "2023-08-27", "2023-08-28", * "2023-08-29" ] */ function wpbc_get__selected_dates_sql__as_arr( resource_id ){ var selected_dates_arr = []; selected_dates_arr = jQuery( '#date_booking' + resource_id ).val().split(','); if ( selected_dates_arr.length ){ // FixIn: 9.8.10.1. for ( let i = 0; i < selected_dates_arr.length; i++ ){ // FixIn: 10.0.0.56. selected_dates_arr[ i ] = selected_dates_arr[ i ].trim(); selected_dates_arr[ i ] = selected_dates_arr[ i ].split( '.' ); if ( selected_dates_arr[ i ].length > 1 ){ selected_dates_arr[ i ] = selected_dates_arr[ i ][ 2 ] + '-' + selected_dates_arr[ i ][ 1 ] + '-' + selected_dates_arr[ i ][ 0 ]; } } } // Remove empty elements from an array selected_dates_arr = selected_dates_arr.filter( function ( n ){ return parseInt(n); } ); selected_dates_arr.sort(); return selected_dates_arr; } /** * Get all time fields in the booking form as array of objects * * @param resource_id * @param is_only_selected_time * @returns [] * * Example: * [ * { * value_option_24h: '06:00 - 06:30' * times_as_seconds: [ 21600, 23400 ] * jquery_option: jQuery_Object {} * name: 'rangetime2[]' * } * ... * { * value_option_24h: '06:00' * times_as_seconds: [ 21600 ] * jquery_option: jQuery_Object {} * name: 'starttime2[]' * } * ] */ function wpbc_get__selected_time_fields__in_booking_form__as_arr( resource_id, is_only_selected_time = true ){ /** * Fields with [] like this select[name="rangetime1[]"] * it's when we have 'multiple' in shortcode: [select* rangetime multiple "06:00 - 06:30" ... ] */ var time_fields_arr=[ 'select[name="rangetime' + resource_id + '"]', 'select[name="rangetime' + resource_id + '[]"]', 'select[name="starttime' + resource_id + '"]', 'select[name="starttime' + resource_id + '[]"]', 'select[name="endtime' + resource_id + '"]', 'select[name="endtime' + resource_id + '[]"]', 'select[name="durationtime' + resource_id + '"]', 'select[name="durationtime' + resource_id + '[]"]' ]; var time_fields_obj_arr = []; // Loop all Time Fields for ( var ctf= 0; ctf < time_fields_arr.length; ctf++ ){ var time_field = time_fields_arr[ ctf ]; var time_option; if ( is_only_selected_time ){ time_option = jQuery( '#booking_form' + resource_id + ' ' + time_field + ' option:selected' ); // Exclude conditional fields, because of using '#booking_form3 ...' } else { time_option = jQuery( '#booking_form' + resource_id + ' ' + time_field + ' option' ); // All time fields } // Loop all options in time field for ( var j = 0; j < time_option.length; j++ ){ var jquery_option = jQuery( time_option[ j ] ); // Get only selected options //jQuery( time_field + ' option:eq(' + j + ')' ); var value_option_seconds_arr = jquery_option.val().split( '-' ); var times_as_seconds = []; // Get time as seconds if ( value_option_seconds_arr.length ){ // FixIn: 9.8.10.1. for ( let i = 0; i < value_option_seconds_arr.length; i++ ){ // FixIn: 10.0.0.56. // value_option_seconds_arr[i] = '14:00 ' | ' 16:00' (if from 'rangetime') and '16:00' if (start/end time) var start_end_times_arr = value_option_seconds_arr[ i ].trim().split( ':' ); var time_in_seconds = parseInt( start_end_times_arr[ 0 ] ) * 60 * 60 + parseInt( start_end_times_arr[ 1 ] ) * 60; times_as_seconds.push( time_in_seconds ); } } time_fields_obj_arr.push( { 'name' : jQuery( '#booking_form' + resource_id + ' ' + time_field ).attr( 'name' ), 'value_option_24h': jquery_option.val(), 'jquery_option' : jquery_option, 'times_as_seconds': times_as_seconds } ); } } // Text: [starttime] - [endtime] ----------------------------------------------------------------------------- var text_time_fields_arr=[ 'input[name="starttime' + resource_id + '"]', 'input[name="endtime' + resource_id + '"]', ]; for ( var tf= 0; tf < text_time_fields_arr.length; tf++ ){ var text_jquery = jQuery( '#booking_form' + resource_id + ' ' + text_time_fields_arr[ tf ] ); // Exclude conditional fields, because of using '#booking_form3 ...' if ( text_jquery.length > 0 ){ var time__h_m__arr = text_jquery.val().trim().split( ':' ); // '14:00' if ( 0 == time__h_m__arr.length ){ continue; // Not entered time value in a field } if ( 1 == time__h_m__arr.length ){ if ( '' === time__h_m__arr[ 0 ] ){ continue; // Not entered time value in a field } time__h_m__arr[ 1 ] = 0; } var text_time_in_seconds = parseInt( time__h_m__arr[ 0 ] ) * 60 * 60 + parseInt( time__h_m__arr[ 1 ] ) * 60; var text_times_as_seconds = []; text_times_as_seconds.push( text_time_in_seconds ); time_fields_obj_arr.push( { 'name' : text_jquery.attr( 'name' ), 'value_option_24h': text_jquery.val(), 'jquery_option' : text_jquery, 'times_as_seconds': text_times_as_seconds } ); } } return time_fields_obj_arr; } // --------------------------------------------------------------------------------------------------------------------- /* == S U P P O R T for C A L E N D A R == // --------------------------------------------------------------------------------------------------------------------- */ /** * Get Calendar datepick Instance. * * @param {int|string} resource_id * @returns {*|null} */ function wpbc_calendar__get_inst(resource_id) { if ( 'undefined' === typeof (resource_id) ) { resource_id = '1'; } if ( jQuery( '#calendar_booking' + resource_id ).length > 0 ) { try { var inst = jQuery.datepick._getInst( jQuery( '#calendar_booking' + resource_id ).get( 0 ) ); return inst ? inst : null; } catch ( e ) { return null; } } return null; } /** * Unselect all dates in calendar and visually update this calendar * * @param resource_id ID of booking resource * @returns {boolean} true on success | false, if no such calendar */ function wpbc_calendar__unselect_all_dates( resource_id ){ if ( 'undefined' === typeof (resource_id) ){ resource_id = '1'; } var inst = wpbc_calendar__get_inst( resource_id ) if ( null !== inst ){ // Unselect all dates and set properties of Datepick jQuery( '#date_booking' + resource_id ).val( '' ); //FixIn: 5.4.3 inst.stayOpen = false; inst.dates = []; jQuery.datepick._updateDatepick( inst ); return true } return false; } /** * Clear days highlighting in All or specific Calendars * * @param resource_id - can be skiped to clear highlighting in all calendars */ function wpbc_calendars__clear_days_highlighting( resource_id ){ if ( 'undefined' !== typeof ( resource_id ) ){ jQuery( '#calendar_booking' + resource_id + ' .datepick-days-cell-over' ).removeClass( 'datepick-days-cell-over' ); // Clear in specific calendar } else { jQuery( '.datepick-days-cell-over' ).removeClass( 'datepick-days-cell-over' ); // Clear in all calendars } } /** * Scroll to specific month in calendar * * @param resource_id ID of resource * @param year - real year - 2023 * @param month - real month - 12 * @returns {boolean} */ function wpbc_calendar__scroll_to( resource_id, year, month ){ if ( 'undefined' === typeof (resource_id) ){ resource_id = '1'; } var inst = wpbc_calendar__get_inst( resource_id ) if ( null !== inst ){ year = parseInt( year ); month = parseInt( month ) - 1; // In JS date, month -1 inst.cursorDate = new Date(); // In some cases, the setFullYear can set only Year, and not the Month and day // FixIn: 6.2.3.5. inst.cursorDate.setFullYear( year, month, 1 ); inst.cursorDate.setMonth( month ); inst.cursorDate.setDate( 1 ); inst.drawMonth = inst.cursorDate.getMonth(); inst.drawYear = inst.cursorDate.getFullYear(); jQuery.datepick._notifyChange( inst ); jQuery.datepick._adjustInstDate( inst ); jQuery.datepick._showDate( inst ); jQuery.datepick._updateDatepick( inst ); return true; } return false; } /** * Is this date selectable in calendar (mainly it's means AVAILABLE date) * * @param {int|string} resource_id 1 * @param {string} sql_class_day '2023-08-11' * @returns {boolean} true | false */ function wpbc_is_this_day_selectable( resource_id, sql_class_day ){ // Get Data -------------------------------------------------------------------------------------------------------- var date_bookings_obj = _wpbc.bookings_in_calendar__get_for_date( resource_id, sql_class_day ); var is_day_selectable = ( parseInt( date_bookings_obj[ 'day_availability' ] ) > 0 ); if ( typeof (date_bookings_obj[ 'summary' ]) === 'undefined' ){ return is_day_selectable; } if ( 'available' != date_bookings_obj[ 'summary']['status_for_day' ] ){ var is_set_pending_days_selectable = _wpbc.calendar__get_param_value( resource_id, 'pending_days_selectable' ); // set pending days selectable // FixIn: 8.6.1.18. switch ( date_bookings_obj[ 'summary']['status_for_bookings' ] ){ case 'pending': // Situations for "change-over" days: case 'pending_pending': case 'pending_approved': case 'approved_pending': is_day_selectable = (is_day_selectable) ? true : is_set_pending_days_selectable; break; default: } } return is_day_selectable; } /** * Is date to check IN array of selected dates * * @param {date}js_date_to_check - JS Date - simple JavaScript Date object * @param {[]} js_dates_arr - [ JSDate, ... ] - array of JS dates * @returns {boolean} */ function wpbc_is_this_day_among_selected_days( js_date_to_check, js_dates_arr ){ for ( var date_index = 0; date_index < js_dates_arr.length ; date_index++ ){ // FixIn: 8.4.5.16. if ( ( js_dates_arr[ date_index ].getFullYear() === js_date_to_check.getFullYear() ) && ( js_dates_arr[ date_index ].getMonth() === js_date_to_check.getMonth() ) && ( js_dates_arr[ date_index ].getDate() === js_date_to_check.getDate() ) ) { return true; } } return false; } /** * Get SQL Class Date '2023-08-01' from JS Date * * @param date JS Date * @returns {string} '2023-08-12' */ function wpbc__get__sql_class_date( date ){ var sql_class_day = date.getFullYear() + '-'; sql_class_day += ( ( date.getMonth() + 1 ) < 10 ) ? '0' : ''; sql_class_day += ( date.getMonth() + 1 ) + '-' sql_class_day += ( date.getDate() < 10 ) ? '0' : ''; sql_class_day += date.getDate(); return sql_class_day; } /** * Get JS Date from the SQL date format '2024-05-14' * @param sql_class_date * @returns {Date} */ function wpbc__get__js_date( sql_class_date ){ var sql_class_date_arr = sql_class_date.split( '-' ); var date_js = new Date(); date_js.setFullYear( parseInt( sql_class_date_arr[ 0 ] ), (parseInt( sql_class_date_arr[ 1 ] ) - 1), parseInt( sql_class_date_arr[ 2 ] ) ); // year, month, date // Without this time adjust Dates selection in Datepicker can not work!!! date_js.setHours(0); date_js.setMinutes(0); date_js.setSeconds(0); date_js.setMilliseconds(0); return date_js; } /** * Get TD Class Date '1-31-2023' from JS Date * * @param date JS Date * @returns {string} '1-31-2023' */ function wpbc__get__td_class_date( date ){ var td_class_day = (date.getMonth() + 1) + '-' + date.getDate() + '-' + date.getFullYear(); // '1-9-2023' return td_class_day; } /** * Get date params from string date * * @param date string date like '31.5.2023' * @param separator default '.' can be skipped. * @returns { {date: number, month: number, year: number} } */ function wpbc__get__date_params__from_string_date( date , separator){ separator = ( 'undefined' !== typeof (separator) ) ? separator : '.'; var date_arr = date.split( separator ); var date_obj = { 'year' : parseInt( date_arr[ 2 ] ), 'month': (parseInt( date_arr[ 1 ] ) - 1), 'date' : parseInt( date_arr[ 0 ] ) }; return date_obj; // for = new Date( date_obj.year , date_obj.month , date_obj.date ); } /** * Add Spin Loader to calendar * @param resource_id */ function wpbc_calendar__loading__start( resource_id ){ if ( ! jQuery( '#calendar_booking' + resource_id ).next().hasClass( 'wpbc_spins_loader_wrapper' ) ){ jQuery( '#calendar_booking' + resource_id ).after( '