PluginProbe
Booking Calendar / 11.4.1
Booking Calendar v11.4.1
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-themes / _src / settings_themes_page.js

settings_themes_page.js in Booking Calendar 11.4.1, at includes/page-settings-themes/_src/settings_themes_page.js

850 lines 30.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Appearance / Theme settings page UI.
3 */
4 ( function ( $, w ) {
5 'use strict';
6
7 var cfg = w.wpbc_settings_themes_page || {};
8 var preview_ajax = null;
9 var preview_timer = 0;
10 var preview_notice_timer = 0;
11 var preview_notice_message_timer = 0;
12
13 function trim_text( value ) {
14 return String( value || '' ).trim();
15 }
16
17 function make_asset_url( path ) {
18 path = String( path || '' );
19 if ( /^https?:\/\//i.test( path ) || /^\/\//.test( path ) ) {
20 return path;
21 }
22 return String( cfg.plugin_url || '' ).replace( /\/$/, '' ) + path;
23 }
24
25 function show_message( message, type, delay ) {
26 if ( typeof w.wpbc_admin_show_message === 'function' ) {
27 w.wpbc_admin_show_message( message, type || 'info', delay || 4000, false );
28 }
29 }
30
31 function pulse_element( $element, duration ) {
32 if ( ! $element || ! $element.length ) {
33 return;
34 }
35
36 $element
37 .removeClass( 'wpbc_theme_attention_pulse' )
38 .each( function () {
39 void this.offsetWidth;
40 } )
41 .addClass( 'wpbc_theme_attention_pulse' );
42
43 setTimeout( function () {
44 $element.removeClass( 'wpbc_theme_attention_pulse' );
45 }, duration || 2100 );
46 }
47
48 function pulse_latest_warning_notice() {
49 clearTimeout( preview_notice_message_timer );
50 preview_notice_message_timer = setTimeout( function () {
51 pulse_element( $( '#ajax_working .wpbc_inner_message.notice-warning' ).last() );
52 }, 50 );
53 }
54
55 function show_highlighted_notice( message, type, delay, $control ) {
56 if ( $control && $control.length ) {
57 pulse_element( $control );
58 }
59
60 show_message( message, type || 'warning', delay || 9000 );
61 pulse_latest_warning_notice();
62 }
63
64 function switch_panel( $tab ) {
65 var panel_id = $tab.attr( 'aria-controls' );
66 var $tabs = $tab.closest( '.wpbc_theme_rightbar_tabs' ).find( '[role="tab"]' );
67 var $panels = $( '.wpbc_theme_rightbar_panels [role="tabpanel"]' );
68
69 $tabs.attr( 'aria-selected', 'false' );
70 $tab.attr( 'aria-selected', 'true' );
71
72 $panels.attr( 'hidden', 'hidden' ).attr( 'aria-hidden', 'true' );
73 $( '#' + panel_id ).removeAttr( 'hidden' ).attr( 'aria-hidden', 'false' );
74 }
75
76 function toggle_group( $button ) {
77 var $group = $button.closest( '.wpbc_ui__collapsible_group' );
78 var $fields = $group.find( '> .group__fields' );
79 var is_open = $group.hasClass( 'is-open' );
80
81 $group.toggleClass( 'is-open', ! is_open );
82 $button.attr( 'aria-expanded', is_open ? 'false' : 'true' );
83 $fields.prop( 'hidden', is_open ).attr( 'aria-hidden', is_open ? 'true' : 'false' );
84 }
85
86 function get_form() {
87 return $( '[data-wpbc-theme-settings-form="1"]' ).first();
88 }
89
90 function collect_payload() {
91 var $form = get_form();
92 var data = {};
93
94 sync_form_style_choice();
95
96 $.each( $form.serializeArray(), function ( index, item ) {
97 if ( 0 === String( item.name || '' ).indexOf( 'wpbc_setup' ) ) {
98 return;
99 }
100 data[ item.name ] = item.value;
101 } );
102
103 data.booking_timeslot_picker = $form.find( '[name="booking_timeslot_picker"]' ).prop( 'checked' ) ? 'On' : 'Off';
104 data.resource_id = $( '#wpbc_theme_resource_id' ).val() || '';
105 data.months_count = $( '#wpbc_theme_months_count' ).val() || '';
106 data.preview_mode = $( '#wpbc_theme_preview_mode' ).val() || 'calendar';
107 data.custom_booking_form = $( '#wpbc_theme_custom_form' ).val() || 'standard';
108
109 return data;
110 }
111
112 function map_form_style_choice( value ) {
113 var choice = String( value || 'light_bordered' );
114 var current_theme = $( '#booking_form_theme' ).val() || '';
115 var parts;
116 var preset;
117
118 if ( 'custom' === choice ) {
119 return {
120 theme : current_theme,
121 preset: 'custom'
122 };
123 }
124
125 parts = choice.split( '_' );
126 preset = parts[1] || 'bordered';
127 if ( [ 'bordered', 'none', 'soft' ].indexOf( preset ) === -1 ) {
128 preset = 'bordered';
129 }
130
131 return {
132 theme : ( 'dark' === parts[0] ) ? 'wpbc_theme_dark_1' : '',
133 preset: preset
134 };
135 }
136
137 function get_form_style_choice_from_values() {
138 var theme = $( '#booking_form_theme' ).val() || '';
139 var preset = $( '#booking_form_appearance_preset' ).val() || 'bordered';
140 var prefix = theme ? 'dark' : 'light';
141
142 if ( 'custom' === preset ) {
143 return 'custom';
144 }
145 if ( [ 'bordered', 'none', 'soft' ].indexOf( preset ) === -1 ) {
146 preset = 'bordered';
147 }
148
149 return prefix + '_' + preset;
150 }
151
152 function sync_form_style_choice() {
153 var $checked = get_form().find( '[name="booking_form_style"]:checked' );
154 var mapped;
155
156 if ( ! $checked.length ) {
157 return;
158 }
159
160 mapped = map_form_style_choice( $checked.val() );
161 $( '#booking_form_theme' ).val( mapped.theme );
162 $( '#booking_form_appearance_preset' ).val( mapped.preset );
163 }
164
165 function sync_form_style_choice_selection() {
166 var choice = get_form_style_choice_from_values();
167 var $choices = get_form().find( '[name="booking_form_style"]' );
168
169 $choices.prop( 'checked', false );
170 $choices.filter( '[value="' + choice + '"]' ).prop( 'checked', true );
171
172 $( '.wpbc_theme_choice' ).removeClass( 'is-selected' );
173 $choices.filter( ':checked' ).closest( '.wpbc_theme_choice' ).addClass( 'is-selected' );
174 }
175
176 function apply_form_theme() {
177 var theme = $( '#booking_form_theme' ).val() || '';
178 var $preview = $( '[data-wpbc-theme-preview="1"]' );
179 var $theme_targets = $preview.add( $preview.find( '.wpbc_container.wpbc_form, .wpbc_container_booking_form' ) );
180
181 $theme_targets.each( function () {
182 var $target = $( this );
183 var classes = String( this.className || '' ).split( /\s+/ );
184
185 $.each( classes, function ( index, class_name ) {
186 if ( /^wpbc_theme_/.test( class_name ) && ! /^wpbc_theme_preview/.test( class_name ) ) {
187 $target.removeClass( class_name );
188 }
189 } );
190 } );
191 if ( theme ) {
192 $theme_targets.addClass( theme );
193 }
194
195 sync_form_style_choice_selection();
196 }
197
198 function get_form_appearance_presets() {
199 return {
200 bordered: {
201 background : '#ffffff',
202 borderColor: '#cccccc',
203 borderWidth: '1px',
204 radius : '2px',
205 padding : '10px 30px',
206 shadow : 'rgba(0, 0, 0, 0.05) 0px 2px 6px 0px'
207 },
208 none : {
209 background : 'transparent',
210 borderColor: 'transparent',
211 borderWidth: '0px',
212 radius : '0px',
213 padding : '0px',
214 shadow : 'none'
215 },
216 soft : {
217 background : '#f9f9fa',
218 borderColor: '#fff',
219 borderWidth: '3px',
220 radius : '8px',
221 padding : '20px',
222 shadow : 'rgba(15, 23, 42, 0.06) 0px 4px 16px 0px'
223 }
224 };
225 }
226
227 function is_dark_form_theme() {
228 return 'wpbc_theme_dark_1' === String( $( '#booking_form_theme' ).val() || '' );
229 }
230
231 function get_form_appearance_preset_for_theme( preset ) {
232 var presets = get_form_appearance_presets();
233
234 if ( ! is_dark_form_theme() ) {
235 return presets[preset] || presets.bordered;
236 }
237
238 if ( 'soft' === preset ) {
239 return {
240 background : '#1f2937',
241 borderColor: '#334155',
242 borderWidth: '3px',
243 radius : '8px',
244 padding : '20px',
245 shadow : 'rgba(0, 0, 0, 0.24) 0px 4px 16px 0px'
246 };
247 }
248
249 return presets[preset] || presets.bordered;
250 }
251
252 function sanitize_theme_color( value, fallback ) {
253 var v = String( value || '' ).trim();
254 return /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.test( v ) || 'transparent' === v ? v : fallback;
255 }
256
257 function sanitize_theme_length( value, fallback ) {
258 var v = String( value || '' ).trim();
259 return /^-?\d+(?:\.\d+)?(?:px|rem|em|%)$/i.test( v ) ? v : fallback;
260 }
261
262 function sanitize_theme_spacing( value, fallback ) {
263 var v = String( value || '' ).trim().replace( /\s+/g, ' ' );
264 var parts = v ? v.split( ' ' ) : [];
265 var i;
266
267 if ( parts.length < 1 || parts.length > 4 ) {
268 return fallback;
269 }
270 for ( i = 0; i < parts.length; i++ ) {
271 if ( ! /^-?\d+(?:\.\d+)?(?:px|rem|em|%)$/i.test( parts[i] ) ) {
272 return fallback;
273 }
274 }
275 return parts.join( ' ' );
276 }
277
278 function get_form_style_presets() {
279 return cfg.form_style_presets && 'object' === typeof cfg.form_style_presets ? cfg.form_style_presets : {};
280 }
281
282 function get_current_form_style() {
283 var $checked = get_form().find( '[name="booking_form_style"]:checked' );
284 return $checked.length ? String( $checked.val() || 'light_bordered' ) : 'light_bordered';
285 }
286
287 function get_custom_form_style_defaults() {
288 return $.extend( {
289 booking_form_custom_background_color : '#ffffff',
290 booking_form_custom_border_color : '#cccccc',
291 booking_form_custom_border_width : '1px',
292 booking_form_custom_border_radius : '2px',
293 booking_form_custom_padding_vertical : '10px',
294 booking_form_custom_padding_horizontal : '30px',
295 booking_form_custom_text_color : '#1d2327',
296 booking_form_custom_field_background_color : '#ffffff',
297 booking_form_custom_field_text_color : '#3c434a',
298 booking_form_custom_field_border_color : '#cccccc',
299 booking_form_custom_button_background_color: '#066aab',
300 booking_form_custom_button_text_color : '#ffffff',
301 booking_form_custom_button_border_color : '#066aab',
302 booking_form_custom_button_hover_background_color: '#055589',
303 booking_form_custom_button_hover_text_color: '#ffffff',
304 booking_form_custom_button_hover_border_color: '#055589',
305 booking_form_custom_secondary_button_background_color: '#fdfdfd',
306 booking_form_custom_secondary_button_text_color: '#444444',
307 booking_form_custom_secondary_button_border_color: '#eeeeee',
308 booking_form_custom_secondary_button_hover_background_color: '#fdfdfd',
309 booking_form_custom_secondary_button_hover_text_color: '#444444',
310 booking_form_custom_secondary_button_hover_border_color: '#4d91cd'
311 }, cfg.custom_form_style_defaults && 'object' === typeof cfg.custom_form_style_defaults ? cfg.custom_form_style_defaults : {} );
312 }
313
314 function get_custom_form_style_css_vars() {
315 var defaults = get_custom_form_style_defaults();
316 var values = $.extend( {}, defaults, cfg.settings && 'object' === typeof cfg.settings ? cfg.settings : {} );
317
318 return {
319 '--wpbc-bfb-form-background' : sanitize_theme_color( values.booking_form_custom_background_color, defaults.booking_form_custom_background_color ),
320 '--wpbc-bfb-form-border-color' : sanitize_theme_color( values.booking_form_custom_border_color, defaults.booking_form_custom_border_color ),
321 '--wpbc-bfb-form-border-width' : sanitize_theme_length( values.booking_form_custom_border_width, defaults.booking_form_custom_border_width ),
322 '--wpbc-bfb-form-border-radius' : sanitize_theme_length( values.booking_form_custom_border_radius, defaults.booking_form_custom_border_radius ),
323 '--wpbc-bfb-form-padding' : sanitize_theme_length( values.booking_form_custom_padding_vertical, defaults.booking_form_custom_padding_vertical ) + ' ' + sanitize_theme_length( values.booking_form_custom_padding_horizontal, defaults.booking_form_custom_padding_horizontal ),
324 '--wpbc-bfb-form-box-shadow' : 'rgba(0, 0, 0, 0.05) 0px 2px 6px 0px',
325 '--wpbc_form-label-color' : sanitize_theme_color( values.booking_form_custom_text_color, defaults.booking_form_custom_text_color ),
326 '--wpbc_form-label-sublabel-color' : sanitize_theme_color( values.booking_form_custom_text_color, defaults.booking_form_custom_text_color ),
327 '--wpbc_form-label-error-color' : '#d63637',
328 '--wpbc_form-field-background-color' : sanitize_theme_color( values.booking_form_custom_field_background_color, defaults.booking_form_custom_field_background_color ),
329 '--wpbc_form-field-menu-color' : sanitize_theme_color( values.booking_form_custom_field_background_color, defaults.booking_form_custom_field_background_color ),
330 '--wpbc_form-field-text-color' : sanitize_theme_color( values.booking_form_custom_field_text_color, defaults.booking_form_custom_field_text_color ),
331 '--wpbc_form-field-border-color' : sanitize_theme_color( values.booking_form_custom_field_border_color, defaults.booking_form_custom_field_border_color ),
332 '--wpbc_form-field-border-color-spare': sanitize_theme_color( values.booking_form_custom_field_border_color, defaults.booking_form_custom_field_border_color ),
333 '--wpbc_form-field-focus-border-color': '#066aab',
334 '--wpbc_form-field-focus-shadow-color': '#066aab',
335 '--wpbc_form-field-disabled-color' : 'rgba(0, 0, 0, 0.2)',
336 '--wpbc_form-button-background-color' : sanitize_theme_color( values.booking_form_custom_button_background_color, defaults.booking_form_custom_button_background_color ),
337 '--wpbc_form-button-background-color-alt': sanitize_theme_color( values.booking_form_custom_button_background_color, defaults.booking_form_custom_button_background_color ),
338 '--wpbc_form-button-border-color' : sanitize_theme_color( values.booking_form_custom_button_border_color, defaults.booking_form_custom_button_border_color ),
339 '--wpbc_form-button-text-color' : sanitize_theme_color( values.booking_form_custom_button_text_color, defaults.booking_form_custom_button_text_color ),
340 '--wpbc_form-button-text-color-alt' : sanitize_theme_color( values.booking_form_custom_button_text_color, defaults.booking_form_custom_button_text_color ),
341 '--wpbc_form-button-hover-background-color': sanitize_theme_color( values.booking_form_custom_button_hover_background_color, defaults.booking_form_custom_button_hover_background_color ),
342 '--wpbc_form-button-hover-border-color': sanitize_theme_color( values.booking_form_custom_button_hover_border_color, defaults.booking_form_custom_button_hover_border_color ),
343 '--wpbc_form-button-hover-text-color' : sanitize_theme_color( values.booking_form_custom_button_hover_text_color, defaults.booking_form_custom_button_hover_text_color ),
344 '--wpbc_form-choice-checked-border-color': '#066aab',
345 '--wpbc_form-choice-checked-color' : '#066aab',
346 '--wpbc_form-choice-focus-color' : '#066aab',
347 '--wpbc_form-button-light-background-color': sanitize_theme_color( values.booking_form_custom_secondary_button_background_color, defaults.booking_form_custom_secondary_button_background_color ),
348 '--wpbc_form-button-light-border-color': sanitize_theme_color( values.booking_form_custom_secondary_button_border_color, defaults.booking_form_custom_secondary_button_border_color ),
349 '--wpbc_form-button-light-text-color' : sanitize_theme_color( values.booking_form_custom_secondary_button_text_color, defaults.booking_form_custom_secondary_button_text_color ),
350 '--wpbc_form-button-light-box-shadow' : '0 2px 10px 2px #ffffff54',
351 '--wpbc_form-button-light-hover-background-color': sanitize_theme_color( values.booking_form_custom_secondary_button_hover_background_color, defaults.booking_form_custom_secondary_button_hover_background_color ),
352 '--wpbc_form-button-light-hover-border-color': sanitize_theme_color( values.booking_form_custom_secondary_button_hover_border_color, defaults.booking_form_custom_secondary_button_hover_border_color ),
353 '--wpbc_form-button-light-hover-text-color': sanitize_theme_color( values.booking_form_custom_secondary_button_hover_text_color, defaults.booking_form_custom_secondary_button_hover_text_color ),
354 '--wpbc_form-button-light-hover-box-shadow': '0 2px 10px 2px #ffffff54',
355 '--wpbc_form-button-primary-hover-border-color': sanitize_theme_color( values.booking_form_custom_button_hover_border_color, defaults.booking_form_custom_button_hover_border_color ),
356 '--wpbc_form-page-break-color' : '#066aab'
357 };
358 }
359
360 function get_form_style_css_var_names() {
361 var keys = [];
362 var presets;
363
364 if ( Array.isArray( cfg.form_style_css_var_names ) && cfg.form_style_css_var_names.length ) {
365 return cfg.form_style_css_var_names;
366 }
367
368 presets = get_form_style_presets();
369 $.each( presets, function ( preset_key, preset ) {
370 if ( preset && preset.css_vars && 'object' === typeof preset.css_vars ) {
371 $.each( preset.css_vars, function ( var_name ) {
372 if ( -1 === keys.indexOf( var_name ) ) {
373 keys.push( var_name );
374 }
375 } );
376 }
377 } );
378
379 $.each( get_custom_form_style_css_vars(), function ( var_name ) {
380 if ( -1 === keys.indexOf( var_name ) ) {
381 keys.push( var_name );
382 }
383 } );
384
385 return keys;
386 }
387
388 function resolve_form_style_css_vars( style ) {
389 var presets = get_form_style_presets();
390 var preset = presets[ style ] || presets.light_bordered || {};
391
392 if ( 'custom' === style || preset.custom ) {
393 return get_custom_form_style_css_vars();
394 }
395
396 return preset.css_vars && 'object' === typeof preset.css_vars ? preset.css_vars : {};
397 }
398
399 function apply_form_style_to_preview() {
400 var style = get_current_form_style();
401 var presets = get_form_style_presets();
402 var preset = presets[ style ] || presets.light_bordered || {};
403 var css_vars = resolve_form_style_css_vars( style );
404 var css_var_names = get_form_style_css_var_names();
405 var is_custom = ( 'custom' === style || preset.custom );
406 var $preview = $( '[data-wpbc-theme-preview="1"]' );
407 var $targets = $preview.find( '.wpbc_container.wpbc_form, .wpbc_bfb_form, .wpbc_bfb__form_preview_section_container' );
408
409 $( '[data-wpbc-theme-custom-appearance-notice="1"]' ).toggle( is_custom );
410
411 if ( ! $targets.length ) {
412 return;
413 }
414
415 $targets
416 .removeClass( 'wpbc_bfb_form_appearance_custom' )
417 .each( function () {
418 var style_obj = this.style;
419
420 $.each( css_var_names, function ( index, var_name ) {
421 style_obj.removeProperty( var_name );
422 } );
423
424 $.each( css_vars, function ( var_name, value ) {
425 if ( '' !== String( value || '' ) ) {
426 style_obj.setProperty( var_name, value );
427 }
428 } );
429 } );
430
431 if ( is_custom ) {
432 $targets.filter( '.wpbc_container.wpbc_form, .wpbc_bfb_form' ).addClass( 'wpbc_bfb_form_appearance_custom' );
433 }
434 }
435
436 function resolve_form_appearance() {
437 var preset = $( '#booking_form_appearance_preset' ).val() || 'bordered';
438
439 if ( 'custom' === preset ) {
440 return get_form_appearance_presets().bordered;
441 }
442
443 return get_form_appearance_preset_for_theme( preset );
444 }
445
446 function apply_form_appearance() {
447 apply_form_style_to_preview();
448 }
449
450 function apply_calendar_skin() {
451 var $select = $( '[data-wpbc-theme-calendar-skin="1"]' );
452 var value = $select.find( 'option:selected' ).attr( 'data-wpbc-calendar-skin-url' ) || $select.val() || '';
453 var skin_url = value ? make_asset_url( value ) : '';
454
455 if ( skin_url && typeof w.wpbc__calendar__change_skin === 'function' && $( '#wpbc-calendar-skin-css' ).length ) {
456 w.wpbc__calendar__change_skin( skin_url );
457 }
458 }
459
460 function apply_time_skin() {
461 var value = $( '[data-wpbc-theme-time-skin="1"]' ).val() || '';
462 var skin_url = value ? make_asset_url( value ) : '';
463
464 if ( skin_url && typeof w.wpbc__css__change_skin === 'function' && $( '#wpbc-time_picker-skin-css' ).length ) {
465 w.wpbc__css__change_skin( skin_url, 'wpbc-time_picker-skin-css' );
466 }
467 }
468
469 function select_if_option_exists( $select, value ) {
470 var $option;
471
472 if ( ! $select.length || ! value ) {
473 return false;
474 }
475
476 $option = $select.find( 'option[value="' + value + '"]' );
477 if ( ! $option.length ) {
478 return false;
479 }
480
481 if ( $select.val() === value ) {
482 return false;
483 }
484
485 $select.val( value ).trigger( 'change' );
486 return true;
487 }
488
489 function parse_number_list( value ) {
490 if ( Array.isArray( value ) ) {
491 return $.map( value, function ( item ) {
492 var parsed = parseInt( item, 10 );
493 return isNaN( parsed ) ? null : parsed;
494 } );
495 }
496
497 return $.map( String( value || '' ).split( /\s*,\s*/ ), function ( item ) {
498 var parsed = parseInt( item, 10 );
499 return ( '' === item || isNaN( parsed ) ) ? null : parsed;
500 } );
501 }
502
503 function set_calendar_param( resource_id, key, value ) {
504 if ( w._wpbc && typeof w._wpbc.calendar__set_param_value === 'function' ) {
505 w._wpbc.calendar__set_param_value( resource_id, key, value );
506 }
507 }
508
509 function apply_days_selection_to_calendar( resource_id, days_selection, should_reinit ) {
510 var ds = days_selection || {};
511 var fixed_week_days;
512 var dynamic_specific;
513 var dynamic_week_days;
514
515 if ( ! resource_id || ! w._wpbc || typeof w._wpbc.calendar__set_param_value !== 'function' ) {
516 return;
517 }
518
519 fixed_week_days = parse_number_list( ds.fixed__week_days__start );
520 dynamic_specific = parse_number_list( ds.dynamic__days_specific );
521 dynamic_week_days = parse_number_list( ds.dynamic__week_days__start );
522
523 set_calendar_param( resource_id, 'days_select_mode', String( ds.days_select_mode || 'multiple' ) );
524 set_calendar_param( resource_id, 'fixed__days_num', parseInt( ds.fixed__days_num || 0, 10 ) );
525 set_calendar_param( resource_id, 'fixed__week_days__start', fixed_week_days.length ? fixed_week_days : [ -1 ] );
526 set_calendar_param( resource_id, 'dynamic__days_min', parseInt( ds.dynamic__days_min || 0, 10 ) );
527 set_calendar_param( resource_id, 'dynamic__days_max', parseInt( ds.dynamic__days_max || 0, 10 ) );
528 set_calendar_param( resource_id, 'dynamic__days_specific', dynamic_specific );
529 set_calendar_param( resource_id, 'dynamic__week_days__start', dynamic_week_days.length ? dynamic_week_days : [ -1 ] );
530
531 if ( typeof w.wpbc__conditions__SAVE_INITIAL__days_selection_params__bm === 'function' ) {
532 w.wpbc__conditions__SAVE_INITIAL__days_selection_params__bm( resource_id );
533 }
534
535 if ( should_reinit && typeof w.wpbc_cal__re_init === 'function' ) {
536 w.wpbc_cal__re_init( resource_id );
537 }
538 }
539
540 function ensure_calendar_only_days_selection() {
541 var $preview = $( '[data-wpbc-theme-preview="1"]' ).first();
542 var preview_mode = $preview.attr( 'data-preview-mode' ) || $( '#wpbc_theme_preview_mode' ).val() || 'calendar';
543 var resource_id = parseInt( $preview.attr( 'data-resource-id' ) || 0, 10 );
544 var expected = cfg.days_selection || {};
545 var expected_mode = String( expected.days_select_mode || 'multiple' );
546 var current_mode = null;
547 var $calendar;
548 var should_reinit = false;
549
550 if ( 'calendar' !== preview_mode || ! resource_id || ! expected_mode ) {
551 return;
552 }
553
554 if ( ! w._wpbc || typeof w._wpbc.calendar__get_param_value !== 'function' ) {
555 return;
556 }
557
558 current_mode = w._wpbc.calendar__get_param_value( resource_id, 'days_select_mode' );
559 if ( String( current_mode || '' ) === expected_mode ) {
560 return;
561 }
562
563 $calendar = $( '#calendar_booking' + resource_id );
564 should_reinit = $calendar.length && $calendar.hasClass( 'hasDatepick' );
565
566 apply_days_selection_to_calendar( resource_id, expected, should_reinit );
567 }
568
569 function apply_related_skins_for_theme( theme ) {
570 var calendar_skin = theme ? '/css/skins/24_9__dark_1.css' : '/css/skins/25_5__square_1.css';
571 var time_skin = theme ? '/css/time_picker_skins/black.css' : '/css/time_picker_skins/light__24_8.css';
572
573 select_if_option_exists( $( '[data-wpbc-theme-calendar-skin="1"]' ), calendar_skin );
574 select_if_option_exists( $( '[data-wpbc-theme-time-skin="1"]' ), time_skin );
575 }
576
577 function pulse_preview_mode_control() {
578 var $control = $( '.wpbc_theme_control_preview_mode' ).first();
579
580 pulse_element( $control );
581
582 clearTimeout( preview_notice_timer );
583 preview_notice_timer = setTimeout( function () {
584 $control.removeClass( 'wpbc_theme_attention_pulse' );
585 }, 2100 );
586 }
587
588 function get_preview_notice_message( notice_type ) {
589 var i18n = cfg.i18n || {};
590
591 if ( 'form' === notice_type ) {
592 return i18n.form_preview_option_notice || 'This option is visible in the Booking form preview. Switch Preview to Booking form to inspect it.';
593 }
594
595 return '';
596 }
597
598 function maybe_show_preview_notice( $source ) {
599 var notice_type = $source.attr( 'data-wpbc-theme-preview-notice' ) || '';
600 var preview_mode = $( '#wpbc_theme_preview_mode' ).val() || 'calendar';
601 var message = get_preview_notice_message( notice_type );
602 var $control = $( '.wpbc_theme_control_preview_mode' ).first();
603
604 if ( ! message ) {
605 return;
606 }
607
608 if ( 'form' === notice_type && 'calendar' !== preview_mode ) {
609 return;
610 }
611
612 if ( 'form' === notice_type ) {
613 pulse_preview_mode_control();
614 show_highlighted_notice( message, 'warning', 9000 );
615 return;
616 }
617
618 show_highlighted_notice( message, 'warning', 9000, $control );
619 }
620
621 function show_calendar_only_theme_notice() {
622 var preview_mode = $( '#wpbc_theme_preview_mode' ).val() || 'calendar';
623
624 if ( 'calendar' !== preview_mode ) {
625 return;
626 }
627
628 pulse_preview_mode_control();
629 show_highlighted_notice(
630 cfg.i18n && cfg.i18n.calendar_only_theme_notice ? cfg.i18n.calendar_only_theme_notice : 'Preview is set to Calendar only. Switch Preview to Booking form to inspect the form theme.',
631 'warning',
632 9000
633 );
634 }
635
636 function sync_time_picker_preview() {
637 var is_enabled = get_form().find( '[name="booking_timeslot_picker"]' ).prop( 'checked' );
638 var $preview = $( '[data-wpbc-theme-preview="1"]' );
639 var time_selectors = 'select[name^="rangetime"], select[name^="starttime"], select[name^="endtime"], select[name^="durationtime"]';
640
641 if ( w._wpbc && typeof w._wpbc.set_other_param === 'function' ) {
642 w._wpbc.set_other_param( 'is_enabled_booking_timeslot_picker', !! is_enabled );
643 }
644
645 if ( is_enabled ) {
646 if ( w._wpbc && typeof w.wpbc_hook__init_timeselector === 'function' ) {
647 w.wpbc_hook__init_timeselector();
648 }
649 return;
650 }
651
652 $preview.find( '.wpbc_times_selector' ).remove();
653 $preview.find( time_selectors ).show();
654 }
655
656 function refresh_preview_mode_controls() {
657 var preview_mode = $( '#wpbc_theme_preview_mode' ).val() || 'calendar';
658 $( '[data-wpbc-theme-form-control="1"]' ).toggleClass( 'is-visible', 'form' === preview_mode );
659 }
660
661 function set_calendar_loading( is_loading ) {
662 var $panel = $( '[data-wpbc-theme-calendar-panel="1"]' );
663
664 $panel.toggleClass( 'is-loading', !! is_loading );
665 $panel.find( '.wpbc_theme_calendar_loading' ).remove();
666
667 if ( is_loading ) {
668 $panel.append(
669 '<div class="wpbc_calendar_loading wpbc_theme_calendar_loading">' +
670 '<span class="wpbc_icn_autorenew wpbc_animation_spin"></span>&nbsp;' +
671 trim_text( cfg.i18n && cfg.i18n.loading ? cfg.i18n.loading : 'Loading' ) +
672 '</div>'
673 );
674 }
675 }
676
677 function refresh_preview() {
678 var data = collect_payload();
679
680 if ( preview_ajax && preview_ajax.readyState !== 4 ) {
681 preview_ajax.abort();
682 }
683
684 data.action = cfg.preview_action;
685 data.nonce = cfg.nonce;
686
687 set_calendar_loading( true );
688 preview_ajax = $.post( cfg.ajax_url, data )
689 .done( function ( response ) {
690 if ( response && response.success && response.data && response.data.html ) {
691 $( '[data-wpbc-theme-preview="1"]' ).replaceWith( response.data.html );
692 if ( response.data.days_selection ) {
693 cfg.days_selection = response.data.days_selection;
694 }
695 apply_form_theme();
696 apply_form_appearance();
697 apply_calendar_skin();
698 apply_time_skin();
699 ensure_calendar_only_days_selection();
700 sync_time_picker_preview();
701 return;
702 }
703
704 show_message(
705 response && response.data && response.data.message ? response.data.message : ( cfg.i18n && cfg.i18n.preview_failed ? cfg.i18n.preview_failed : 'Unable to refresh calendar preview.' ),
706 'error',
707 10000
708 );
709 } )
710 .fail( function ( xhr, text_status ) {
711 if ( 'abort' === text_status ) {
712 return;
713 }
714 show_message( cfg.i18n && cfg.i18n.preview_failed ? cfg.i18n.preview_failed : 'Unable to refresh calendar preview.', 'error', 10000 );
715 } )
716 .always( function () {
717 set_calendar_loading( false );
718 } );
719 }
720
721 function schedule_preview_refresh() {
722 clearTimeout( preview_timer );
723 preview_timer = setTimeout( refresh_preview, 180 );
724 }
725
726 function save_settings() {
727 var $button = $( '[data-wpbc-theme-save="1"]' );
728 var original_text = $button.data( 'wpbc-original-text' );
729 var data = collect_payload();
730
731 if ( ! original_text ) {
732 original_text = $button.html();
733 $button.data( 'wpbc-original-text', original_text );
734 }
735
736 data.action = cfg.action;
737 data.nonce = cfg.nonce;
738
739 $button.addClass( 'disabled' ).attr( 'aria-disabled', 'true' );
740 $button.find( '.in-button-text' ).html( '&nbsp;&nbsp;' + trim_text( cfg.i18n && cfg.i18n.saving ? cfg.i18n.saving : 'Saving' ) + '...' );
741
742 $.post( cfg.ajax_url, data )
743 .done( function ( response ) {
744 if ( response && response.success ) {
745 show_message( response.data && response.data.message ? response.data.message : ( cfg.i18n && cfg.i18n.saved ? cfg.i18n.saved : 'Saved' ), 'success', 3000 );
746 cfg.settings = response.data && response.data.settings ? response.data.settings : cfg.settings;
747 return;
748 }
749
750 show_message(
751 response && response.data && response.data.message ? response.data.message : ( cfg.i18n && cfg.i18n.save_failed ? cfg.i18n.save_failed : 'Unable to save appearance settings.' ),
752 'error',
753 10000
754 );
755 } )
756 .fail( function () {
757 show_message( cfg.i18n && cfg.i18n.save_failed ? cfg.i18n.save_failed : 'Unable to save appearance settings.', 'error', 10000 );
758 } )
759 .always( function () {
760 $button.removeClass( 'disabled' ).removeAttr( 'aria-disabled' ).html( original_text );
761 } );
762 }
763
764 function bind_events() {
765 $( document ).on( 'click', '.wpbc_theme_rightbar_tabs [role="tab"]', function ( event ) {
766 event.preventDefault();
767 switch_panel( $( this ) );
768 } );
769
770 $( document ).on( 'click', '.wpbc_theme_premium_dismiss a', function ( event ) {
771 event.stopPropagation();
772 } );
773
774 $( document ).on( 'click', '.wpbc_theme_rightbar_panels .wpbc_ui__collapsible_group > .group__header', function ( event ) {
775 event.preventDefault();
776 toggle_group( $( this ) );
777 } );
778
779 $( document ).on( 'click', '[data-wpbc-theme-save="1"]', function ( event ) {
780 event.preventDefault();
781 if ( ! $( this ).hasClass( 'disabled' ) ) {
782 save_settings();
783 }
784 } );
785
786 $( document ).on( 'submit', '[data-wpbc-theme-settings-form="1"]', function () {
787 return true;
788 } );
789
790 $( document ).on( 'change', '[name="booking_form_theme"]', function () {
791 apply_form_theme();
792 apply_related_skins_for_theme( $( this ).val() || '' );
793 show_calendar_only_theme_notice();
794 } );
795
796 $( document ).on( 'change', '[name="booking_form_style"]', function () {
797 sync_form_style_choice();
798 apply_form_theme();
799 apply_form_appearance();
800 apply_related_skins_for_theme( $( '#booking_form_theme' ).val() || '' );
801 show_calendar_only_theme_notice();
802 schedule_preview_refresh();
803 } );
804
805 $( document ).on( 'input change', '[data-wpbc-theme-appearance-control]', function () {
806 apply_form_appearance();
807 schedule_preview_refresh();
808 } );
809
810 $( document ).on( 'change', '[data-wpbc-theme-calendar-skin="1"]', function () {
811 apply_calendar_skin();
812 } );
813
814 $( document ).on( 'change', '[data-wpbc-theme-time-skin="1"]', function () {
815 apply_time_skin();
816 } );
817
818 $( document ).on( 'change', '[name="booking_timeslot_picker"]', function () {
819 sync_time_picker_preview();
820 schedule_preview_refresh();
821 } );
822
823 $( document ).on( 'change', '[data-wpbc-theme-preview-notice]', function () {
824 maybe_show_preview_notice( $( this ) );
825 } );
826
827 $( document ).on( 'change', '#wpbc_theme_resource_id, #wpbc_theme_months_count, #wpbc_theme_custom_form', function () {
828 schedule_preview_refresh();
829 } );
830
831 $( document ).on( 'change', '#wpbc_theme_preview_mode', function () {
832 refresh_preview_mode_controls();
833 schedule_preview_refresh();
834 } );
835 }
836
837 $( function () {
838 if ( ! $( '[data-wpbc-theme-page="1"]' ).length ) {
839 return;
840 }
841
842 bind_events();
843 refresh_preview_mode_controls();
844 apply_form_theme();
845 apply_form_appearance();
846 ensure_calendar_only_days_selection();
847 sync_time_picker_preview();
848 } );
849 }( jQuery, window ) );
850