PluginProbe
Booking Calendar / 10.10.2
Booking Calendar v10.10.2
11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 All 203 releases
booking / includes / page-availability / _src / availability_page.js

availability_page.js in Booking Calendar 10.10.2, at includes/page-availability/_src/availability_page.js

1,094 lines 44.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2
3 /**
4 * Request Object
5 * Here we can define Search parameters and Update it later, when some parameter was changed
6 *
7 */
8
9 var wpbc_ajx_availability = (function ( obj, $) {
10
11 // Secure parameters for Ajax ------------------------------------------------------------------------------------
12 var p_secure = obj.security_obj = obj.security_obj || {
13 user_id: 0,
14 nonce : '',
15 locale : ''
16 };
17
18 obj.set_secure_param = function ( param_key, param_val ) {
19 p_secure[ param_key ] = param_val;
20 };
21
22 obj.get_secure_param = function ( param_key ) {
23 return p_secure[ param_key ];
24 };
25
26
27 // Listing Search parameters ------------------------------------------------------------------------------------
28 var p_listing = obj.search_request_obj = obj.search_request_obj || {
29 // sort : "booking_id",
30 // sort_type : "DESC",
31 // page_num : 1,
32 // page_items_count: 10,
33 // create_date : "",
34 // keyword : "",
35 // source : ""
36 };
37
38 obj.search_set_all_params = function ( request_param_obj ) {
39 p_listing = request_param_obj;
40 };
41
42 obj.search_get_all_params = function () {
43 return p_listing;
44 };
45
46 obj.search_get_param = function ( param_key ) {
47 return p_listing[ param_key ];
48 };
49
50 obj.search_set_param = function ( param_key, param_val ) {
51 // if ( Array.isArray( param_val ) ){
52 // param_val = JSON.stringify( param_val );
53 // }
54 p_listing[ param_key ] = param_val;
55 };
56
57 obj.search_set_params_arr = function( params_arr ){
58 _.each( params_arr, function ( p_val, p_key, p_data ){ // Define different Search parameters for request
59 this.search_set_param( p_key, p_val );
60 } );
61 }
62
63
64 // Other parameters ------------------------------------------------------------------------------------
65 var p_other = obj.other_obj = obj.other_obj || { };
66
67 obj.set_other_param = function ( param_key, param_val ) {
68 p_other[ param_key ] = param_val;
69 };
70
71 obj.get_other_param = function ( param_key ) {
72 return p_other[ param_key ];
73 };
74
75
76 return obj;
77 }( wpbc_ajx_availability || {}, jQuery ));
78
79 var wpbc_ajx_bookings = [];
80
81 /**
82 * Show Content ---------------------------------------------------------------------------------------------- */
83
84 /**
85 * Show Content - Calendar and UI elements
86 *
87 * @param ajx_data_arr
88 * @param ajx_search_params
89 * @param ajx_cleaned_params
90 */
91 function wpbc_ajx_availability__page_content__show( ajx_data_arr, ajx_search_params , ajx_cleaned_params ){
92
93 var template__availability_main_page_content = wp.template( 'wpbc_ajx_availability_main_page_content' );
94
95 // Content
96 jQuery( wpbc_ajx_availability.get_other_param( 'listing_container' ) ).html( template__availability_main_page_content( {
97 'ajx_data' : ajx_data_arr,
98 'ajx_search_params' : ajx_search_params, // $_REQUEST[ 'search_params' ]
99 'ajx_cleaned_params' : ajx_cleaned_params
100 } ) );
101
102 jQuery( '.wpbc_processing.wpbc_spin').parent().parent().parent().parent( '[id^="wpbc_notice_"]' ).hide();
103 // Load calendar
104 wpbc_ajx_availability__calendar__show( {
105 'resource_id' : ajx_cleaned_params.resource_id,
106 'ajx_nonce_calendar': ajx_data_arr.ajx_nonce_calendar,
107 'ajx_data_arr' : ajx_data_arr,
108 'ajx_cleaned_params' : ajx_cleaned_params
109 } );
110
111
112 /**
113 * Trigger for dates selection in the booking form
114 *
115 * jQuery( wpbc_ajx_availability.get_other_param( 'listing_container' ) ).on('wpbc_page_content_loaded', function(event, ajx_data_arr, ajx_search_params , ajx_cleaned_params) { ... } );
116 */
117 jQuery( wpbc_ajx_availability.get_other_param( 'listing_container' ) ).trigger( 'wpbc_page_content_loaded', [ ajx_data_arr, ajx_search_params , ajx_cleaned_params ] );
118 }
119
120
121 /**
122 * Show inline month view calendar with all predefined CSS (sizes and check in/out, times containers)
123 * @param {obj} calendar_params_arr
124 {
125 'resource_id' : ajx_cleaned_params.resource_id,
126 'ajx_nonce_calendar' : ajx_data_arr.ajx_nonce_calendar,
127 'ajx_data_arr' : ajx_data_arr = { ajx_booking_resources:[], booked_dates: {}, resource_unavailable_dates:[], season_availability:{},.... }
128 'ajx_cleaned_params' : {
129 calendar__days_selection_mode: "dynamic"
130 calendar__start_week_day: "0"
131 calendar__timeslot_day_bg_as_available: ""
132 calendar__view__cell_height: ""
133 calendar__view__months_in_row: 4
134 calendar__view__visible_months: 12
135 calendar__view__width: "100%"
136
137 dates_availability: "unavailable"
138 dates_selection: "2023-03-14 ~ 2023-03-16"
139 do_action: "set_availability"
140 resource_id: 1
141 ui_clicked_element_id: "wpbc_availability_apply_btn"
142 ui_usr__availability_selected_toolbar: "info"
143 }
144 }
145 */
146 function wpbc_ajx_availability__calendar__show( calendar_params_arr ){
147
148 // Update nonce
149 jQuery( '#ajx_nonce_calendar_section' ).html( calendar_params_arr.ajx_nonce_calendar );
150
151 //------------------------------------------------------------------------------------------------------------------
152 // Update bookings
153 if ( 'undefined' == typeof (wpbc_ajx_bookings[ calendar_params_arr.resource_id ]) ){ wpbc_ajx_bookings[ calendar_params_arr.resource_id ] = []; }
154 wpbc_ajx_bookings[ calendar_params_arr.resource_id ] = calendar_params_arr[ 'ajx_data_arr' ][ 'booked_dates' ];
155
156
157 //------------------------------------------------------------------------------------------------------------------
158 /**
159 * Define showing mouse over tooltip on unavailable dates
160 * It's defined, when calendar REFRESHED (change months or days selection) loaded in jquery.datepick.wpbc.9.0.js :
161 * $( 'body' ).trigger( 'wpbc_datepick_inline_calendar_refresh', ... // FixIn: 9.4.4.13.
162 */
163 jQuery( 'body' ).on( 'wpbc_datepick_inline_calendar_refresh', function ( event, resource_id, inst ){
164 // inst.dpDiv it's: <div class="datepick-inline datepick-multi" style="width: 17712px;">....</div>
165 inst.dpDiv.find( '.season_unavailable,.before_after_unavailable,.weekdays_unavailable' ).on( 'mouseover', function ( this_event ){
166 // also available these vars: resource_id, jCalContainer, inst
167 var jCell = jQuery( this_event.currentTarget );
168 wpbc_avy__show_tooltip__for_element( jCell, calendar_params_arr[ 'ajx_data_arr' ]['popover_hints'] );
169 });
170
171 } );
172
173 //------------------------------------------------------------------------------------------------------------------
174 /**
175 * Define height of the calendar cells, and mouse over tooltips at some unavailable dates
176 * It's defined, when calendar loaded in jquery.datepick.wpbc.9.0.js :
177 * $( 'body' ).trigger( 'wpbc_datepick_inline_calendar_loaded', ... // FixIn: 9.4.4.12.
178 */
179 jQuery( 'body' ).on( 'wpbc_datepick_inline_calendar_loaded', function ( event, resource_id, jCalContainer, inst ){
180
181 // Remove highlight day for today date
182 jQuery( '.datepick-days-cell.datepick-today.datepick-days-cell-over' ).removeClass( 'datepick-days-cell-over' );
183
184 // Set height of calendar cells if defined this option
185 if ( '' !== calendar_params_arr.ajx_cleaned_params.calendar__view__cell_height ){
186 jQuery( 'head' ).append( '<style type="text/css">'
187 + '.hasDatepick .datepick-inline .datepick-title-row th, '
188 + '.hasDatepick .datepick-inline .datepick-days-cell {'
189 + 'height: ' + calendar_params_arr.ajx_cleaned_params.calendar__view__cell_height + ' !important;'
190 + '}'
191 +'</style>' );
192 }
193
194 // Define showing mouse over tooltip on unavailable dates
195 jCalContainer.find( '.season_unavailable,.before_after_unavailable,.weekdays_unavailable' ).on( 'mouseover', function ( this_event ){
196 // also available these vars: resource_id, jCalContainer, inst
197 var jCell = jQuery( this_event.currentTarget );
198 wpbc_avy__show_tooltip__for_element( jCell, calendar_params_arr[ 'ajx_data_arr' ]['popover_hints'] );
199 });
200 } );
201
202 //------------------------------------------------------------------------------------------------------------------
203 // Define width of entire calendar
204 var width = 'width:' + calendar_params_arr.ajx_cleaned_params.calendar__view__width + ';'; // var width = 'width:100%;max-width:100%;';
205
206 if ( ( undefined != calendar_params_arr.ajx_cleaned_params.calendar__view__max_width )
207 && ( '' != calendar_params_arr.ajx_cleaned_params.calendar__view__max_width )
208 ){
209 width += 'max-width:' + calendar_params_arr.ajx_cleaned_params.calendar__view__max_width + ';';
210 } else {
211 width += 'max-width:' + ( calendar_params_arr.ajx_cleaned_params.calendar__view__months_in_row * 341 ) + 'px;';
212 }
213
214 //------------------------------------------------------------------------------------------------------------------
215 // Add calendar container: "Calendar is loading..." and textarea
216 jQuery( '.wpbc_ajx_avy__calendar' ).html(
217
218 '<div class="' + ' bk_calendar_frame'
219 + ' months_num_in_row_' + calendar_params_arr.ajx_cleaned_params.calendar__view__months_in_row
220 + ' cal_month_num_' + calendar_params_arr.ajx_cleaned_params.calendar__view__visible_months
221 + ' ' + calendar_params_arr.ajx_cleaned_params.calendar__timeslot_day_bg_as_available // 'wpbc_timeslot_day_bg_as_available' || ''
222 + '" '
223 + 'style="' + width + '">'
224
225 + '<div id="calendar_booking' + calendar_params_arr.resource_id + '">' + 'Calendar is loading...' + '</div>'
226
227 + '</div>'
228
229 + '<textarea id="date_booking' + calendar_params_arr.resource_id + '"'
230 + ' name="date_booking' + calendar_params_arr.resource_id + '"'
231 + ' autocomplete="off"'
232 + ' style="display:none;width:100%;height:10em;margin:2em 0 0;"></textarea>'
233 );
234
235 //------------------------------------------------------------------------------------------------------------------
236 var cal_param_arr = {
237 'html_id' : 'calendar_booking' + calendar_params_arr.ajx_cleaned_params.resource_id,
238 'text_id' : 'date_booking' + calendar_params_arr.ajx_cleaned_params.resource_id,
239
240 'calendar__start_week_day': calendar_params_arr.ajx_cleaned_params.calendar__start_week_day,
241 'calendar__view__visible_months': calendar_params_arr.ajx_cleaned_params.calendar__view__visible_months,
242 'calendar__days_selection_mode': calendar_params_arr.ajx_cleaned_params.calendar__days_selection_mode,
243
244 'resource_id' : calendar_params_arr.ajx_cleaned_params.resource_id,
245 'ajx_nonce_calendar' : calendar_params_arr.ajx_data_arr.ajx_nonce_calendar,
246 'booked_dates' : calendar_params_arr.ajx_data_arr.booked_dates,
247 'season_availability': calendar_params_arr.ajx_data_arr.season_availability,
248
249 'resource_unavailable_dates' : calendar_params_arr.ajx_data_arr.resource_unavailable_dates,
250
251 'popover_hints': calendar_params_arr[ 'ajx_data_arr' ]['popover_hints'] // {'season_unavailable':'...','weekdays_unavailable':'...','before_after_unavailable':'...',}
252 };
253 wpbc_show_inline_booking_calendar( cal_param_arr );
254
255 //------------------------------------------------------------------------------------------------------------------
256 /**
257 * On click AVAILABLE | UNAVAILABLE button in widget - need to change help dates text
258 */
259 jQuery( '.wpbc_radio__set_days_availability' ).on('change', function ( event, resource_id, inst ){
260 wpbc__inline_booking_calendar__on_days_select( jQuery( '#' + cal_param_arr.text_id ).val() , cal_param_arr );
261 });
262
263 // Show 'Select days in calendar then select Available / Unavailable status and click Apply availability button.'
264 jQuery( '#wpbc_toolbar_dates_hint').html( '<div class="ui_element"><span class="wpbc_ui_control wpbc_ui_addon wpbc_help_text" >'
265 + cal_param_arr.popover_hints.toolbar_text
266 + '</span></div>'
267 );
268 }
269
270
271 /**
272 * Load Datepick Inline calendar
273 *
274 * @param calendar_params_arr example:{
275 'html_id' : 'calendar_booking' + calendar_params_arr.ajx_cleaned_params.resource_id,
276 'text_id' : 'date_booking' + calendar_params_arr.ajx_cleaned_params.resource_id,
277
278 'calendar__start_week_day': calendar_params_arr.ajx_cleaned_params.calendar__start_week_day,
279 'calendar__view__visible_months': calendar_params_arr.ajx_cleaned_params.calendar__view__visible_months,
280 'calendar__days_selection_mode': calendar_params_arr.ajx_cleaned_params.calendar__days_selection_mode,
281
282 'resource_id' : calendar_params_arr.ajx_cleaned_params.resource_id,
283 'ajx_nonce_calendar' : calendar_params_arr.ajx_data_arr.ajx_nonce_calendar,
284 'booked_dates' : calendar_params_arr.ajx_data_arr.booked_dates,
285 'season_availability': calendar_params_arr.ajx_data_arr.season_availability,
286
287 'resource_unavailable_dates' : calendar_params_arr.ajx_data_arr.resource_unavailable_dates
288 }
289 * @returns {boolean}
290 */
291 function wpbc_show_inline_booking_calendar( calendar_params_arr ){
292
293 if (
294 ( 0 === jQuery( '#' + calendar_params_arr.html_id ).length ) // If calendar DOM element not exist then exist
295 || ( true === jQuery( '#' + calendar_params_arr.html_id ).hasClass( 'hasDatepick' ) ) // If the calendar with the same Booking resource already has been activated, then exist.
296 ){
297 return false;
298 }
299
300 //------------------------------------------------------------------------------------------------------------------
301 // Configure and show calendar
302 jQuery( '#' + calendar_params_arr.html_id ).text( '' );
303 jQuery( '#' + calendar_params_arr.html_id ).datepick({
304 beforeShowDay: function ( date ){
305 return wpbc__inline_booking_calendar__apply_css_to_days( date, calendar_params_arr, this );
306 },
307 onSelect: function ( date ){
308 jQuery( '#' + calendar_params_arr.text_id ).val( date );
309 //wpbc_blink_element('.wpbc_widget_available_unavailable', 3, 220);
310 return wpbc__inline_booking_calendar__on_days_select( date, calendar_params_arr, this );
311 },
312 onHover: function ( value, date ){
313
314 //wpbc_avy__prepare_tooltip__in_calendar( value, date, calendar_params_arr, this );
315
316 return wpbc__inline_booking_calendar__on_days_hover( value, date, calendar_params_arr, this );
317 },
318 onChangeMonthYear: null,
319 showOn: 'both',
320 numberOfMonths: calendar_params_arr.calendar__view__visible_months,
321 stepMonths: 1,
322 // prevText: '&laquo;',
323 // nextText: '&raquo;',
324 prevText : '&lsaquo;',
325 nextText : '&rsaquo;',
326 dateFormat: 'yy-mm-dd',// 'dd.mm.yy',
327 changeMonth: false,
328 changeYear: false,
329 minDate: 0, //null, //Scroll as long as you need
330 maxDate: '10y', // minDate: new Date(2020, 2, 1), maxDate: new Date(2020, 9, 31), // Ability to set any start and end date in calendar
331 showStatus: false,
332 closeAtTop: false,
333 firstDay: calendar_params_arr.calendar__start_week_day,
334 gotoCurrent: false,
335 hideIfNoPrevNext: true,
336 multiSeparator: ', ',
337 multiSelect: (('dynamic' == calendar_params_arr.calendar__days_selection_mode) ? 0 : 365), // Maximum number of selectable dates: Single day = 0, multi days = 365
338 rangeSelect: ('dynamic' == calendar_params_arr.calendar__days_selection_mode),
339 rangeSeparator: ' ~ ', //' - ',
340 // showWeeks: true,
341 useThemeRoller: false
342 }
343 );
344
345 return true;
346 }
347
348
349 /**
350 * Apply CSS to calendar date cells
351 *
352 * @param date - JavaScript Date Obj: Mon Dec 11 2023 00:00:00 GMT+0200 (Eastern European Standard Time)
353 * @param calendar_params_arr - Calendar Settings Object: {
354 "html_id": "calendar_booking4",
355 "text_id": "date_booking4",
356 "calendar__start_week_day": 1,
357 "calendar__view__visible_months": 12,
358 "resource_id": 4,
359 "ajx_nonce_calendar": "<input type=\"hidden\" ... />",
360 "booked_dates": {
361 "12-28-2022": [
362 {
363 "booking_date": "2022-12-28 00:00:00",
364 "approved": "1",
365 "booking_id": "26"
366 }
367 ], ...
368 }
369 'season_availability':{
370 "2023-01-09": true,
371 "2023-01-10": true,
372 "2023-01-11": true, ...
373 }
374 }
375 }
376 * @param datepick_this - this of datepick Obj
377 *
378 * @returns [boolean,string] - [ {true -available | false - unavailable}, 'CSS classes for calendar day cell' ]
379 */
380 function wpbc__inline_booking_calendar__apply_css_to_days( date, calendar_params_arr, datepick_this ){
381
382 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 );
383 var real_today_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 ], 0, 0, 0 );
384
385 var class_day = ( date.getMonth() + 1 ) + '-' + date.getDate() + '-' + date.getFullYear(); // '1-9-2023'
386 var sql_class_day = wpbc__get__sql_class_date( date ); // '2023-01-09'
387
388 var css_date__standard = 'cal4date-' + class_day;
389 var css_date__additional = ' wpbc_weekday_' + date.getDay() + ' ';
390
391 //--------------------------------------------------------------------------------------------------------------
392
393 // WEEKDAYS :: Set unavailable week days from - Settings General page in "Availability" section
394 for ( var i = 0; i < _wpbc.get_other_param( 'availability__week_days_unavailable' ).length; i++ ){
395 if ( date.getDay() == _wpbc.get_other_param( 'availability__week_days_unavailable' )[ i ] ) {
396 return [ !!false, css_date__standard + ' date_user_unavailable' + ' weekdays_unavailable' ];
397 }
398 }
399 // 10.9.6.3.
400 var date_midnight = new Date( parseInt( date.getFullYear() ), (parseInt( date.getMonth() ) - 0), parseInt( date.getDate() ), 0, 0, 0 );
401 // BEFORE_AFTER :: Set unavailable days Before / After the Today date.
402 //if ( ((wpbc_dates__days_between( date, real_today_date )) < parseInt( _wpbc.get_other_param( 'availability__unavailable_from_today' ) ))
403 if (
404 ( (today_date.getTime() - date_midnight.getTime() ) > 0 )
405 || (
406 (parseInt( '0' + parseInt( _wpbc.get_other_param( 'availability__available_from_today' ) ) ) > 0)
407 && (wpbc_dates__days_between( date_midnight, real_today_date ) >= parseInt( '0' + parseInt( _wpbc.get_other_param( 'availability__available_from_today' ) ) ))
408 )
409 ) {
410 return [ false, css_date__standard + ' date_user_unavailable' + ' before_after_unavailable' ];
411 }
412
413 // SEASONS :: Booking > Resources > Availability page
414 var is_date_available = calendar_params_arr.season_availability[ sql_class_day ];
415 if ( false === is_date_available ){ // FixIn: 9.5.4.4.
416 return [ !!false, css_date__standard + ' date_user_unavailable' + ' season_unavailable' ];
417 }
418
419 // RESOURCE_UNAVAILABLE :: Booking > Availability page
420 if ( wpbc_in_array(calendar_params_arr.resource_unavailable_dates, sql_class_day ) ){
421 is_date_available = false;
422 }
423 if ( false === is_date_available ){ // FixIn: 9.5.4.4.
424 return [ !false, css_date__standard + ' date_user_unavailable' + ' resource_unavailable' ];
425 }
426
427 //--------------------------------------------------------------------------------------------------------------
428
429 //--------------------------------------------------------------------------------------------------------------
430
431
432 // Is any bookings in this date ?
433 if ( 'undefined' !== typeof( calendar_params_arr.booked_dates[ class_day ] ) ) {
434
435 var bookings_in_date = calendar_params_arr.booked_dates[ class_day ];
436
437
438 if ( 'undefined' !== typeof( bookings_in_date[ 'sec_0' ] ) ) { // "Full day" booking -> (seconds == 0)
439
440 css_date__additional += ( '0' === bookings_in_date[ 'sec_0' ].approved ) ? ' date2approve ' : ' date_approved '; // Pending = '0' | Approved = '1'
441 css_date__additional += ' full_day_booking';
442
443 return [ !false, css_date__standard + css_date__additional ];
444
445 } else if ( Object.keys( bookings_in_date ).length > 0 ){ // "Time slots" Bookings
446
447 var is_approved = true;
448
449 _.each( bookings_in_date, function ( p_val, p_key, p_data ) {
450 if ( !parseInt( p_val.approved ) ){
451 is_approved = false;
452 }
453 var ts = p_val.booking_date.substring( p_val.booking_date.length - 1 );
454 if ( true === _wpbc.get_other_param( 'is_enabled_change_over' ) ){
455 if ( ts == '1' ) { css_date__additional += ' check_in_time' + ((parseInt(p_val.approved)) ? ' check_in_time_date_approved' : ' check_in_time_date2approve'); }
456 if ( ts == '2' ) { css_date__additional += ' check_out_time' + ((parseInt(p_val.approved)) ? ' check_out_time_date_approved' : ' check_out_time_date2approve'); }
457 }
458
459 });
460
461 if ( ! is_approved ){
462 css_date__additional += ' date2approve timespartly'
463 } else {
464 css_date__additional += ' date_approved timespartly'
465 }
466
467 if ( ! _wpbc.get_other_param( 'is_enabled_change_over' ) ){
468 css_date__additional += ' times_clock'
469 }
470
471 }
472
473 }
474
475 //--------------------------------------------------------------------------------------------------------------
476
477 return [ true, css_date__standard + css_date__additional + ' date_available' ];
478 }
479
480
481 /**
482 * Apply some CSS classes, when we mouse over specific dates in calendar
483 * @param value
484 * @param date - JavaScript Date Obj: Mon Dec 11 2023 00:00:00 GMT+0200 (Eastern European Standard Time)
485 * @param calendar_params_arr - Calendar Settings Object: {
486 "html_id": "calendar_booking4",
487 "text_id": "date_booking4",
488 "calendar__start_week_day": 1,
489 "calendar__view__visible_months": 12,
490 "resource_id": 4,
491 "ajx_nonce_calendar": "<input type=\"hidden\" ... />",
492 "booked_dates": {
493 "12-28-2022": [
494 {
495 "booking_date": "2022-12-28 00:00:00",
496 "approved": "1",
497 "booking_id": "26"
498 }
499 ], ...
500 }
501 'season_availability':{
502 "2023-01-09": true,
503 "2023-01-10": true,
504 "2023-01-11": true, ...
505 }
506 }
507 }
508 * @param datepick_this - this of datepick Obj
509 *
510 * @returns {boolean}
511 */
512 function wpbc__inline_booking_calendar__on_days_hover( value, date, calendar_params_arr, datepick_this ){
513
514 if ( null === date ){
515 jQuery( '.datepick-days-cell-over' ).removeClass( 'datepick-days-cell-over' ); // clear all highlight days selections
516 return false;
517 }
518
519 var inst = jQuery.datepick._getInst( document.getElementById( 'calendar_booking' + calendar_params_arr.resource_id ) );
520
521 if (
522 ( 1 == inst.dates.length) // If we have one selected date
523 && ('dynamic' === calendar_params_arr.calendar__days_selection_mode) // while have range days selection mode
524 ){
525
526 var td_class;
527 var td_overs = [];
528 var is_check = true;
529 var selceted_first_day = new Date();
530 selceted_first_day.setFullYear(inst.dates[0].getFullYear(),(inst.dates[0].getMonth()), (inst.dates[0].getDate() ) ); //Get first Date
531
532 while( is_check ){
533
534 td_class = (selceted_first_day.getMonth() + 1) + '-' + selceted_first_day.getDate() + '-' + selceted_first_day.getFullYear();
535
536 td_overs[ td_overs.length ] = '#calendar_booking' + calendar_params_arr.resource_id + ' .cal4date-' + td_class; // add to array for later make selection by class
537
538 if (
539 ( ( date.getMonth() == selceted_first_day.getMonth() ) &&
540 ( date.getDate() == selceted_first_day.getDate() ) &&
541 ( date.getFullYear() == selceted_first_day.getFullYear() )
542 ) || ( selceted_first_day > date )
543 ){
544 is_check = false;
545 }
546
547 selceted_first_day.setFullYear( selceted_first_day.getFullYear(), (selceted_first_day.getMonth()), (selceted_first_day.getDate() + 1) );
548 }
549
550 // Highlight Days
551 for ( var i=0; i < td_overs.length ; i++) { // add class to all elements
552 jQuery( td_overs[i] ).addClass('datepick-days-cell-over');
553 }
554 return true;
555
556 }
557
558 return true;
559 }
560
561
562 /**
563 * On DAYs selection in calendar
564 *
565 * @param dates_selection - string: '2023-03-07 ~ 2023-03-07' or '2023-04-10, 2023-04-12, 2023-04-02, 2023-04-04'
566 * @param calendar_params_arr - Calendar Settings Object: {
567 "html_id": "calendar_booking4",
568 "text_id": "date_booking4",
569 "calendar__start_week_day": 1,
570 "calendar__view__visible_months": 12,
571 "resource_id": 4,
572 "ajx_nonce_calendar": "<input type=\"hidden\" ... />",
573 "booked_dates": {
574 "12-28-2022": [
575 {
576 "booking_date": "2022-12-28 00:00:00",
577 "approved": "1",
578 "booking_id": "26"
579 }
580 ], ...
581 }
582 'season_availability':{
583 "2023-01-09": true,
584 "2023-01-10": true,
585 "2023-01-11": true, ...
586 }
587 }
588 }
589 * @param datepick_this - this of datepick Obj
590 *
591 * @returns boolean
592 */
593 function wpbc__inline_booking_calendar__on_days_select( dates_selection, calendar_params_arr, datepick_this = null ){
594
595 var inst = jQuery.datepick._getInst( document.getElementById( 'calendar_booking' + calendar_params_arr.resource_id ) );
596
597 var dates_arr = []; // [ "2023-04-09", "2023-04-10", "2023-04-11" ]
598
599 if ( -1 !== dates_selection.indexOf( '~' ) ) { // Range Days
600
601 dates_arr = wpbc_get_dates_arr__from_dates_range_js( {
602 'dates_separator' : ' ~ ', // ' ~ '
603 'dates' : dates_selection, // '2023-04-04 ~ 2023-04-07'
604 } );
605
606 } else { // Multiple Days
607 dates_arr = wpbc_get_dates_arr__from_dates_comma_separated_js( {
608 'dates_separator' : ', ', // ', '
609 'dates' : dates_selection, // '2023-04-10, 2023-04-12, 2023-04-02, 2023-04-04'
610 } );
611 }
612
613 wpbc_avy_after_days_selection__show_help_info({
614 'calendar__days_selection_mode': calendar_params_arr.calendar__days_selection_mode,
615 'dates_arr' : dates_arr,
616 'dates_click_num' : inst.dates.length,
617 'popover_hints' : calendar_params_arr.popover_hints
618 } );
619 return true;
620 }
621
622 /**
623 * Show help info at the top toolbar about selected dates and future actions
624 *
625 * @param params
626 * Example 1: {
627 calendar__days_selection_mode: "dynamic",
628 dates_arr: [ "2023-04-03" ],
629 dates_click_num: 1
630 'popover_hints' : calendar_params_arr.popover_hints
631 }
632 * Example 2: {
633 calendar__days_selection_mode: "dynamic"
634 dates_arr: Array(10) [ "2023-04-03", "2023-04-04", "2023-04-05", … ]
635 dates_click_num: 2
636 'popover_hints' : calendar_params_arr.popover_hints
637 }
638 */
639 function wpbc_avy_after_days_selection__show_help_info( params ){
640 // console.log( params ); // [ "2023-04-09", "2023-04-10", "2023-04-11" ]
641
642 var message, color;
643 if (jQuery( '#ui_btn_avy__set_days_availability__available').is(':checked')){
644 message = params.popover_hints.toolbar_text_available;//'Set dates _DATES_ as _HTML_ available.';
645 color = '#11be4c';
646 } else {
647 message = params.popover_hints.toolbar_text_unavailable;//'Set dates _DATES_ as _HTML_ unavailable.';
648 color = '#e43939';
649 }
650
651 message = '<span>' + message + '</span>';
652
653 var first_date = params[ 'dates_arr' ][ 0 ];
654 var last_date = ( 'dynamic' == params.calendar__days_selection_mode )
655 ? params[ 'dates_arr' ][ (params[ 'dates_arr' ].length - 1) ]
656 : ( params[ 'dates_arr' ].length > 1 ) ? params[ 'dates_arr' ][ 1 ] : '';
657
658 first_date = jQuery.datepick.formatDate( 'dd M, yy', new Date( first_date + 'T00:00:00' ) );
659 last_date = jQuery.datepick.formatDate( 'dd M, yy', new Date( last_date + 'T00:00:00' ) );
660
661
662 if ( 'dynamic' == params.calendar__days_selection_mode ){
663 if ( 1 == params.dates_click_num ){
664 last_date = '___________'
665 } else {
666 if ( 'first_time' == jQuery( '.wpbc_ajx_availability_container' ).attr( 'wpbc_loaded' ) ){
667 jQuery( '.wpbc_ajx_availability_container' ).attr( 'wpbc_loaded', 'done' )
668 wpbc_blink_element( '.wpbc_widget_available_unavailable', 3, 220 );
669 }
670 }
671 message = message.replace( '_DATES_', '</span>'
672 //+ '<div>' + 'from' + '</div>'
673 + '<span class="wpbc_big_date">' + first_date + '</span>'
674 + '<span>' + '-' + '</span>'
675 + '<span class="wpbc_big_date">' + last_date + '</span>'
676 + '<span>' );
677 } else {
678 // if ( params[ 'dates_arr' ].length > 1 ){
679 // last_date = ', ' + last_date;
680 // last_date += ( params[ 'dates_arr' ].length > 2 ) ? ', ...' : '';
681 // } else {
682 // last_date='';
683 // }
684 var dates_arr = [];
685 for( var i = 0; i < params[ 'dates_arr' ].length; i++ ){
686 dates_arr.push( jQuery.datepick.formatDate( 'dd M yy', new Date( params[ 'dates_arr' ][ i ] + 'T00:00:00' ) ) );
687 }
688 first_date = dates_arr.join( ', ' );
689 message = message.replace( '_DATES_', '</span>'
690 + '<span class="wpbc_big_date">' + first_date + '</span>'
691 + '<span>' );
692 }
693 message = message.replace( '_HTML_' , '</span><span class="wpbc_big_text" style="color:'+color+';">') + '<span>';
694
695 //message += ' <div style="margin-left: 1em;">' + ' Click on Apply button to apply availability.' + '</div>';
696
697 message = '<div class="wpbc_toolbar_dates_hints">' + message + '</div>';
698
699 jQuery( '.wpbc_help_text' ).html( message );
700 }
701
702 /**
703 * Parse dates ------------------------------------------------------------------------------------------- */
704
705 /**
706 * Get dates array, from comma separated dates
707 *
708 * @param params = {
709 * 'dates_separator' => ', ', // Dates separator
710 * 'dates' => '2023-04-04, 2023-04-07, 2023-04-05' // Dates in 'Y-m-d' format: '2023-01-31'
711 }
712 *
713 * @return array = [
714 * [0] => 2023-04-04
715 * [1] => 2023-04-05
716 * [2] => 2023-04-06
717 * [3] => 2023-04-07
718 ]
719 *
720 * Example #1: wpbc_get_dates_arr__from_dates_comma_separated_js( { 'dates_separator' : ', ', 'dates' : '2023-04-04, 2023-04-07, 2023-04-05' } );
721 */
722 function wpbc_get_dates_arr__from_dates_comma_separated_js( params ){
723
724 var dates_arr = [];
725
726 if ( '' !== params[ 'dates' ] ){
727
728 dates_arr = params[ 'dates' ].split( params[ 'dates_separator' ] );
729
730 dates_arr.sort();
731 }
732 return dates_arr;
733 }
734
735 /**
736 * Get dates array, from range days selection
737 *
738 * @param params = {
739 * 'dates_separator' => ' ~ ', // Dates separator
740 * 'dates' => '2023-04-04 ~ 2023-04-07' // Dates in 'Y-m-d' format: '2023-01-31'
741 }
742 *
743 * @return array = [
744 * [0] => 2023-04-04
745 * [1] => 2023-04-05
746 * [2] => 2023-04-06
747 * [3] => 2023-04-07
748 ]
749 *
750 * Example #1: wpbc_get_dates_arr__from_dates_range_js( { 'dates_separator' : ' ~ ', 'dates' : '2023-04-04 ~ 2023-04-07' } );
751 * Example #2: wpbc_get_dates_arr__from_dates_range_js( { 'dates_separator' : ' - ', 'dates' : '2023-04-04 - 2023-04-07' } );
752 */
753 function wpbc_get_dates_arr__from_dates_range_js( params ){
754
755 var dates_arr = [];
756
757 if ( '' !== params['dates'] ) {
758
759 dates_arr = params[ 'dates' ].split( params[ 'dates_separator' ] );
760 var check_in_date_ymd = dates_arr[0];
761 var check_out_date_ymd = dates_arr[1];
762
763 if ( ('' !== check_in_date_ymd) && ('' !== check_out_date_ymd) ){
764
765 dates_arr = wpbc_get_dates_array_from_start_end_days_js( check_in_date_ymd, check_out_date_ymd );
766 }
767 }
768 return dates_arr;
769 }
770
771 /**
772 * Get dates array based on start and end dates.
773 *
774 * @param string sStartDate - start date: 2023-04-09
775 * @param string sEndDate - end date: 2023-04-11
776 * @return array - [ "2023-04-09", "2023-04-10", "2023-04-11" ]
777 */
778 function wpbc_get_dates_array_from_start_end_days_js( sStartDate, sEndDate ){
779
780 sStartDate = new Date( sStartDate + 'T00:00:00' );
781 sEndDate = new Date( sEndDate + 'T00:00:00' );
782
783 var aDays=[];
784
785 // Start the variable off with the start date
786 aDays.push( sStartDate.getTime() );
787
788 // Set a 'temp' variable, sCurrentDate, with the start date - before beginning the loop
789 var sCurrentDate = new Date( sStartDate.getTime() );
790 var one_day_duration = 24*60*60*1000;
791
792 // While the current date is less than the end date
793 while(sCurrentDate < sEndDate){
794 // Add a day to the current date "+1 day"
795 sCurrentDate.setTime( sCurrentDate.getTime() + one_day_duration );
796
797 // Add this new day to the aDays array
798 aDays.push( sCurrentDate.getTime() );
799 }
800
801 for (let i = 0; i < aDays.length; i++) {
802 aDays[ i ] = new Date( aDays[i] );
803 aDays[ i ] = aDays[ i ].getFullYear()
804 + '-' + (( (aDays[ i ].getMonth() + 1) < 10) ? '0' : '') + (aDays[ i ].getMonth() + 1)
805 + '-' + (( aDays[ i ].getDate() < 10) ? '0' : '') + aDays[ i ].getDate();
806 }
807 // Once the loop has finished, return the array of days.
808 return aDays;
809 }
810
811
812
813 /**
814 * Tooltips ---------------------------------------------------------------------------------------------- */
815
816 /**
817 * Define showing tooltip, when mouse over on SELECTABLE (available, pending, approved, resource unavailable), days
818 * Can be called directly from datepick init function.
819 *
820 * @param value
821 * @param date
822 * @param calendar_params_arr
823 * @param datepick_this
824 * @returns {boolean}
825 */
826 function wpbc_avy__prepare_tooltip__in_calendar( value, date, calendar_params_arr, datepick_this ){
827
828 if ( null == date ){ return false; }
829
830 var td_class = ( date.getMonth() + 1 ) + '-' + date.getDate() + '-' + date.getFullYear();
831
832 var jCell = jQuery( '#calendar_booking' + calendar_params_arr.resource_id + ' td.cal4date-' + td_class );
833
834 wpbc_avy__show_tooltip__for_element( jCell, calendar_params_arr[ 'popover_hints' ] );
835 return true;
836 }
837
838
839 /**
840 * Define tooltip for showing on UNAVAILABLE days (season, weekday, today_depends unavailable)
841 *
842 * @param jCell jQuery of specific day cell
843 * @param popover_hints Array with tooltip hint texts : {'season_unavailable':'...','weekdays_unavailable':'...','before_after_unavailable':'...',}
844 */
845 function wpbc_avy__show_tooltip__for_element( jCell, popover_hints ){
846
847 var tooltip_time = '';
848
849 if ( jCell.hasClass( 'season_unavailable' ) ){
850 tooltip_time = popover_hints[ 'season_unavailable' ];
851 } else if ( jCell.hasClass( 'weekdays_unavailable' ) ){
852 tooltip_time = popover_hints[ 'weekdays_unavailable' ];
853 } else if ( jCell.hasClass( 'before_after_unavailable' ) ){
854 tooltip_time = popover_hints[ 'before_after_unavailable' ];
855 } else if ( jCell.hasClass( 'date2approve' ) ){
856
857 } else if ( jCell.hasClass( 'date_approved' ) ){
858
859 } else {
860
861 }
862
863 jCell.attr( 'data-content', tooltip_time );
864
865 var td_el = jCell.get(0); //jQuery( '#calendar_booking' + calendar_params_arr.resource_id + ' td.cal4date-' + td_class ).get(0);
866
867 if ( ( undefined == td_el._tippy ) && ( '' != tooltip_time ) ){
868
869 wpbc_tippy( td_el , {
870 content( reference ){
871
872 var popover_content = reference.getAttribute( 'data-content' );
873
874 return '<div class="popover popover_tippy">'
875 + '<div class="popover-content">'
876 + popover_content
877 + '</div>'
878 + '</div>';
879 },
880 allowHTML : true,
881 trigger : 'mouseenter focus',
882 interactive : ! true,
883 hideOnClick : true,
884 interactiveBorder: 10,
885 maxWidth : 550,
886 theme : 'wpbc-tippy-times',
887 placement : 'top',
888 delay : [400, 0], // FixIn: 9.4.2.2.
889 ignoreAttributes : true,
890 touch : true, //['hold', 500], // 500ms delay // FixIn: 9.2.1.5.
891 appendTo: () => document.body,
892 });
893 }
894 }
895
896
897
898
899
900 /**
901 * Ajax ------------------------------------------------------------------------------------------------------ */
902
903 /**
904 * Send Ajax show request
905 */
906 function wpbc_ajx_availability__ajax_request(){
907
908 console.groupCollapsed( 'WPBC_AJX_AVAILABILITY' ); console.log( ' == Before Ajax Send - search_get_all_params() == ' , wpbc_ajx_availability.search_get_all_params() );
909
910 wpbc_availability_reload_button__spin_start();
911
912 // Start Ajax
913 jQuery.post( wpbc_url_ajax,
914 {
915 action : 'WPBC_AJX_AVAILABILITY',
916 wpbc_ajx_user_id: wpbc_ajx_availability.get_secure_param( 'user_id' ),
917 nonce : wpbc_ajx_availability.get_secure_param( 'nonce' ),
918 wpbc_ajx_locale : wpbc_ajx_availability.get_secure_param( 'locale' ),
919
920 search_params : wpbc_ajx_availability.search_get_all_params()
921 },
922 /**
923 * S u c c e s s
924 *
925 * @param response_data - its object returned from Ajax - class-live-searcg.php
926 * @param textStatus - 'success'
927 * @param jqXHR - Object
928 */
929 function ( response_data, textStatus, jqXHR ) {
930
931 console.log( ' == Response WPBC_AJX_AVAILABILITY == ', response_data ); console.groupEnd();
932
933 // Probably Error
934 if ( (typeof response_data !== 'object') || (response_data === null) ){
935
936 wpbc_ajx_availability__show_message( response_data );
937
938 return;
939 }
940
941 // Reload page, after filter toolbar has been reset
942 if ( ( undefined != response_data[ 'ajx_cleaned_params' ])
943 && ( 'reset_done' === response_data[ 'ajx_cleaned_params' ][ 'do_action' ])
944 ){
945 location.reload();
946 return;
947 }
948
949 // Show listing
950 wpbc_ajx_availability__page_content__show( response_data[ 'ajx_data' ], response_data[ 'ajx_search_params' ] , response_data[ 'ajx_cleaned_params' ] );
951
952 //wpbc_ajx_availability__define_ui_hooks(); // Redefine Hooks, because we show new DOM elements
953 if ( '' != response_data[ 'ajx_data' ][ 'ajx_after_action_message' ].replace( /\n/g, "<br />" ) ){
954 wpbc_admin_show_message(
955 response_data[ 'ajx_data' ][ 'ajx_after_action_message' ].replace( /\n/g, "<br />" )
956 , ( '1' == response_data[ 'ajx_data' ][ 'ajx_after_action_result' ] ) ? 'success' : 'error'
957 , 10000
958 );
959 }
960
961 wpbc_availability_reload_button__spin_pause();
962 // Remove spin icon from button and Enable this button.
963 wpbc_button__remove_spin( response_data[ 'ajx_cleaned_params' ][ 'ui_clicked_element_id' ] )
964
965 jQuery( '#ajax_respond' ).html( response_data ); // For ability to show response, add such DIV element to page
966 }
967 ).fail( function ( jqXHR, textStatus, errorThrown ) { if ( window.console && window.console.log ){ console.log( 'Ajax_Error', jqXHR, textStatus, errorThrown ); }
968
969 var error_message = '<strong>' + 'Error!' + '</strong> ' + errorThrown ;
970 if ( jqXHR.status ){
971 error_message += ' (<b>' + jqXHR.status + '</b>)';
972 if (403 == jqXHR.status ){
973 error_message += ' Probably nonce for this page has been expired. Please <a href="javascript:void(0)" onclick="javascript:location.reload();">reload the page</a>.';
974 }
975 }
976 if ( jqXHR.responseText ){
977 error_message += ' ' + jqXHR.responseText;
978 }
979 error_message = error_message.replace( /\n/g, "<br />" );
980
981 wpbc_ajx_availability__show_message( error_message );
982 })
983 // .done( function ( data, textStatus, jqXHR ) { if ( window.console && window.console.log ){ console.log( 'second success', data, textStatus, jqXHR ); } })
984 // .always( function ( data_jqXHR, textStatus, jqXHR_errorThrown ) { if ( window.console && window.console.log ){ console.log( 'always finished', data_jqXHR, textStatus, jqXHR_errorThrown ); } })
985 ; // End Ajax
986
987 }
988
989
990
991 /**
992 * H o o k s - its Action/Times when need to re-Render Views ----------------------------------------------- */
993
994 /**
995 * Send Ajax Search Request after Updating search request parameters
996 *
997 * @param params_arr
998 */
999 function wpbc_ajx_availability__send_request_with_params ( params_arr ){
1000
1001 // Define different Search parameters for request
1002 _.each( params_arr, function ( p_val, p_key, p_data ) {
1003 //console.log( 'Request for: ', p_key, p_val );
1004 wpbc_ajx_availability.search_set_param( p_key, p_val );
1005 });
1006
1007 // Send Ajax Request
1008 wpbc_ajx_availability__ajax_request();
1009 }
1010
1011
1012 /**
1013 * Search request for "Page Number"
1014 * @param page_number int
1015 */
1016 function wpbc_ajx_availability__pagination_click( page_number ){
1017
1018 wpbc_ajx_availability__send_request_with_params( {
1019 'page_num': page_number
1020 } );
1021 }
1022
1023
1024
1025 /**
1026 * Show / Hide Content --------------------------------------------------------------------------------------- */
1027
1028 /**
1029 * Show Listing Content - Sending Ajax Request - with parameters that we early defined
1030 */
1031 function wpbc_ajx_availability__actual_content__show(){
1032
1033 wpbc_ajx_availability__ajax_request(); // Send Ajax Request - with parameters that we early defined in "wpbc_ajx_booking_listing" Obj.
1034 }
1035
1036 /**
1037 * Hide Listing Content
1038 */
1039 function wpbc_ajx_availability__actual_content__hide(){
1040
1041 jQuery( wpbc_ajx_availability.get_other_param( 'listing_container' ) ).html( '' );
1042 }
1043
1044
1045
1046 /**
1047 * M e s s a g e --------------------------------------------------------------------------------------------- */
1048
1049 /**
1050 * Show just message instead of content
1051 */
1052 function wpbc_ajx_availability__show_message( message ){
1053
1054 wpbc_ajx_availability__actual_content__hide();
1055
1056 jQuery( wpbc_ajx_availability.get_other_param( 'listing_container' ) ).html(
1057 '<div class="wpbc-settings-notice notice-warning" style="text-align:left">' +
1058 message +
1059 '</div>'
1060 );
1061 }
1062
1063
1064
1065 /**
1066 * Support Functions - Spin Icon in Buttons ------------------------------------------------------------------ */
1067
1068 /**
1069 * Spin button in Filter toolbar - Start
1070 */
1071 function wpbc_availability_reload_button__spin_start(){
1072 jQuery( '#wpbc_availability_reload_button .menu_icon.wpbc_spin').removeClass( 'wpbc_animation_pause' );
1073 }
1074
1075 /**
1076 * Spin button in Filter toolbar - Pause
1077 */
1078 function wpbc_availability_reload_button__spin_pause(){
1079 jQuery( '#wpbc_availability_reload_button .menu_icon.wpbc_spin' ).addClass( 'wpbc_animation_pause' );
1080 }
1081
1082 /**
1083 * Spin button in Filter toolbar - is Spinning ?
1084 *
1085 * @returns {boolean}
1086 */
1087 function wpbc_availability_reload_button__is_spin(){
1088 if ( jQuery( '#wpbc_availability_reload_button .menu_icon.wpbc_spin' ).hasClass( 'wpbc_animation_pause' ) ){
1089 return true;
1090 } else {
1091 return false;
1092 }
1093 }
1094