| 1 |
/** |
| 2 |
* ==================================================================================================================== |
| 3 |
* includes/__js/cal_ajx_load/wpbc_cal_ajx.js |
| 4 |
* ==================================================================================================================== |
| 5 |
*/ |
| 6 |
|
| 7 |
// --------------------------------------------------------------------------------------------------------------------- |
| 8 |
// A j a x L o a d C a l e n d a r D a t a |
| 9 |
// --------------------------------------------------------------------------------------------------------------------- |
| 10 |
|
| 11 |
function wpbc_calendar__load_data__ajx( params ){ |
| 12 |
|
| 13 |
// FixIn: 9.8.6.2. |
| 14 |
wpbc_calendar__loading__start( params['resource_id'] ); |
| 15 |
|
| 16 |
// Trigger event for calendar before loading Booking data, but after showing Calendar. |
| 17 |
if ( jQuery( '#calendar_booking' + params['resource_id'] ).length > 0 ){ |
| 18 |
var target_elm = jQuery( 'body' ).trigger( "wpbc_calendar_ajx__before_loaded_data", [params['resource_id']] ); |
| 19 |
//jQuery( 'body' ).on( 'wpbc_calendar_ajx__before_loaded_data', function( event, resource_id ) { ... } ); |
| 20 |
} |
| 21 |
|
| 22 |
if ( wpbc_balancer__is_wait( params , 'wpbc_calendar__load_data__ajx' ) ){ |
| 23 |
return false; |
| 24 |
} |
| 25 |
|
| 26 |
// FixIn: 9.8.6.2. |
| 27 |
wpbc_calendar__blur__stop( params['resource_id'] ); |
| 28 |
|
| 29 |
// ----------------------------------------------------------------------------------------------------------------- |
| 30 |
// == Get start / end dates from the Booking Calendar shortcode. == |
| 31 |
// Example: [booking calendar_dates_start='2026-01-01' calendar_dates_end='2026-12-31' resource_id=1] // FixIn: 10.13.1.4. |
| 32 |
// ----------------------------------------------------------------------------------------------------------------- |
| 33 |
if ( false !== wpbc_calendar__get_dates_start( params['resource_id'] ) ) { |
| 34 |
if ( ! params['dates_to_check'] ) { params['dates_to_check'] = []; } |
| 35 |
var dates_start = wpbc_calendar__get_dates_start( params['resource_id'] ); // E.g. - local__min_date = new Date( 2025, 0, 1 ); |
| 36 |
if ( false !== dates_start ){ |
| 37 |
params['dates_to_check'][0] = wpbc__get__sql_class_date( dates_start ); |
| 38 |
} |
| 39 |
} |
| 40 |
if ( false !== wpbc_calendar__get_dates_end( params['resource_id'] ) ) { |
| 41 |
if ( !params['dates_to_check'] ) { params['dates_to_check'] = []; } |
| 42 |
var dates_end = wpbc_calendar__get_dates_end( params['resource_id'] ); // E.g. - local__min_date = new Date( 2025, 0, 1 ); |
| 43 |
if ( false !== dates_end ) { |
| 44 |
params['dates_to_check'][1] = wpbc__get__sql_class_date( dates_end ); |
| 45 |
if ( !params['dates_to_check'][0] ) { |
| 46 |
params['dates_to_check'][0] = wpbc__get__sql_class_date( new Date() ); |
| 47 |
} |
| 48 |
} |
| 49 |
} |
| 50 |
// ----------------------------------------------------------------------------------------------------------------- |
| 51 |
|
| 52 |
// console.groupEnd(); console.time('resource_id_' + params['resource_id']); |
| 53 |
console.groupCollapsed( 'WPBC_AJX_CALENDAR_LOAD' ); console.log( ' == Before Ajax Send - calendars_all__get() == ' , _wpbc.calendars_all__get() ); |
| 54 |
if ( 'function' === typeof (wpbc_hook__init_timeselector) ) { |
| 55 |
wpbc_hook__init_timeselector(); |
| 56 |
} |
| 57 |
|
| 58 |
// Start Ajax |
| 59 |
jQuery.post( wpbc_url_ajax, |
| 60 |
{ |
| 61 |
action : 'WPBC_AJX_CALENDAR_LOAD', |
| 62 |
wpbc_ajx_user_id: _wpbc.get_secure_param( 'user_id' ), |
| 63 |
nonce : _wpbc.get_secure_param( 'nonce' ), |
| 64 |
wpbc_ajx_locale : _wpbc.get_secure_param( 'locale' ), |
| 65 |
|
| 66 |
calendar_request_params : params // Usually like: { 'resource_id': 1, 'max_days_count': 365 } |
| 67 |
}, |
| 68 |
|
| 69 |
/** |
| 70 |
* S u c c e s s |
| 71 |
* |
| 72 |
* @param response_data - its object returned from Ajax - class-live-search.php |
| 73 |
* @param textStatus - 'success' |
| 74 |
* @param jqXHR - Object |
| 75 |
*/ |
| 76 |
function ( response_data, textStatus, jqXHR ) { |
| 77 |
// console.timeEnd('resource_id_' + response_data['resource_id']); |
| 78 |
console.log( ' == Response WPBC_AJX_CALENDAR_LOAD == ', response_data ); console.groupEnd(); |
| 79 |
|
| 80 |
// FixIn: 9.8.6.2. |
| 81 |
var ajx_post_data__resource_id = wpbc_get_resource_id__from_ajx_post_data_url( this.data ); |
| 82 |
wpbc_balancer__completed( ajx_post_data__resource_id , 'wpbc_calendar__load_data__ajx' ); |
| 83 |
|
| 84 |
var is_valid_response = ( |
| 85 |
(typeof response_data === 'object') |
| 86 |
&& (response_data !== null) |
| 87 |
&& (! Array.isArray( response_data )) |
| 88 |
&& Object.prototype.hasOwnProperty.call( response_data, 'resource_id' ) |
| 89 |
&& (typeof response_data[ 'ajx_data' ] === 'object') |
| 90 |
&& (response_data[ 'ajx_data' ] !== null) |
| 91 |
&& (! Array.isArray( response_data[ 'ajx_data' ] )) |
| 92 |
&& Object.prototype.hasOwnProperty.call( response_data[ 'ajx_data' ], 'dates' ) |
| 93 |
&& Object.prototype.hasOwnProperty.call( response_data[ 'ajx_data' ], 'resources_id_arr__in_dates' ) |
| 94 |
&& Object.prototype.hasOwnProperty.call( response_data[ 'ajx_data' ], 'aggregate_resource_id_arr' ) |
| 95 |
); |
| 96 |
|
| 97 |
if ( ! is_valid_response ) { |
| 98 |
var jq_node = wpbc_get_calendar__jq_node__for_messages( this.data ); |
| 99 |
var response_error_message = _wpbc.get_message( 'message_unexpected_server_response' ) || 'The server returned an unexpected response. Please reload the page and try again.'; |
| 100 |
|
| 101 |
wpbc_front_end__log_unexpected_ajax_response( 'WPBC_AJX_CALENDAR_LOAD', response_data, jqXHR, textStatus, 'Invalid response structure' ); |
| 102 |
wpbc_calendar__loading__stop( ajx_post_data__resource_id ); |
| 103 |
|
| 104 |
wpbc_front_end__show_message( response_error_message, { 'type' : 'error', |
| 105 |
'show_here' : {'jq_node': jq_node, 'where': 'after'}, |
| 106 |
'is_append' : true, |
| 107 |
'style' : 'text-align:left;', |
| 108 |
'content_mode': 'text', |
| 109 |
'delay' : 0 |
| 110 |
} ); |
| 111 |
return; |
| 112 |
} |
| 113 |
|
| 114 |
// Show Calendar |
| 115 |
wpbc_calendar__loading__stop( response_data[ 'resource_id' ] ); |
| 116 |
|
| 117 |
// ------------------------------------------------------------------------------------------------- |
| 118 |
// Bookings - Dates |
| 119 |
_wpbc.bookings_in_calendar__set_dates( response_data[ 'resource_id' ], response_data[ 'ajx_data' ]['dates'] ); |
| 120 |
|
| 121 |
// Bookings - Child or only single booking resource in dates |
| 122 |
_wpbc.booking__set_param_value( response_data[ 'resource_id' ], 'resources_id_arr__in_dates', response_data[ 'ajx_data' ][ 'resources_id_arr__in_dates' ] ); |
| 123 |
|
| 124 |
// Aggregate booking resources, if any ? |
| 125 |
_wpbc.booking__set_param_value( response_data[ 'resource_id' ], 'aggregate_resource_id_arr', response_data[ 'ajx_data' ][ 'aggregate_resource_id_arr' ] ); |
| 126 |
// ------------------------------------------------------------------------------------------------- |
| 127 |
|
| 128 |
/** |
| 129 |
* Allow optional modules to calculate derived calendar state after canonical |
| 130 |
* AJAX data is stored and before the first refreshed calendar render. |
| 131 |
* |
| 132 |
* @param {number|string} resource_id Booking resource ID. |
| 133 |
*/ |
| 134 |
jQuery( 'body' ).trigger( 'wpbc_calendar_ajx__before_update_look', [ response_data[ 'resource_id' ] ] ); |
| 135 |
|
| 136 |
// Update calendar |
| 137 |
wpbc_calendar__update_look( response_data[ 'resource_id' ] ); |
| 138 |
|
| 139 |
if ( 'function' === typeof (wpbc_hook__init_timeselector) ) { |
| 140 |
wpbc_hook__init_timeselector(); |
| 141 |
} |
| 142 |
|
| 143 |
if ( |
| 144 |
( 'undefined' !== typeof (response_data[ 'ajx_data' ][ 'ajx_after_action_message' ]) ) |
| 145 |
&& ( '' != response_data[ 'ajx_data' ][ 'ajx_after_action_message' ].replace( /\n/g, "<br />" ) ) |
| 146 |
){ |
| 147 |
|
| 148 |
var jq_node = wpbc_get_calendar__jq_node__for_messages( this.data ); |
| 149 |
|
| 150 |
// Show Message |
| 151 |
wpbc_front_end__show_message( response_data[ 'ajx_data' ][ 'ajx_after_action_message' ].replace( /\n/g, "<br />" ), |
| 152 |
{ 'type' : ( 'undefined' !== typeof( response_data[ 'ajx_data' ][ 'ajx_after_action_message_status' ] ) ) |
| 153 |
? response_data[ 'ajx_data' ][ 'ajx_after_action_message_status' ] : 'info', |
| 154 |
'show_here': {'jq_node': jq_node, 'where': 'after'}, |
| 155 |
'is_append': true, |
| 156 |
'style' : 'text-align:left;', |
| 157 |
'delay' : 10000 |
| 158 |
} ); |
| 159 |
} |
| 160 |
|
| 161 |
if ( 'function' === typeof (wpbc_update_capacity_hint) ) { |
| 162 |
wpbc_update_capacity_hint( response_data['resource_id'] ); |
| 163 |
} |
| 164 |
|
| 165 |
// Trigger event that calendar has been // FixIn: 10.0.0.44. // FixIn: 10.14.17.2. |
| 166 |
if ( (jQuery( '#calendar_booking' + response_data['resource_id'] ).length > 0) || (jQuery( '#date_booking' + response_data['resource_id'] ).length > 0) ) { |
| 167 |
var target_elm = jQuery( 'body' ).trigger( "wpbc_calendar_ajx__loaded_data", [response_data[ 'resource_id' ]] ); |
| 168 |
//jQuery( 'body' ).on( 'wpbc_calendar_ajx__loaded_data', function( event, resource_id ) { ... } ); |
| 169 |
} |
| 170 |
|
| 171 |
//jQuery( '#ajax_respond' ).html( response_data ); // For ability to show response, add such DIV element to page |
| 172 |
} |
| 173 |
).fail( function ( jqXHR, textStatus, errorThrown ) { |
| 174 |
wpbc_front_end__log_unexpected_ajax_response( 'WPBC_AJX_CALENDAR_LOAD', jqXHR.responseText || '', jqXHR, textStatus, errorThrown ); |
| 175 |
|
| 176 |
var ajx_post_data__resource_id = wpbc_get_resource_id__from_ajx_post_data_url( this.data ); |
| 177 |
wpbc_balancer__completed( ajx_post_data__resource_id , 'wpbc_calendar__load_data__ajx' ); |
| 178 |
wpbc_calendar__loading__stop( ajx_post_data__resource_id ); |
| 179 |
|
| 180 |
var fallback_error_message = _wpbc.get_message( 'message_unexpected_server_response' ) || 'The server returned an unexpected response. Please reload the page and try again.'; |
| 181 |
var conflict_cache_hint = _wpbc.get_message( 'message_http_conflict_cache_hint' ) || 'A cached or optimized version of this page may be outdated. Clear the browser cache and reload the page. Website administrators should also purge page, server, and CDN caches and regenerate minified or optimized files.'; |
| 182 |
var error_message = wpbc_front_end__get_ajax_error_message( jqXHR, fallback_error_message, conflict_cache_hint ); |
| 183 |
var message_show_delay = 3000; |
| 184 |
|
| 185 |
var jq_node = wpbc_get_calendar__jq_node__for_messages( this.data ); |
| 186 |
|
| 187 |
/** |
| 188 |
* If we make fast clicking on different pages, |
| 189 |
* then under calendar will show error message with empty text, because ajax was not received. |
| 190 |
* To not show such warnings we are set delay in 3 seconds. var message_show_delay = 3000; |
| 191 |
*/ |
| 192 |
var closed_timer = setTimeout( function (){ |
| 193 |
|
| 194 |
// Show Message |
| 195 |
wpbc_front_end__show_message( error_message , { 'type' : 'error', |
| 196 |
'show_here': {'jq_node': jq_node, 'where': 'after'}, |
| 197 |
'is_append': true, |
| 198 |
'style' : 'text-align:left;', |
| 199 |
'css_class':'wpbc_fe_message_alt', |
| 200 |
'content_mode': 'text', |
| 201 |
'delay' : 0 |
| 202 |
} ); |
| 203 |
} , |
| 204 |
parseInt( message_show_delay ) ); |
| 205 |
|
| 206 |
}) |
| 207 |
// .done( function ( data, textStatus, jqXHR ) { if ( window.console && window.console.log ){ console.log( 'second success', data, textStatus, jqXHR ); } }) |
| 208 |
// .always( function ( data_jqXHR, textStatus, jqXHR_errorThrown ) { if ( window.console && window.console.log ){ console.log( 'always finished', data_jqXHR, textStatus, jqXHR_errorThrown ); } }) |
| 209 |
; // End Ajax |
| 210 |
} |
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
// --------------------------------------------------------------------------------------------------------------------- |
| 215 |
// Support |
| 216 |
// --------------------------------------------------------------------------------------------------------------------- |
| 217 |
|
| 218 |
/** |
| 219 |
* Get Calendar jQuery node for showing messages during Ajax |
| 220 |
* This parameter: calendar_request_params[resource_id] parsed from this.data Ajax post data |
| 221 |
* |
| 222 |
* @param ajx_post_data_url_params 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params' |
| 223 |
* @returns {string} ''#calendar_booking1' | '.booking_form_div' ... |
| 224 |
* |
| 225 |
* Example var jq_node = wpbc_get_calendar__jq_node__for_messages( this.data ); |
| 226 |
*/ |
| 227 |
function wpbc_get_calendar__jq_node__for_messages( ajx_post_data_url_params ){ |
| 228 |
|
| 229 |
var jq_node = '.booking_form_div'; |
| 230 |
|
| 231 |
var calendar_resource_id = wpbc_get_resource_id__from_ajx_post_data_url( ajx_post_data_url_params ); |
| 232 |
|
| 233 |
if ( calendar_resource_id > 0 ){ |
| 234 |
jq_node = '#calendar_booking' + calendar_resource_id; |
| 235 |
} |
| 236 |
|
| 237 |
return jq_node; |
| 238 |
} |
| 239 |
|
| 240 |
|
| 241 |
/** |
| 242 |
* Get resource ID from ajx post data url usually from this.data = |
| 243 |
* 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params' |
| 244 |
* |
| 245 |
* @param ajx_post_data_url_params 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params' |
| 246 |
* @returns {int} 1 | 0 (if errror then 0) |
| 247 |
* |
| 248 |
* Example var jq_node = wpbc_get_calendar__jq_node__for_messages( this.data ); |
| 249 |
*/ |
| 250 |
function wpbc_get_resource_id__from_ajx_post_data_url( ajx_post_data_url_params ){ |
| 251 |
|
| 252 |
// Get booking resource ID from Ajax Post Request -> this.data = 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params' |
| 253 |
var calendar_resource_id = wpbc_get_uri_param_by_name( 'calendar_request_params[resource_id]', ajx_post_data_url_params ); |
| 254 |
if ( (null !== calendar_resource_id) && ('' !== calendar_resource_id) ){ |
| 255 |
calendar_resource_id = parseInt( calendar_resource_id ); |
| 256 |
if ( calendar_resource_id > 0 ){ |
| 257 |
return calendar_resource_id; |
| 258 |
} |
| 259 |
} |
| 260 |
return 0; |
| 261 |
} |
| 262 |
|
| 263 |
|
| 264 |
/** |
| 265 |
* Get parameter from URL - parse URL parameters, like this: |
| 266 |
* action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params |
| 267 |
* @param name parameter name, like 'calendar_request_params[resource_id]' |
| 268 |
* @param url 'parameter string URL' |
| 269 |
* @returns {string|null} parameter value |
| 270 |
* |
| 271 |
* Example: wpbc_get_uri_param_by_name( 'calendar_request_params[resource_id]', this.data ); -> '2' |
| 272 |
*/ |
| 273 |
function wpbc_get_uri_param_by_name( name, url ){ |
| 274 |
|
| 275 |
url = decodeURIComponent( url ); |
| 276 |
|
| 277 |
name = name.replace( /[\[\]]/g, '\\$&' ); |
| 278 |
var regex = new RegExp( '[?&]' + name + '(=([^&#]*)|&|#|$)' ), |
| 279 |
results = regex.exec( url ); |
| 280 |
if ( !results ) return null; |
| 281 |
if ( !results[ 2 ] ) return ''; |
| 282 |
return decodeURIComponent( results[ 2 ].replace( /\+/g, ' ' ) ); |
| 283 |
} |
| 284 |
|