PluginProbe
Booking Calendar / 11.0
Booking Calendar v11.0
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-general / _src / availability_general_page.js

availability_general_page.js in Booking Calendar 11.0, at includes/page-availability-general/_src/availability_general_page.js

801 lines 27.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * General Availability UI.
3 */
4 ( function ( $, w ) {
5 'use strict';
6
7 var cfg = w.wpbc_availability_general_page || {};
8 var preview_timer = 0;
9 var preview_frame = 0;
10 var preview_ajax = null;
11 var observer = null;
12 var preview_unavailable_classes = 'wpbc_ag_preview_unavailable wpbc_ag_preview_weekday_unavailable wpbc_ag_preview_from_today_unavailable wpbc_ag_preview_limit_available_from_today wpbc_ag_preview_buffer_unavailable weekday_unavailable from_today_unavailable limit_available_from_today buffer_unavailable';
13
14 function trim_text( value ) {
15 return String( value || '' ).trim();
16 }
17
18 function switch_panel( $tab ) {
19 var panel_id = $tab.attr( 'aria-controls' );
20 var $tabs = $tab.closest( '.wpbc_ag_rightbar_tabs' ).find( '[role="tab"]' );
21 var $panels = $( '.wpbc_ag_rightbar_panels [role="tabpanel"]' );
22
23 $tabs.attr( 'aria-selected', 'false' );
24 $tab.attr( 'aria-selected', 'true' );
25
26 $panels.attr( 'hidden', 'hidden' ).attr( 'aria-hidden', 'true' );
27 $( '#' + panel_id ).removeAttr( 'hidden' ).attr( 'aria-hidden', 'false' );
28 }
29
30 function toggle_group( $button ) {
31 var $group = $button.closest( '.wpbc_ui__collapsible_group' );
32 var $fields = $group.find( '> .group__fields' );
33 var is_open = $group.hasClass( 'is-open' );
34
35 $group.toggleClass( 'is-open', ! is_open );
36 $button.attr( 'aria-expanded', is_open ? 'false' : 'true' );
37 $fields.prop( 'hidden', is_open ).attr( 'aria-hidden', is_open ? 'true' : 'false' );
38 }
39
40 function refresh_buffer_fields() {
41 var value = $( 'input[name="booking_unavailable_extra_in_out"]:checked' ).val() || '';
42
43 $( '.wpbc_ag_buffer_fields' ).each( function () {
44 var $panel = $( this );
45 $panel.toggleClass( 'is-visible', $panel.data( 'buffer-panel' ) === value );
46 } );
47 }
48
49 function is_buffer_available() {
50 return ! ( cfg.is_buffer_available === false || cfg.is_buffer_available === 'false' || cfg.is_buffer_available === 0 || cfg.is_buffer_available === '0' );
51 }
52
53 function is_available_limit_available() {
54 return ! ( cfg.is_available_limit_available === false || cfg.is_available_limit_available === 'false' || cfg.is_available_limit_available === 0 || cfg.is_available_limit_available === '0' );
55 }
56
57 function sync_range_from_select( select ) {
58 var $select = $( select );
59 var name = $select.attr( 'name' );
60 var selected_index = $select.prop( 'selectedIndex' );
61 var selected_text = trim_text( $select.find( 'option:selected' ).text() );
62 var $range = $( '[data-wpbc-ag-range-for="' + name + '"]' );
63 var $value = $( '[data-wpbc-ag-range-value-for="' + name + '"]' );
64
65 if ( ! $range.length ) {
66 return;
67 }
68
69 $range.val( selected_index < 0 ? 0 : selected_index );
70 $value.text( selected_text );
71 }
72
73 function sync_select_from_range( range ) {
74 var $range = $( range );
75 var name = $range.attr( 'data-wpbc-ag-range-for' );
76 var $select = $( '[name="' + name + '"]' );
77 var index = parseInt( $range.val(), 10 ) || 0;
78
79 if ( ! $select.length ) {
80 return;
81 }
82
83 $select.prop( 'selectedIndex', index );
84 sync_range_from_select( $select );
85 }
86
87 function sync_all_ranges() {
88 $( '[data-wpbc-ag-range-for]' ).each( function () {
89 var name = $( this ).attr( 'data-wpbc-ag-range-for' );
90 sync_range_from_select( $( '[name="' + name + '"]' ).first() );
91 } );
92 }
93
94 function step_select_value( button ) {
95 var $button = $( button );
96 var name = $button.attr( 'data-wpbc-ag-stepper' );
97 var step = parseInt( $button.attr( 'data-step' ), 10 ) || 0;
98 var $select = $( '[name="' + name + '"]' ).first();
99 var current_index;
100 var next_index;
101
102 if ( ! $select.length || $select.prop( 'disabled' ) ) {
103 return;
104 }
105
106 current_index = $select.prop( 'selectedIndex' );
107 next_index = Math.max( 0, Math.min( $select.find( 'option' ).length - 1, current_index + step ) );
108
109 if ( next_index === current_index ) {
110 return;
111 }
112
113 $select.prop( 'selectedIndex', next_index ).trigger( 'change' );
114 }
115
116 function get_form() {
117 return $( '[data-wpbc-ag-settings-form="1"]' ).first();
118 }
119
120 function collect_settings() {
121 var $form = get_form();
122 var weekdays = [];
123
124 $form.find( 'input[name="booking_unavailable_days[]"]:checked' ).each( function () {
125 weekdays.push( parseInt( this.value, 10 ) );
126 } );
127
128 return {
129 weekdays: weekdays,
130 booking_unavailable_days_num_from_today: $form.find( '[name="booking_unavailable_days_num_from_today"]' ).val() || '0',
131 booking_available_days_num_from_today: $form.find( '[name="booking_available_days_num_from_today"]' ).val() || '',
132 booking_unavailable_extra_in_out: $form.find( '[name="booking_unavailable_extra_in_out"]:checked' ).val() || '',
133 booking_unavailable_extra_minutes_in: $form.find( '[name="booking_unavailable_extra_minutes_in"]' ).val() || '',
134 booking_unavailable_extra_minutes_out: $form.find( '[name="booking_unavailable_extra_minutes_out"]' ).val() || '',
135 booking_unavailable_extra_days_in: $form.find( '[name="booking_unavailable_extra_days_in"]' ).val() || '',
136 booking_unavailable_extra_days_out: $form.find( '[name="booking_unavailable_extra_days_out"]' ).val() || ''
137 };
138 }
139
140 function set_select_value( name, value ) {
141 var $field = get_form().find( '[name="' + name + '"]' ).first();
142
143 if ( ! $field.length ) {
144 return;
145 }
146
147 $field.val( value );
148 if ( String( $field.val() ) !== String( value ) ) {
149 $field.prop( 'selectedIndex', 0 );
150 }
151 }
152
153 function apply_settings_to_form( settings ) {
154 var $form = get_form();
155 var weekdays = settings && settings.weekdays ? settings.weekdays : [];
156
157 if ( ! $form.length || ! settings ) {
158 return;
159 }
160
161 $form.find( 'input[name="booking_unavailable_days[]"]' ).prop( 'checked', false );
162 $.each( weekdays, function ( index, day_num ) {
163 $form.find( 'input[name="booking_unavailable_days[]"][value="' + parseInt( day_num, 10 ) + '"]' ).prop( 'checked', true );
164 } );
165
166 set_select_value( 'booking_unavailable_days_num_from_today', settings.booking_unavailable_days_num_from_today || '0' );
167 set_select_value( 'booking_available_days_num_from_today', settings.booking_available_days_num_from_today || '' );
168 set_select_value( 'booking_unavailable_extra_minutes_in', settings.booking_unavailable_extra_minutes_in || '' );
169 set_select_value( 'booking_unavailable_extra_minutes_out', settings.booking_unavailable_extra_minutes_out || '' );
170 set_select_value( 'booking_unavailable_extra_days_in', settings.booking_unavailable_extra_days_in || '' );
171 set_select_value( 'booking_unavailable_extra_days_out', settings.booking_unavailable_extra_days_out || '' );
172
173 $form.find( 'input[name="booking_unavailable_extra_in_out"]' ).prop( 'checked', false );
174 $form.find( 'input[name="booking_unavailable_extra_in_out"][value="' + ( settings.booking_unavailable_extra_in_out || '' ) + '"]' ).prop( 'checked', true );
175
176 refresh_buffer_fields();
177 sync_all_ranges();
178 schedule_preview_refresh();
179 }
180
181 function date_from_sql( sql_date ) {
182 var parts = String( sql_date || '' ).split( '-' );
183 if ( parts.length !== 3 ) {
184 return null;
185 }
186 return new Date( parseInt( parts[0], 10 ), parseInt( parts[1], 10 ) - 1, parseInt( parts[2], 10 ), 0, 0, 0 );
187 }
188
189 function get_today_date() {
190 var arr = w._wpbc && typeof w._wpbc.get_other_param === 'function' ? w._wpbc.get_other_param( 'today_arr' ) : null;
191 if ( arr && arr.length >= 3 ) {
192 return new Date( parseInt( arr[0], 10 ), parseInt( arr[1], 10 ) - 1, parseInt( arr[2], 10 ), 0, 0, 0 );
193 }
194 var now = new Date();
195 return new Date( now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0 );
196 }
197
198 function get_real_today_date() {
199 var arr = w._wpbc && typeof w._wpbc.get_other_param === 'function' ? w._wpbc.get_other_param( 'time_local_arr' ) : null;
200 if ( arr && arr.length >= 3 ) {
201 return new Date( parseInt( arr[0], 10 ), parseInt( arr[1], 10 ) - 1, parseInt( arr[2], 10 ), 0, 0, 0 );
202 }
203 return get_today_date();
204 }
205
206 function days_between( date_a, date_b ) {
207 return Math.floor( ( date_a.getTime() - date_b.getTime() ) / 86400000 );
208 }
209
210 function add_days( date, days ) {
211 var shifted_date = new Date( date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0 );
212 shifted_date.setDate( shifted_date.getDate() + days );
213 return shifted_date;
214 }
215
216 function date_to_sql( date ) {
217 var month = String( date.getMonth() + 1 );
218 var day = String( date.getDate() );
219
220 if ( month.length < 2 ) {
221 month = '0' + month;
222 }
223 if ( day.length < 2 ) {
224 day = '0' + day;
225 }
226
227 return date.getFullYear() + '-' + month + '-' + day;
228 }
229
230 function get_sql_date_from_cell( cell ) {
231 var classes = String( cell.className || '' ).split( /\s+/ );
232 var i;
233 for ( i = 0; i < classes.length; i++ ) {
234 if ( classes[i].indexOf( 'sql_date_' ) === 0 ) {
235 return classes[i].replace( 'sql_date_', '' );
236 }
237 }
238 return '';
239 }
240
241 function unavailable_from_today_applies( cell_date, today_date, value ) {
242 var minutes;
243 var now;
244 var unavailable_until;
245
246 if ( ! value || value === '0' ) {
247 return false;
248 }
249
250 if ( /m$/.test( value ) ) {
251 minutes = parseInt( value, 10 );
252 if ( ! minutes ) {
253 return false;
254 }
255 now = new Date();
256 unavailable_until = new Date( now.getTime() + ( ( minutes - 1 ) * 60000 ) );
257 unavailable_until = new Date( unavailable_until.getFullYear(), unavailable_until.getMonth(), unavailable_until.getDate(), 0, 0, 0 );
258 return cell_date.getTime() <= unavailable_until.getTime();
259 }
260
261 return days_between( cell_date, today_date ) < parseInt( value, 10 );
262 }
263
264 function get_option_text( selector ) {
265 var text = $( selector ).find( 'option:selected' ).text();
266 return trim_text( text );
267 }
268
269 function get_days_value( value ) {
270 if ( ! value || ! /d$/.test( value ) ) {
271 return 0;
272 }
273 return parseInt( value, 10 ) || 0;
274 }
275
276 function update_wpbc_preview_params( settings ) {
277 if ( ! w._wpbc || typeof w._wpbc.set_other_param !== 'function' ) {
278 return;
279 }
280
281 w._wpbc.set_other_param( 'availability__week_days_unavailable', settings.weekdays.concat( [ 999 ] ) );
282 w._wpbc.set_other_param( 'availability__available_from_today', is_available_limit_available() ? ( settings.booking_available_days_num_from_today || '' ) : '' );
283 w._wpbc.set_other_param( 'availability__unavailable_from_today', settings.booking_unavailable_days_num_from_today || '0' );
284 }
285
286 function update_buffer_preview_note( settings ) {
287 var $notes = $( '[data-wpbc-ag-calendar-notes="1"]' ).first();
288 var $calendar = $( '[data-wpbc-ag-calendar-panel="1"]' ).first();
289 var $note = $notes.find( '.wpbc_ag_buffer_preview_note' );
290 var type = settings.booking_unavailable_extra_in_out || '';
291 var before_text = '';
292 var after_text = '';
293 var message = '';
294
295 if ( ! $notes.length || ! $calendar.length ) {
296 return;
297 }
298
299 if ( ! $note.length ) {
300 $note = $( '<div class="wpbc_ag_buffer_preview_note" aria-live="polite"></div>' );
301 $notes.append( $note );
302 }
303
304 if ( ! is_buffer_available() ) {
305 $calendar.removeClass( 'wpbc_ag_preview_buffer_active' );
306 $note.attr( 'hidden', 'hidden' );
307 return;
308 }
309
310 $calendar.toggleClass( 'wpbc_ag_preview_buffer_active', !! type );
311
312 if ( type === 'm' ) {
313 before_text = get_option_text( '[name="booking_unavailable_extra_minutes_in"]' ) || '-';
314 after_text = get_option_text( '[name="booking_unavailable_extra_minutes_out"]' ) || '-';
315 } else if ( type === 'd' ) {
316 before_text = get_option_text( '[name="booking_unavailable_extra_days_in"]' ) || '-';
317 after_text = get_option_text( '[name="booking_unavailable_extra_days_out"]' ) || '-';
318 }
319
320 if ( type ) {
321 message = '<strong>' + ( cfg.i18n && cfg.i18n.buffer_preview ? cfg.i18n.buffer_preview : 'Buffer preview' ) + ':</strong> ' +
322 ( cfg.i18n && cfg.i18n.before_booking ? cfg.i18n.before_booking : 'Before booking' ) + ' ' + before_text +
323 ' / ' + ( cfg.i18n && cfg.i18n.after_booking ? cfg.i18n.after_booking : 'After booking' ) + ' ' + after_text;
324 if ( $note.html() !== message ) {
325 $note.html( message );
326 }
327 if ( $note.attr( 'hidden' ) ) {
328 $note.removeAttr( 'hidden' );
329 }
330 } else {
331 message = cfg.i18n && cfg.i18n.no_buffer ? cfg.i18n.no_buffer : 'No booking buffer is selected.';
332 if ( $note.text() !== message ) {
333 $note.text( message );
334 }
335 if ( ! $note.attr( 'hidden' ) ) {
336 $note.attr( 'hidden', 'hidden' );
337 }
338 }
339 }
340
341 function apply_buffer_days_preview( settings ) {
342 var $calendar = $( '[data-wpbc-ag-calendar-panel="1"]' );
343 var before_days = get_days_value( settings.booking_unavailable_extra_days_in );
344 var after_days = get_days_value( settings.booking_unavailable_extra_days_out );
345 var date_cells = {};
346 var booked_dates = [];
347
348 if ( ! is_buffer_available() ) {
349 return;
350 }
351
352 if ( settings.booking_unavailable_extra_in_out !== 'd' || ( ! before_days && ! after_days ) ) {
353 return;
354 }
355
356 $calendar.find( '.datepick-days-cell' ).each( function () {
357 var $cell = $( this );
358 var sql_date = get_sql_date_from_cell( this );
359 var cell_date;
360
361 if ( ! sql_date ) {
362 return;
363 }
364
365 date_cells[ sql_date ] = $cell;
366
367 if ( $cell.hasClass( 'date_approved' ) || $cell.hasClass( 'date2approve' ) ) {
368 cell_date = date_from_sql( sql_date );
369 if ( cell_date ) {
370 booked_dates.push( cell_date );
371 }
372 }
373 } );
374
375 $.each( booked_dates, function ( index, booked_date ) {
376 var offset;
377 var target_sql_date;
378 var $target_cell;
379
380 for ( offset = before_days * -1; offset < 0; offset++ ) {
381 target_sql_date = date_to_sql( add_days( booked_date, offset ) );
382 $target_cell = date_cells[ target_sql_date ];
383 if ( $target_cell && ! $target_cell.hasClass( 'date_approved' ) && ! $target_cell.hasClass( 'date2approve' ) ) {
384 remember_preview_origin( $target_cell );
385 $target_cell.addClass( 'date_user_unavailable wpbc_ag_preview_unavailable wpbc_ag_preview_buffer_unavailable buffer_unavailable' );
386 $target_cell.attr( 'data-wpbc-ag-preview-reason', 'wpbc_ag_preview_buffer_unavailable' );
387 }
388 }
389
390 for ( offset = 1; offset <= after_days; offset++ ) {
391 target_sql_date = date_to_sql( add_days( booked_date, offset ) );
392 $target_cell = date_cells[ target_sql_date ];
393 if ( $target_cell && ! $target_cell.hasClass( 'date_approved' ) && ! $target_cell.hasClass( 'date2approve' ) ) {
394 remember_preview_origin( $target_cell );
395 $target_cell.addClass( 'date_user_unavailable wpbc_ag_preview_unavailable wpbc_ag_preview_buffer_unavailable buffer_unavailable' );
396 $target_cell.attr( 'data-wpbc-ag-preview-reason', 'wpbc_ag_preview_buffer_unavailable' );
397 }
398 }
399 } );
400 }
401
402 function remember_preview_origin( $cell ) {
403 if ( typeof $cell.attr( 'data-wpbc-ag-original-date-user-unavailable' ) === 'undefined' ) {
404 $cell.attr( 'data-wpbc-ag-original-date-user-unavailable', $cell.hasClass( 'date_user_unavailable' ) ? '1' : '0' );
405 }
406 }
407
408 function clear_preview_cell( $cell ) {
409 var had_date_user_unavailable = $cell.attr( 'data-wpbc-ag-original-date-user-unavailable' ) === '1';
410
411 $cell.removeClass( preview_unavailable_classes );
412 $cell.removeAttr( 'data-wpbc-ag-preview-reason' );
413 $cell.removeAttr( 'data-wpbc-ag-original-date-user-unavailable' );
414
415 if ( ! had_date_user_unavailable ) {
416 $cell.removeClass( 'date_user_unavailable' );
417 }
418 }
419
420 function apply_calendar_preview() {
421 var settings = collect_settings();
422 var today_date = get_real_today_date();
423 var available_limit = is_available_limit_available() ? parseInt( settings.booking_available_days_num_from_today || '0', 10 ) : 0;
424 var $calendar = $( '[data-wpbc-ag-calendar-panel="1"]' );
425
426 update_wpbc_preview_params( settings );
427 update_buffer_preview_note( settings );
428
429 $calendar.find( '.datepick-days-cell' ).each( function () {
430 var cell = this;
431 var $cell = $( cell );
432 var sql_date = get_sql_date_from_cell( cell );
433 var cell_date = date_from_sql( sql_date );
434 var make_unavailable = false;
435 var reason_class = '';
436 var previous_reason = $cell.attr( 'data-wpbc-ag-preview-reason' ) || '';
437 var had_general_preview = !! previous_reason || $cell.hasClass( 'wpbc_ag_preview_unavailable' ) || $cell.hasClass( 'weekday_unavailable' ) || $cell.hasClass( 'from_today_unavailable' ) || $cell.hasClass( 'limit_available_from_today' ) || $cell.hasClass( 'buffer_unavailable' );
438
439 if ( ! cell_date ) {
440 return;
441 }
442
443 if ( settings.weekdays.indexOf( cell_date.getDay() ) > -1 ) {
444 make_unavailable = true;
445 reason_class = 'wpbc_ag_preview_weekday_unavailable';
446 }
447
448 if ( unavailable_from_today_applies( cell_date, today_date, settings.booking_unavailable_days_num_from_today ) ) {
449 make_unavailable = true;
450 reason_class = 'wpbc_ag_preview_from_today_unavailable';
451 }
452
453 if ( available_limit > 0 && days_between( cell_date, today_date ) >= available_limit ) {
454 make_unavailable = true;
455 reason_class = 'wpbc_ag_preview_limit_available_from_today';
456 }
457
458 if ( make_unavailable ) {
459 if ( previous_reason !== reason_class ) {
460 if ( had_general_preview ) {
461 clear_preview_cell( $cell );
462 }
463 remember_preview_origin( $cell );
464 $cell.addClass( 'date_user_unavailable wpbc_ag_preview_unavailable ' + reason_class );
465 $cell.attr( 'data-wpbc-ag-preview-reason', reason_class );
466 }
467 } else if ( had_general_preview ) {
468 clear_preview_cell( $cell );
469 }
470 } );
471
472 apply_buffer_days_preview( settings );
473 }
474
475 function queue_preview_refresh() {
476 if ( preview_frame ) {
477 return;
478 }
479
480 if ( w.requestAnimationFrame ) {
481 preview_frame = w.requestAnimationFrame( function () {
482 preview_frame = 0;
483 apply_calendar_preview();
484 } );
485 } else {
486 preview_frame = w.setTimeout( function () {
487 preview_frame = 0;
488 apply_calendar_preview();
489 }, 0 );
490 }
491 }
492
493 function schedule_preview_refresh( delay ) {
494 clearTimeout( preview_timer );
495 delay = parseInt( delay, 10 ) || 0;
496
497 if ( delay > 0 ) {
498 preview_timer = setTimeout( queue_preview_refresh, delay );
499 return;
500 }
501
502 queue_preview_refresh();
503 }
504
505 function update_hints( hints ) {
506 if ( ! hints ) {
507 return;
508 }
509
510 if ( typeof hints.booking_unavailable_days_num_from_today__hint !== 'undefined' ) {
511 $( '[data-wpbc-ag-hint="booking_unavailable_days_num_from_today"]' ).html(
512 '<span class="wpbc_ag_hint_unavailable">' + $( '[data-wpbc-ag-hint="booking_unavailable_days_num_from_today"] .wpbc_ag_hint_unavailable' ).first().text() + '</span>' +
513 hints.booking_unavailable_days_num_from_today__hint
514 );
515 }
516
517 if ( typeof hints.booking_available_days_num_from_today__hint !== 'undefined' ) {
518 $( '[data-wpbc-ag-hint="booking_available_days_num_from_today"]' ).html(
519 '<span class="wpbc_ag_hint_available">' + $( '[data-wpbc-ag-hint="booking_available_days_num_from_today"] .wpbc_ag_hint_available' ).first().text() + '</span>' +
520 hints.booking_available_days_num_from_today__hint
521 );
522 }
523 }
524
525 function show_message( message, type, duration ) {
526 if ( typeof w.wpbc_admin_show_message === 'function' ) {
527 w.wpbc_admin_show_message( message, type || 'info', duration || 2000, false );
528 } else {
529 w.alert( message );
530 }
531 }
532
533 function set_busy( $button, busy ) {
534 var busy_text;
535
536 if ( ! $button || ! $button.length ) {
537 return;
538 }
539
540 if ( busy ) {
541 if ( ! $button.data( 'wpbc-ag-original-html' ) ) {
542 $button.data( 'wpbc-ag-original-html', $button.html() );
543 }
544 busy_text = $button.data( 'wpbc-u-busy-text' ) || ( cfg.i18n && cfg.i18n.saving ) || 'Saving...';
545 $button.addClass( 'wpbc_ag_is_saving' ).attr( 'aria-busy', 'true' ).html( '<i class="menu_icon icon-1x wpbc_icn_rotate_right wpbc_spin"></i><span class="in-button-text">&nbsp;&nbsp;' + busy_text + '</span>' );
546 } else {
547 $button.removeClass( 'wpbc_ag_is_saving' ).removeAttr( 'aria-busy' );
548 if ( $button.data( 'wpbc-ag-original-html' ) ) {
549 $button.html( $button.data( 'wpbc-ag-original-html' ) );
550 }
551 }
552 }
553
554 function replace_calendar_panel( html ) {
555 var $holder = $( '<div />' ).append( $.parseHTML( html, document, true ) );
556 var $new_panel = $holder.find( '[data-wpbc-ag-calendar-panel="1"]' ).first();
557 var $old_panel = $( '[data-wpbc-ag-calendar-panel="1"]' ).first();
558 var $scripts;
559
560 if ( ! $new_panel.length || ! $old_panel.length ) {
561 return;
562 }
563
564 $scripts = $new_panel.find( 'script' ).remove();
565 $old_panel.replaceWith( $new_panel );
566
567 $scripts.each( function () {
568 var code = this.text || this.textContent || this.innerHTML || '';
569 var src = this.src || '';
570
571 if ( src ) {
572 $.ajax( {
573 url: src,
574 dataType: 'script',
575 cache: true
576 } );
577 } else if ( code ) {
578 $.globalEval( code );
579 }
580 } );
581 }
582
583 function set_calendar_loading( is_loading ) {
584 var $calendar = $( '[data-wpbc-ag-calendar-panel="1"]' ).first();
585 var loading_text = cfg.i18n && cfg.i18n.loading ? cfg.i18n.loading : 'Loading';
586 var $loading;
587
588 if ( ! $calendar.length ) {
589 return;
590 }
591
592 if ( is_loading ) {
593 $loading = $calendar.find( '.wpbc_calendar_loading' ).first();
594 if ( ! $loading.length ) {
595 $loading = $(
596 '<div class="wpbc_calendar_loading wpbc_ag_calendar_loading">' +
597 '<span class="wpbc_icn_autorenew wpbc_spin"></span>&nbsp;&nbsp;' +
598 '<span></span>' +
599 '</div>'
600 );
601 $loading.find( 'span' ).last().text( loading_text + '...' );
602 $calendar.append( $loading );
603 }
604 $calendar.addClass( 'is-loading' ).attr( 'aria-busy', 'true' );
605 } else {
606 $calendar.removeClass( 'is-loading' ).removeAttr( 'aria-busy' );
607 $calendar.find( '.wpbc_calendar_loading' ).remove();
608 }
609 }
610
611 function get_preview_payload() {
612 return {
613 action: cfg.preview_action || 'WPBC_AJX_AVAILABILITY_GENERAL_PREVIEW',
614 nonce: cfg.nonce || '',
615 resource_id: $( '#wpbc_ag_resource_id' ).val() || '',
616 months_count: $( '#wpbc_ag_months_count' ).val() || ''
617 };
618 }
619
620 function load_calendar_preview() {
621 var $calendar = $( '[data-wpbc-ag-calendar-panel="1"]' ).first();
622 var current_preview_ajax;
623
624 if ( ! cfg.ajax_url ) {
625 show_message( ( cfg.i18n && cfg.i18n.preview_failed ) || 'Unable to refresh calendar preview.', 'error', 10000 );
626 return;
627 }
628
629 if ( preview_ajax && preview_ajax.readyState !== 4 ) {
630 preview_ajax.abort();
631 }
632
633 set_calendar_loading( true );
634
635 current_preview_ajax = $.ajax( {
636 url: cfg.ajax_url,
637 method: 'POST',
638 dataType: 'json',
639 data: get_preview_payload()
640 } );
641 preview_ajax = current_preview_ajax;
642
643 current_preview_ajax.done( function ( response ) {
644 if ( ! response || ! response.success || ! response.data || ! response.data.html ) {
645 show_message( ( response && response.data && response.data.message ) || ( cfg.i18n && cfg.i18n.preview_failed ) || 'Unable to refresh calendar preview.', 'error', 10000 );
646 return;
647 }
648
649 replace_calendar_panel( response.data.html );
650 $( '[data-wpbc-ag-page="1"]' ).attr( 'data-wpbc-ag-resource-id', response.data.resource_id || '' );
651 observe_calendar_changes();
652 schedule_preview_refresh();
653 setTimeout( schedule_preview_refresh, 600 );
654 } ).fail( function ( jq_xhr, text_status ) {
655 if ( text_status !== 'abort' ) {
656 show_message( ( cfg.i18n && cfg.i18n.preview_failed ) || 'Unable to refresh calendar preview.', 'error', 10000 );
657 }
658 } ).always( function () {
659 if ( preview_ajax === current_preview_ajax ) {
660 set_calendar_loading( false );
661 }
662 } );
663 }
664
665 function save_settings( button ) {
666 var $button = $( button );
667 var settings = collect_settings();
668 var payload = $.extend( {}, settings, {
669 action: cfg.action || 'WPBC_AJX_AVAILABILITY_GENERAL_SAVE',
670 nonce: cfg.nonce || '',
671 booking_unavailable_days: settings.weekdays
672 } );
673
674 if ( ! cfg.ajax_url ) {
675 show_message( ( cfg.i18n && cfg.i18n.save_failed ) || 'Unable to save general availability settings.', 'error', 10000 );
676 return;
677 }
678
679 set_busy( $button, true );
680
681 $.ajax( {
682 url: cfg.ajax_url,
683 method: 'POST',
684 dataType: 'json',
685 data: payload
686 } ).done( function ( response ) {
687 if ( ! response || ! response.success ) {
688 show_message( ( response && response.data && response.data.message ) || ( cfg.i18n && cfg.i18n.save_failed ) || 'Unable to save general availability settings.', 'error', 10000 );
689 return;
690 }
691
692 if ( response.data && response.data.settings && response.data.settings.hints ) {
693 update_hints( response.data.settings.hints );
694 }
695
696 load_calendar_preview();
697 show_message( ( response.data && response.data.message ) || ( cfg.i18n && cfg.i18n.saved ) || 'General availability settings updated.', 'success', 2000 );
698 } ).fail( function () {
699 show_message( ( cfg.i18n && cfg.i18n.save_failed ) || 'Unable to save general availability settings.', 'error', 10000 );
700 } ).always( function () {
701 set_busy( $button, false );
702 } );
703 }
704
705 function reset_settings( button ) {
706 var confirm_message = ( cfg.i18n && cfg.i18n.reset_confirm ) || 'Reset general availability settings to default values?';
707 var default_settings = cfg.default_settings || {
708 weekdays: [],
709 booking_unavailable_days_num_from_today: '0',
710 booking_available_days_num_from_today: '',
711 booking_unavailable_extra_in_out: '',
712 booking_unavailable_extra_minutes_in: '',
713 booking_unavailable_extra_minutes_out: '',
714 booking_unavailable_extra_days_in: '',
715 booking_unavailable_extra_days_out: ''
716 };
717
718 if ( ! w.confirm( confirm_message ) ) {
719 return;
720 }
721
722 apply_settings_to_form( default_settings );
723 load_calendar_preview();
724 show_message( ( cfg.i18n && cfg.i18n.reset_applied ) || 'Default availability settings are ready for preview. Click Save Changes to apply them.', 'success', 4000 );
725 }
726
727 function observe_calendar_changes() {
728 var target = document.querySelector( '[data-wpbc-ag-calendar-panel="1"]' );
729
730 if ( ! target || ! w.MutationObserver ) {
731 return;
732 }
733
734 if ( observer ) {
735 observer.disconnect();
736 }
737
738 observer = new MutationObserver( schedule_preview_refresh );
739 observer.observe( target, {
740 childList: true,
741 subtree: true
742 } );
743 }
744
745 $( document ).on( 'click', '.wpbc_ag_rightbar_tabs [role="tab"]', function () {
746 switch_panel( $( this ) );
747 } );
748
749 $( document ).on( 'click', '.wpbc_ag_rightbar_panels .group__header', function () {
750 toggle_group( $( this ) );
751 } );
752
753 $( document ).on( 'submit', '[data-wpbc-ag-preview-toolbar="1"]', function ( event ) {
754 event.preventDefault();
755 load_calendar_preview();
756 } );
757
758 $( document ).on( 'change', '#wpbc_ag_resource_id, #wpbc_ag_months_count', load_calendar_preview );
759
760 $( document ).on( 'input change', '[data-wpbc-ag-range-for]', function () {
761 sync_select_from_range( this );
762 schedule_preview_refresh();
763 } );
764
765 $( document ).on( 'change', '[data-wpbc-ag-settings-form="1"] select', function () {
766 sync_range_from_select( this );
767 } );
768
769 $( document ).on( 'click', '[data-wpbc-ag-stepper]', function () {
770 step_select_value( this );
771 } );
772
773 $( document ).on( 'change', 'input[name="booking_unavailable_extra_in_out"]', function () {
774 refresh_buffer_fields();
775 schedule_preview_refresh();
776 } );
777
778 $( document ).on( 'change', '[data-wpbc-ag-settings-form="1"] input, [data-wpbc-ag-settings-form="1"] select', schedule_preview_refresh );
779
780 $( document ).on( 'submit', '[data-wpbc-ag-settings-form="1"]', function ( event ) {
781 event.preventDefault();
782 save_settings( $( '[data-wpbc-ag-save="1"]' ).first() );
783 } );
784
785 $( document ).on( 'click', '[data-wpbc-ag-save="1"]', function () {
786 save_settings( this );
787 } );
788
789 $( document ).on( 'click', '[data-wpbc-ag-reset="1"]', function () {
790 reset_settings( this );
791 } );
792
793 $( document ).ready( function () {
794 refresh_buffer_fields();
795 sync_all_ranges();
796 observe_calendar_changes();
797 schedule_preview_refresh();
798 setTimeout( schedule_preview_refresh, 600 );
799 } );
800 }( jQuery, window ) );
801