PluginProbe
Booking Calendar / 11.7
Booking Calendar v11.7
11.9 11.8.4 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 All 205 releases
booking / includes / page-settings-calendar / _src / settings_calendar_page.js

settings_calendar_page.js in Booking Calendar 11.7, at includes/page-settings-calendar/_src/settings_calendar_page.js

837 lines 33.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Calendar settings page UI.
3 */
4 ( function ( $, w ) {
5 'use strict';
6
7 var cfg = w.wpbc_settings_calendar_page || {};
8 var preview_ajax = null;
9 var preview_timer = 0;
10 var is_saving = false;
11 var notice_timer = 0;
12 var calendar_load_patch_timer = 0;
13 var last_preview_signature = '';
14
15 function trim_text( value ) {
16 return String( value || '' ).trim();
17 }
18
19 function show_message( message, type, delay ) {
20 if ( typeof w.wpbc_admin_show_message === 'function' ) {
21 w.wpbc_admin_show_message( message, type || 'info', delay || 4000, false );
22 }
23 }
24
25 function pulse_element( $element, duration ) {
26 if ( ! $element || ! $element.length ) {
27 return;
28 }
29
30 $element
31 .removeClass( 'wpbc_calendar_attention_pulse' )
32 .each( function () {
33 void this.offsetWidth;
34 } )
35 .addClass( 'wpbc_calendar_attention_pulse' );
36
37 setTimeout( function () {
38 $element.removeClass( 'wpbc_calendar_attention_pulse' );
39 }, duration || 2100 );
40 }
41
42 function pulse_latest_warning_notice() {
43 clearTimeout( notice_timer );
44 notice_timer = setTimeout( function () {
45 pulse_element( $( '#ajax_working .wpbc_inner_message.notice-warning' ).last() );
46 }, 50 );
47 }
48
49 function show_premium_notice( $control ) {
50 var is_range_info = $control && $control.is( '[data-wpbc-calendar-premium-range-info="1"]' );
51 var is_changeover_info = $control && $control.is( '[data-wpbc-calendar-premium-changeover-info="1"]' );
52 var message = cfg.i18n && cfg.i18n.premium_option_notice ? cfg.i18n.premium_option_notice : 'This option is available in Booking Calendar Business Small or higher.';
53 var $note;
54
55 if ( is_range_info ) {
56 message = cfg.i18n && cfg.i18n.premium_notice ? cfg.i18n.premium_notice : 'Advanced range rules are available in Booking Calendar Business Small or higher. Open the live demo to test the real behavior.';
57 } else if ( is_changeover_info ) {
58 message = cfg.i18n && cfg.i18n.premium_changeover_notice ? cfg.i18n.premium_changeover_notice : 'Changeover days are available in Booking Calendar Business Small or higher. Open the live demo to test the real behavior.';
59 }
60
61 pulse_element( $control.closest( '.wpbc_calendar_field_row, label, .wpbc_calendar_radio_stack' ) );
62 if ( is_range_info ) {
63 $note = $control.closest( '.wpbc_ui__collapsible_group' ).find( '[data-wpbc-calendar-range-upgrade-note="1"]' ).first();
64 $note.addClass( 'is-visible' );
65 pulse_element( $note );
66 } else if ( is_changeover_info ) {
67 $note = $control.closest( '.wpbc_ui__collapsible_group' ).find( '[data-wpbc-calendar-changeover-upgrade-note="1"]' ).first();
68 $note.addClass( 'is-visible' );
69 pulse_element( $note );
70 }
71 show_message( message, 'warning', 9000 );
72 pulse_latest_warning_notice();
73 }
74
75 function is_range_supported() {
76 return cfg.is_range_supported === 1 || cfg.is_range_supported === '1' || cfg.is_range_supported === true;
77 }
78
79 function is_locked_changeover_control( field ) {
80 return ! is_range_supported() && $( field ).is( '[name="booking_range_selection_time_is_active"]' );
81 }
82
83 function switch_panel( $tab ) {
84 var panel_id = $tab.attr( 'aria-controls' );
85 var $tabs = $tab.closest( '.wpbc_calendar_rightbar_tabs' ).find( '[role="tab"]' );
86 var $panels = $( '.wpbc_calendar_rightbar_panels [role="tabpanel"]' );
87
88 $tabs.attr( 'aria-selected', 'false' );
89 $tab.attr( 'aria-selected', 'true' );
90
91 $panels.attr( 'hidden', 'hidden' ).attr( 'aria-hidden', 'true' );
92 $( '#' + panel_id ).removeAttr( 'hidden' ).attr( 'aria-hidden', 'false' );
93 }
94
95 function toggle_group( $button ) {
96 var $group = $button.closest( '.wpbc_ui__collapsible_group' );
97 var $fields = $group.find( '> .group__fields' );
98 var is_open = $group.hasClass( 'is-open' );
99
100 $group.toggleClass( 'is-open', ! is_open );
101 $button.attr( 'aria-expanded', is_open ? 'false' : 'true' );
102 $fields.prop( 'hidden', is_open ).attr( 'aria-hidden', is_open ? 'true' : 'false' );
103 }
104
105 function close_group( $group ) {
106 var $button = $group.find( '> .group__header' );
107 var $fields = $group.find( '> .group__fields' );
108
109 $group.removeClass( 'is-open' );
110 $button.attr( 'aria-expanded', 'false' );
111 $fields.prop( 'hidden', true ).attr( 'aria-hidden', 'true' );
112 }
113
114 function open_group( group_name, is_exclusive ) {
115 var $group = $( '.wpbc_calendar_rightbar_panels .wpbc_ui__collapsible_group[data-group="' + group_name + '"]' );
116 var $button = $group.find( '> .group__header' );
117 var $fields = $group.find( '> .group__fields' );
118
119 if ( ! $group.length ) {
120 return $();
121 }
122
123 if ( is_exclusive ) {
124 $group.siblings( '.wpbc_ui__collapsible_group' ).each( function () {
125 close_group( $( this ) );
126 } );
127 }
128
129 $group.addClass( 'is-open' );
130 $button.attr( 'aria-expanded', 'true' );
131 $fields.prop( 'hidden', false ).attr( 'aria-hidden', 'false' );
132
133 return $group;
134 }
135
136 function scroll_to_group( group_name ) {
137 var $group = $( '.wpbc_calendar_rightbar_panels .wpbc_ui__collapsible_group[data-group="' + group_name + '"]' );
138 var $scroll_parent = $();
139 var scroll_parent_el;
140 var group_el;
141 var scroll_top;
142 var parent_rect;
143 var group_rect;
144
145 if ( ! $group.length ) {
146 return;
147 }
148
149 $group.parents().each( function () {
150 var $candidate = $( this );
151 var overflow_y = $candidate.css( 'overflow-y' );
152
153 if (
154 $candidate.hasClass( 'simplebar-content-wrapper' )
155 || (
156 /(auto|scroll)/.test( overflow_y )
157 && this.scrollHeight > this.clientHeight
158 )
159 ) {
160 $scroll_parent = $candidate;
161 return false;
162 }
163 } );
164
165 if ( ! $scroll_parent.length ) {
166 $scroll_parent = $group.closest( '.wpbc_ui_el__vert_right_bar__content' ).find( '.simplebar-content-wrapper' ).first();
167 }
168
169 if ( ! $scroll_parent.length ) {
170 $group.get( 0 ).scrollIntoView( { block: 'nearest' } );
171 return;
172 }
173
174 scroll_parent_el = $scroll_parent.get( 0 );
175 group_el = $group.get( 0 );
176 parent_rect = scroll_parent_el.getBoundingClientRect();
177 group_rect = group_el.getBoundingClientRect();
178 scroll_top = $scroll_parent.scrollTop() + group_rect.top - parent_rect.top - 10;
179
180 $scroll_parent.stop().animate( { scrollTop: Math.max( 0, scroll_top ) }, 180 );
181 }
182
183 function apply_open_section_from_url() {
184 var section_groups = cfg.section_groups || {};
185 var group_name = section_groups[ cfg.open_section ] || '';
186 var $group;
187
188 if ( '' === group_name ) {
189 return;
190 }
191
192 $group = open_group( group_name, true );
193 $.each( [ 120, 650 ], function ( index, delay ) {
194 setTimeout( function () {
195 scroll_to_group( group_name );
196 pulse_element( $group );
197 }, delay );
198 } );
199 }
200
201 function sync_left_navigation_active_section() {
202 var section_menus = cfg.section_menus || {};
203 var menu_slug = section_menus[ cfg.open_section ] || '';
204 var $menu_item;
205
206 if ( '' === menu_slug ) {
207 return;
208 }
209
210 $menu_item = $( '.wpbc_ui_el__vert_nav_item__' + menu_slug );
211 if ( ! $menu_item.length ) {
212 return;
213 }
214
215 $menu_item
216 .closest( '.wpbc_ui_el__level__folder' )
217 .find( '.wpbc_ui_el__vert_nav_item_sub' )
218 .removeClass( 'active' );
219 $menu_item.addClass( 'active' );
220 }
221
222 function get_form() {
223 return $( '[data-wpbc-calendar-settings-form="1"]' ).first();
224 }
225
226 function collect_payload() {
227 var $form = get_form();
228 var data = {};
229 var name;
230 var checkboxes = [
231 'booking_calendar_allow_several_months_on_mobile',
232 'booking_recurrent_time',
233 'booking_last_checkout_day_available',
234 'booking_range_selection_time_is_active',
235 'booking_change_over_days_triangles',
236 'booking_change_over__is_excerpt_on_pages',
237 'booking_is_show_legend',
238 'booking_legend_is_show_numbers',
239 'booking_legend_is_vertical',
240 'booking_show_timeslots_in_tooltip',
241 'booking_is_show_availability_in_tooltips',
242 'booking_is_show_availability_in_date_cell',
243 'booking_is_show_cost_in_tooltips',
244 'booking_is_show_cost_in_date_cell',
245 'booking_is_show_booked_data_in_tooltips'
246 ];
247
248 $.each( $form.serializeArray(), function ( index, item ) {
249 name = String( item.name || '' ).replace( /\[\]$/, '' );
250 if ( 0 === name.indexOf( 'wpbc_setup' ) ) {
251 return;
252 }
253 if ( data[ name ] ) {
254 if ( ! Array.isArray( data[ name ] ) ) {
255 data[ name ] = [ data[ name ] ];
256 }
257 data[ name ].push( item.value );
258 } else {
259 data[ name ] = item.value;
260 }
261 } );
262
263 $.each( checkboxes, function ( index, name ) {
264 data[ name ] = $form.find( '[name="' + name + '"]' ).prop( 'checked' ) ? 'On' : 'Off';
265 } );
266
267 $form.find( 'input[type="checkbox"][name]' ).each( function () {
268 var raw_name = String( this.name || '' );
269 var is_array_name = /\[\]$/.test( raw_name );
270
271 name = raw_name.replace( /\[\]$/, '' );
272 if ( is_array_name ) {
273 if ( 'undefined' === typeof data[ name ] ) {
274 data[ name ] = [];
275 }
276 return;
277 }
278 if ( $.inArray( name, checkboxes ) !== -1 ) {
279 return;
280 }
281 data[ name ] = $( this ).prop( 'checked' ) ? ( $( this ).val() || 'On' ) : 'Off';
282 } );
283
284 data.booking_disable_timeslots_in_tooltip = data.booking_show_timeslots_in_tooltip === 'On' ? 'Off' : 'On';
285
286 data.resource_id = $( '#wpbc_calendar_resource_id' ).val() || '';
287 data.months_count = $( '#wpbc_calendar_months_count' ).val() || '';
288
289 return data;
290 }
291
292 function get_resource_id() {
293 var $preview = $( '[data-wpbc-calendar-preview="1"]' ).first();
294
295 return parseInt( $preview.attr( 'data-resource-id' ) || $( '#wpbc_calendar_resource_id' ).val() || 0, 10 );
296 }
297
298 function get_months_count() {
299 return parseInt( $( '#wpbc_calendar_months_count' ).val() || 3, 10 );
300 }
301
302 function parse_number_list( value ) {
303 if ( Array.isArray( value ) ) {
304 return $.map( value, function ( item ) {
305 var parsed = parseInt( item, 10 );
306 return isNaN( parsed ) ? null : parsed;
307 } );
308 }
309
310 return $.map( String( value || '' ).split( /\s*,\s*/ ), function ( item ) {
311 var parsed = parseInt( item, 10 );
312 return ( '' === item || isNaN( parsed ) ) ? null : parsed;
313 } );
314 }
315
316 function normalize_fixed_range_days_count( value ) {
317 var days_count = parseInt( value, 10 );
318
319 if ( isNaN( days_count ) || days_count < 1 ) {
320 return 3;
321 }
322
323 return Math.min( 180, days_count );
324 }
325
326 function set_calendar_param( resource_id, key, value ) {
327 if ( w._wpbc && typeof w._wpbc.calendar__set_param_value === 'function' ) {
328 w._wpbc.calendar__set_param_value( resource_id, key, value );
329 }
330 }
331
332 function patch_calendar_data_loader() {
333 if ( typeof w.wpbc_calendar__load_data__ajx !== 'function' ) {
334 clearTimeout( calendar_load_patch_timer );
335 calendar_load_patch_timer = setTimeout( patch_calendar_data_loader, 120 );
336 return;
337 }
338
339 if ( w.wpbc_calendar__load_data__ajx.wpbc_settings_calendar_preview_patched ) {
340 return;
341 }
342
343 var original_loader = w.wpbc_calendar__load_data__ajx;
344
345 w.wpbc_calendar__load_data__ajx = function ( params ) {
346 var payload;
347
348 if ( $( '[data-wpbc-calendar-page="1"]' ).length && params && typeof params === 'object' ) {
349 payload = collect_payload();
350 params.wpbc_settings_calendar_preview = 1;
351 params.wpbc_settings_calendar_preview_changeover = payload.booking_range_selection_time_is_active === 'On' ? 'On' : 'Off';
352 params.wpbc_settings_calendar_preview_triangles = payload.booking_change_over_days_triangles === 'Off' ? 'Off' : 'On';
353 params.wpbc_settings_calendar_preview_recurrent_time = payload.booking_recurrent_time === 'On' ? 'On' : 'Off';
354 params.wpbc_settings_calendar_preview_last_checkout = payload.booking_last_checkout_day_available === 'On' ? 'On' : 'Off';
355 params.wpbc_settings_calendar_preview_excerpt_on_pages = payload.booking_change_over__is_excerpt_on_pages === 'On' ? 'On' : 'Off';
356 params.wpbc_settings_calendar_preview_excerpt_pages = payload.booking_change_over__excerpt_on_pages || '';
357 params.wpbc_settings_calendar_preview_excerpt_resources = payload.booking_change_over__excerpt_bk_resources || '';
358 params.wpbc_settings_calendar_preview_show_legend = payload.booking_is_show_legend === 'On' ? 'On' : 'Off';
359 params.wpbc_settings_calendar_preview_legend_show_numbers = payload.booking_legend_is_show_numbers === 'On' ? 'On' : 'Off';
360 params.wpbc_settings_calendar_preview_legend_vertical = payload.booking_legend_is_vertical === 'On' ? 'On' : 'Off';
361 $.each( [ 'available', 'pending', 'approved', 'partially', 'unavailable' ], function ( index, legend_item ) {
362 params[ 'wpbc_settings_calendar_preview_legend_show_' + legend_item ] = payload[ 'booking_legend_is_show_item_' + legend_item ] === 'On' ? 'On' : 'Off';
363 params[ 'wpbc_settings_calendar_preview_legend_text_' + legend_item ] = payload[ 'booking_legend_text_for_item_' + legend_item ] || '';
364 } );
365 params.wpbc_settings_calendar_preview_disable_timeslots_tooltip = payload.booking_disable_timeslots_in_tooltip === 'On' ? 'On' : 'Off';
366 params.wpbc_settings_calendar_preview_timeslot_word = payload.booking_highlight_timeslot_word || '';
367 params.wpbc_settings_calendar_preview_show_availability_tooltip = payload.booking_is_show_availability_in_tooltips === 'On' ? 'On' : 'Off';
368 params.wpbc_settings_calendar_preview_availability_word = payload.booking_highlight_availability_word || '';
369 params.wpbc_settings_calendar_preview_show_availability_cell = payload.booking_is_show_availability_in_date_cell === 'On' ? 'On' : 'Off';
370 params.wpbc_settings_calendar_preview_availability_cell_word = payload.booking_highlight_availability_word_in_date_cell || '';
371 params.wpbc_settings_calendar_preview_show_cost_tooltip = payload.booking_is_show_cost_in_tooltips === 'On' ? 'On' : 'Off';
372 params.wpbc_settings_calendar_preview_cost_word = payload.booking_highlight_cost_word || '';
373 params.wpbc_settings_calendar_preview_show_cost_cell = payload.booking_is_show_cost_in_date_cell === 'On' ? 'On' : 'Off';
374 params.wpbc_settings_calendar_preview_cost_currency = payload.booking_cost_in_date_cell_currency || '';
375 params.wpbc_settings_calendar_preview_show_booked_details = payload.booking_is_show_booked_data_in_tooltips === 'On' ? 'On' : 'Off';
376 params.wpbc_settings_calendar_preview_booked_details = payload.booking_booked_data_in_tooltips || '';
377 }
378
379 return original_loader.apply( this, arguments );
380 };
381 w.wpbc_calendar__load_data__ajx.wpbc_settings_calendar_preview_patched = true;
382 }
383
384 function sync_changeover_preview_class( payload ) {
385 var data = payload || collect_payload();
386 var is_enabled = data.booking_range_selection_time_is_active === 'On' && data.booking_change_over_days_triangles !== 'Off';
387
388 $( '[data-wpbc-calendar-preview="1"], [data-wpbc-calendar-preview="1"] .wpbc_calendar_wraper' )
389 .toggleClass( 'wpbc_change_over_triangle', is_enabled );
390 $( '[data-wpbc-calendar-preview="1"] .wpbc_calendar_legend_table_width_height' ).parent( 'span' )
391 .toggleClass( 'wpbc_change_over_triangle', is_enabled );
392 }
393
394 function sync_mobile_months_preview( resource_id, payload ) {
395 var data = payload || collect_payload();
396 var allow_mobile_months = data.booking_calendar_allow_several_months_on_mobile === 'On';
397 var months_count = get_months_count() || 3;
398
399 if ( ! resource_id ) {
400 return;
401 }
402
403 if ( w._wpbc && typeof w._wpbc.set_other_param === 'function' ) {
404 w._wpbc.set_other_param( 'is_allow_several_months_on_mobile', allow_mobile_months );
405 }
406
407 if ( allow_mobile_months && typeof w.wpbc_calendar__update_months_number === 'function' ) {
408 w.wpbc_calendar__update_months_number( resource_id, months_count );
409 return;
410 }
411
412 if ( typeof w.wpbc_calendar__auto_update_months_number__on_resize === 'function' ) {
413 w.wpbc_calendar__auto_update_months_number__on_resize( resource_id );
414 } else if ( typeof w.wpbc_calendar__update_months_number === 'function' ) {
415 w.wpbc_calendar__update_months_number( resource_id, $( w ).width() <= 782 ? 1 : months_count );
416 }
417 }
418
419 function apply_standard_days_selection( resource_id, days_selection ) {
420 var ds = days_selection || {};
421 var mode = String( ds.days_select_mode || 'multiple' );
422 var fixed_week_days = parse_number_list( ds.fixed__week_days__start );
423 var dynamic_specific = parse_number_list( ds.dynamic__days_specific );
424 var dynamic_week_days = parse_number_list( ds.dynamic__week_days__start );
425
426 fixed_week_days = fixed_week_days.length ? fixed_week_days : [ -1 ];
427 dynamic_week_days = dynamic_week_days.length ? dynamic_week_days : [ -1 ];
428
429 if ( 'single' === mode && typeof w.wpbc_cal_days_select__single === 'function' ) {
430 w.wpbc_cal_days_select__single( resource_id );
431 return true;
432 }
433
434 if ( 'multiple' === mode && typeof w.wpbc_cal_days_select__multiple === 'function' ) {
435 w.wpbc_cal_days_select__multiple( resource_id );
436 return true;
437 }
438
439 if ( 'fixed' === mode && typeof w.wpbc_cal_days_select__fixed === 'function' ) {
440 w.wpbc_cal_days_select__fixed(
441 resource_id,
442 normalize_fixed_range_days_count( ds.fixed__days_num ),
443 fixed_week_days
444 );
445 return true;
446 }
447
448 if ( 'dynamic' === mode && typeof w.wpbc_cal_days_select__range === 'function' ) {
449 w.wpbc_cal_days_select__range(
450 resource_id,
451 parseInt( ds.dynamic__days_min || 1, 10 ),
452 parseInt( ds.dynamic__days_max || 1, 10 ),
453 dynamic_specific,
454 dynamic_week_days
455 );
456 return true;
457 }
458
459 return false;
460 }
461
462 function apply_calendar_settings_to_calendar( days_selection, should_reinit ) {
463 var resource_id = get_resource_id();
464 var ds = days_selection || {};
465 var payload = collect_payload();
466 var fixed_week_days;
467 var dynamic_specific;
468 var dynamic_week_days;
469 var $calendar;
470
471 if ( ! resource_id || ! w._wpbc || typeof w._wpbc.calendar__set_param_value !== 'function' ) {
472 return;
473 }
474
475 fixed_week_days = parse_number_list( ds.fixed__week_days__start );
476 dynamic_specific = parse_number_list( ds.dynamic__days_specific );
477 dynamic_week_days = parse_number_list( ds.dynamic__week_days__start );
478
479 set_calendar_param( resource_id, 'booking_max_monthes_in_calendar', String( payload.booking_max_monthes_in_calendar || '1y' ) );
480 set_calendar_param( resource_id, 'booking_start_day_weeek', String( payload.booking_start_day_weeek || '0' ) );
481 set_calendar_param( resource_id, 'calendar_number_of_months', String( get_months_count() || 3 ) );
482 set_calendar_param( resource_id, 'calendar_scroll_to', false );
483 set_calendar_param( resource_id, 'is_enabled_change_over', payload.booking_range_selection_time_is_active === 'On' );
484 set_calendar_param( resource_id, 'days_select_mode', String( ds.days_select_mode || 'multiple' ) );
485 set_calendar_param( resource_id, 'fixed__days_num', normalize_fixed_range_days_count( ds.fixed__days_num ) );
486 set_calendar_param( resource_id, 'fixed__week_days__start', fixed_week_days.length ? fixed_week_days : [ -1 ] );
487 set_calendar_param( resource_id, 'dynamic__days_min', parseInt( ds.dynamic__days_min || 1, 10 ) );
488 set_calendar_param( resource_id, 'dynamic__days_max', parseInt( ds.dynamic__days_max || 1, 10 ) );
489 set_calendar_param( resource_id, 'dynamic__days_specific', dynamic_specific );
490 set_calendar_param( resource_id, 'dynamic__week_days__start', dynamic_week_days.length ? dynamic_week_days : [ -1 ] );
491 set_calendar_param( resource_id, 'booking_recurrent_time', get_form().find( '[name="booking_recurrent_time"]' ).prop( 'checked' ) ? 'On' : 'Off' );
492
493 if ( w._wpbc && typeof w._wpbc.set_other_param === 'function' ) {
494 w._wpbc.set_other_param( 'is_enabled_change_over', payload.booking_range_selection_time_is_active === 'On' );
495 w._wpbc.set_other_param( 'is_allow_several_months_on_mobile', payload.booking_calendar_allow_several_months_on_mobile === 'On' );
496 }
497
498 sync_changeover_preview_class( payload );
499 sync_mobile_months_preview( resource_id, payload );
500
501 if ( typeof w.wpbc__conditions__SAVE_INITIAL__days_selection_params__bm === 'function' ) {
502 w.wpbc__conditions__SAVE_INITIAL__days_selection_params__bm( resource_id );
503 }
504
505 $calendar = $( '#calendar_booking' + resource_id );
506 if ( should_reinit && $calendar.length && apply_standard_days_selection( resource_id, ds ) ) {
507 return;
508 }
509
510 if ( should_reinit && $calendar.length && typeof w.wpbc_cal__re_init === 'function' ) {
511 w.wpbc_cal__re_init( resource_id );
512 }
513 }
514
515 function schedule_calendar_settings_apply( days_selection ) {
516 $.each( [ 0, 120, 420, 900, 1400 ], function ( index, delay ) {
517 setTimeout( function () {
518 apply_calendar_settings_to_calendar( days_selection || get_days_selection_from_form(), true );
519 }, delay );
520 } );
521 }
522
523 function get_days_selection_from_form() {
524 var data = collect_payload();
525 var mode = data.booking_type_of_day_selections === 'range'
526 ? ( is_range_supported() ? data.booking_range_selection_type : 'dynamic' )
527 : data.booking_type_of_day_selections;
528 var fixed_days = data.booking_range_start_day_mode === '-1' ? '-1' : ( data.booking_range_start_day_weekdays || '-1' );
529 var dynamic_days = data.booking_range_start_day_dynamic_mode === '-1' ? '-1' : ( data.booking_range_start_day_dynamic_weekdays || '-1' );
530
531 if ( Array.isArray( fixed_days ) ) {
532 fixed_days = fixed_days.join( ',' );
533 }
534 if ( Array.isArray( dynamic_days ) ) {
535 dynamic_days = dynamic_days.join( ',' );
536 }
537
538 return {
539 days_select_mode: mode || 'multiple',
540 fixed__days_num: normalize_fixed_range_days_count( data.booking_range_selection_days_count ),
541 fixed__week_days__start: fixed_days || '-1',
542 dynamic__days_min: parseInt( data.booking_range_selection_days_count_dynamic || 1, 10 ),
543 dynamic__days_max: parseInt( data.booking_range_selection_days_max_count_dynamic || 1, 10 ),
544 dynamic__days_specific: data.booking_range_selection_days_specific_num_dynamic || '',
545 dynamic__week_days__start: dynamic_days || '-1'
546 };
547 }
548
549 function refresh_conditional_controls() {
550 var $form = get_form();
551 var day_mode = $form.find( '[name="booking_type_of_day_selections"]:checked' ).val() || 'multiple';
552 var range_type = $form.find( '[name="booking_range_selection_type"]:checked' ).val() || 'dynamic';
553 var fixed_start = $form.find( '[name="booking_range_start_day_mode"]:checked' ).val() || '-1';
554 var dynamic_start = $form.find( '[name="booking_range_start_day_dynamic_mode"]:checked' ).val() || '-1';
555 var is_changeover = $form.find( '[name="booking_range_selection_time_is_active"]' ).prop( 'checked' );
556 var is_legend = $form.find( '[name="booking_is_show_legend"]' ).prop( 'checked' );
557 var is_timeslot_tooltip = $form.find( '[name="booking_show_timeslots_in_tooltip"]' ).prop( 'checked' );
558 var is_availability_tooltip = $form.find( '[name="booking_is_show_availability_in_tooltips"]' ).prop( 'checked' );
559 var is_availability_cell = $form.find( '[name="booking_is_show_availability_in_date_cell"]' ).prop( 'checked' );
560 var is_cost_tooltip = $form.find( '[name="booking_is_show_cost_in_tooltips"]' ).prop( 'checked' );
561 var is_cost_cell = $form.find( '[name="booking_is_show_cost_in_date_cell"]' ).prop( 'checked' );
562 var is_booked_tooltip = $form.find( '[name="booking_is_show_booked_data_in_tooltips"]' ).prop( 'checked' );
563
564 $( '[data-wpbc-calendar-range-settings="1"]' ).toggleClass( 'is-visible', day_mode === 'range' );
565 $( '[data-wpbc-calendar-range-upgrade-note="1"]' ).toggleClass( 'is-visible', day_mode === 'range' && ! is_range_supported() );
566 $( '[data-wpbc-calendar-range-type]' ).removeClass( 'is-visible' );
567 $( '[data-wpbc-calendar-range-type="' + range_type + '"]' ).addClass( 'is-visible' );
568 $( '[data-wpbc-calendar-weekday-checks="booking_range_start_day_weekdays"]' ).toggleClass( 'is-visible', fixed_start !== '-1' );
569 $( '[data-wpbc-calendar-weekday-checks="booking_range_start_day_dynamic_weekdays"]' ).toggleClass( 'is-visible', dynamic_start !== '-1' );
570 $( '[data-wpbc-calendar-changeover-settings="1"]' ).toggleClass( 'is-visible', !! is_changeover );
571 $( '[data-wpbc-calendar-legend-settings="1"]' ).toggleClass( 'is-visible', !! is_legend );
572 $( '[data-wpbc-calendar-timeslot-tooltip-settings="1"]' ).toggleClass( 'is-visible', !! is_timeslot_tooltip );
573 $( '[data-wpbc-calendar-availability-tooltip-settings="1"]' ).toggleClass( 'is-visible', !! is_availability_tooltip );
574 $( '[data-wpbc-calendar-availability-cell-settings="1"]' ).toggleClass( 'is-visible', !! is_availability_cell );
575 $( '[data-wpbc-calendar-cost-tooltip-settings="1"]' ).toggleClass( 'is-visible', !! is_cost_tooltip );
576 $( '[data-wpbc-calendar-cost-cell-settings="1"]' ).toggleClass( 'is-visible', !! is_cost_cell );
577 $( '[data-wpbc-calendar-booked-tooltip-settings="1"]' ).toggleClass( 'is-visible', !! is_booked_tooltip );
578
579 if ( is_changeover ) {
580 $form.find( '[name="booking_recurrent_time"], [name="booking_last_checkout_day_available"]' ).prop( 'checked', false );
581 }
582 if ( $form.find( '[name="booking_recurrent_time"]' ).prop( 'checked' ) ) {
583 $form.find( '[name="booking_range_selection_time_is_active"]' ).prop( 'checked', false );
584 $( '[data-wpbc-calendar-changeover-settings="1"]' ).removeClass( 'is-visible' );
585 }
586 }
587
588 function set_calendar_loading( is_loading ) {
589 var $panel = $( '[data-wpbc-calendar-panel="1"]' );
590
591 $panel.toggleClass( 'is-loading', !! is_loading );
592 $panel.find( '.wpbc_calendar_settings_loading' ).remove();
593
594 if ( is_loading ) {
595 $panel.append(
596 '<div class="wpbc_calendar_loading wpbc_calendar_settings_loading">' +
597 '<span class="wpbc_icn_autorenew wpbc_animation_spin"></span>&nbsp;' +
598 trim_text( cfg.i18n && cfg.i18n.loading ? cfg.i18n.loading : 'Loading' ) +
599 '</div>'
600 );
601 }
602 }
603
604 function refresh_preview() {
605 var data = collect_payload();
606 var signature;
607
608 if ( is_saving ) {
609 return;
610 }
611
612 data.action = cfg.preview_action;
613 data.nonce = cfg.nonce;
614 signature = JSON.stringify( data );
615 if ( signature === last_preview_signature ) {
616 return;
617 }
618
619 if ( preview_ajax && preview_ajax.readyState !== 4 ) {
620 preview_ajax.abort();
621 }
622 last_preview_signature = signature;
623
624 set_calendar_loading( true );
625 preview_ajax = $.post( cfg.ajax_url, data )
626 .done( function ( response ) {
627 if ( response && response.success && response.data && response.data.html ) {
628 $( '[data-wpbc-calendar-preview="1"]' ).replaceWith( response.data.html );
629 cfg.days_selection = response.data.days_selection || get_days_selection_from_form();
630 schedule_calendar_settings_apply( cfg.days_selection );
631 return;
632 }
633
634 show_message(
635 response && response.data && response.data.message ? response.data.message : ( cfg.i18n && cfg.i18n.preview_failed ? cfg.i18n.preview_failed : 'Unable to refresh calendar preview.' ),
636 'error',
637 10000
638 );
639 } )
640 .fail( function ( xhr, text_status ) {
641 if ( 'abort' === text_status ) {
642 return;
643 }
644 last_preview_signature = '';
645 show_message( cfg.i18n && cfg.i18n.preview_failed ? cfg.i18n.preview_failed : 'Unable to refresh calendar preview.', 'error', 10000 );
646 } )
647 .always( function () {
648 set_calendar_loading( false );
649 } );
650 }
651
652 function schedule_preview_refresh( delay ) {
653 clearTimeout( preview_timer );
654 if ( is_saving ) {
655 return;
656 }
657 preview_timer = setTimeout( refresh_preview, typeof delay === 'number' ? delay : 180 );
658 }
659
660 function is_text_typing_field( field ) {
661 var tag_name = String( field && field.tagName ? field.tagName : '' ).toLowerCase();
662 var input_type = String( field && field.type ? field.type : '' ).toLowerCase();
663
664 return (
665 'textarea' === tag_name ||
666 ( 'input' === tag_name && -1 !== $.inArray( input_type, [ 'text', 'number', 'search', 'email', 'url', 'tel' ] ) )
667 );
668 }
669
670 function is_full_preview_only_field( field_name ) {
671 field_name = String( field_name || '' ).replace( /\[\]$/, '' );
672
673 return (
674 'booking_is_show_legend' === field_name ||
675 0 === field_name.indexOf( 'booking_legend_' ) ||
676 'booking_show_timeslots_in_tooltip' === field_name ||
677 'booking_disable_timeslots_in_tooltip' === field_name ||
678 0 === field_name.indexOf( 'booking_highlight_' ) ||
679 'booking_is_show_availability_in_tooltips' === field_name ||
680 'booking_is_show_availability_in_date_cell' === field_name ||
681 'booking_is_show_cost_in_tooltips' === field_name ||
682 'booking_is_show_cost_in_date_cell' === field_name ||
683 'booking_cost_in_date_cell_currency' === field_name ||
684 'booking_is_show_booked_data_in_tooltips' === field_name ||
685 'booking_booked_data_in_tooltips' === field_name
686 );
687 }
688
689 function apply_calendar_settings_safely( days_selection ) {
690 try {
691 apply_calendar_settings_to_calendar( days_selection, true );
692 } catch ( error ) {
693 if ( w.console && typeof w.console.warn === 'function' ) {
694 w.console.warn( '[WPBC] Calendar Settings preview apply failed; full preview refresh will continue.', error );
695 }
696 }
697 }
698
699 function save_settings() {
700 var $button = $( '[data-wpbc-calendar-save="1"]' );
701 var original_text = $button.data( 'wpbc-original-text' );
702 var data = collect_payload();
703
704 if ( ! original_text ) {
705 original_text = $button.html();
706 $button.data( 'wpbc-original-text', original_text );
707 }
708
709 data.action = cfg.action;
710 data.nonce = cfg.nonce;
711
712 is_saving = true;
713 clearTimeout( preview_timer );
714 if ( preview_ajax && preview_ajax.readyState !== 4 ) {
715 preview_ajax.abort();
716 }
717 preview_ajax = null;
718 last_preview_signature = '';
719 set_calendar_loading( false );
720
721 $button.addClass( 'disabled' ).attr( 'aria-disabled', 'true' );
722 $button.find( '.in-button-text' ).html( '&nbsp;&nbsp;' + trim_text( cfg.i18n && cfg.i18n.saving ? cfg.i18n.saving : 'Saving' ) + '...' );
723
724 $.post( cfg.ajax_url, data )
725 .done( function ( response ) {
726 if ( response && response.success ) {
727 show_message( response.data && response.data.message ? response.data.message : ( cfg.i18n && cfg.i18n.saved ? cfg.i18n.saved : 'Saved' ), 'success', 3000 );
728 cfg.settings = response.data && response.data.settings ? response.data.settings : cfg.settings;
729 cfg.days_selection = response.data && response.data.days_selection ? response.data.days_selection : get_days_selection_from_form();
730 schedule_calendar_settings_apply( cfg.days_selection );
731 $( document ).trigger( 'wpbc:setup-wizard:step-saved', [ 'date_selection' ] );
732 return;
733 }
734
735 show_message(
736 response && response.data && response.data.message ? response.data.message : ( cfg.i18n && cfg.i18n.save_failed ? cfg.i18n.save_failed : 'Unable to save calendar settings.' ),
737 'error',
738 10000
739 );
740 } )
741 .fail( function ( xhr, text_status ) {
742 var message;
743
744 if ( 'abort' === text_status ) {
745 return;
746 }
747
748 message = xhr && xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message
749 ? xhr.responseJSON.data.message
750 : ( cfg.i18n && cfg.i18n.save_failed ? cfg.i18n.save_failed : 'Unable to save calendar settings.' );
751
752 show_message( message, 'error', 10000 );
753 } )
754 .always( function () {
755 is_saving = false;
756 $button.removeClass( 'disabled' ).removeAttr( 'aria-disabled' ).html( original_text );
757 } );
758 }
759
760 function bind_events() {
761 $( document ).on( 'click', '.wpbc_calendar_rightbar_tabs [role="tab"]', function ( event ) {
762 event.preventDefault();
763 switch_panel( $( this ) );
764 } );
765
766 $( document ).on( 'click', '.wpbc_calendar_premium_dismiss a', function ( event ) {
767 event.stopPropagation();
768 } );
769
770 $( document ).on( 'click', '.wpbc_calendar_rightbar_panels .wpbc_ui__collapsible_group > .group__header', function ( event ) {
771 event.preventDefault();
772 toggle_group( $( this ) );
773 } );
774
775 $( document ).on( 'click', '[data-wpbc-calendar-save="1"]', function ( event ) {
776 event.preventDefault();
777 if ( ! $( this ).hasClass( 'disabled' ) ) {
778 save_settings();
779 }
780 } );
781
782 $( document ).on( 'click', '[data-wpbc-calendar-premium-range-info="1"], [data-wpbc-calendar-premium-changeover-info="1"]', function ( event ) {
783 event.preventDefault();
784 event.stopImmediatePropagation();
785 if ( $( this ).is( '[data-wpbc-calendar-premium-changeover-info="1"]' ) ) {
786 $( this ).prop( 'checked', false );
787 }
788 refresh_conditional_controls();
789 show_premium_notice( $( this ) );
790 } );
791
792 $( document ).on( 'change input', '[data-wpbc-calendar-settings-form="1"] input, [data-wpbc-calendar-settings-form="1"] select, [data-wpbc-calendar-settings-form="1"] textarea', function ( event ) {
793 var field_name = this.name || '';
794 var preview_delay = ( 'input' === event.type && is_text_typing_field( this ) ) ? 850 : 180;
795
796 if ( is_locked_changeover_control( this ) ) {
797 $( this ).prop( 'checked', false );
798 refresh_conditional_controls();
799 show_premium_notice( $( this ) );
800 return;
801 }
802
803 refresh_conditional_controls();
804 schedule_preview_refresh( preview_delay );
805
806 if ( is_full_preview_only_field( field_name ) ) {
807 return;
808 }
809
810 apply_calendar_settings_safely( get_days_selection_from_form() );
811 } );
812
813 $( document ).on( 'change', '[data-wpbc-calendar-premium="1"]', function () {
814 show_premium_notice( $( this ) );
815 } );
816
817 $( document ).on( 'change', '#wpbc_calendar_resource_id, #wpbc_calendar_months_count', function () {
818 schedule_preview_refresh();
819 } );
820 }
821
822 patch_calendar_data_loader();
823
824 $( function () {
825 if ( ! $( '[data-wpbc-calendar-page="1"]' ).length ) {
826 return;
827 }
828
829 bind_events();
830 patch_calendar_data_loader();
831 refresh_conditional_controls();
832 sync_left_navigation_active_section();
833 apply_open_section_from_url();
834 schedule_calendar_settings_apply( cfg.days_selection || get_days_selection_from_form() );
835 } );
836 }( jQuery, window ) );
837