PluginProbe
Booking Calendar / 10.15.7
Booking Calendar v10.15.7
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 10.11.3 10.11.4 All 201 releases
booking / js / client.js

client.js in Booking Calendar 10.15.7, at js/client.js

498 lines 19.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1
2 // Hint labels inside of input boxes.
3 jQuery( document ).ready(
4 function () {
5
6 jQuery( 'div.inside_hint' ).on(
7 'click',
8 function () {
9 jQuery( this ).css( 'visibility', 'hidden' ).siblings( '.has-inside-hint' ).trigger( 'focus' ); // FixIn: 8.7.11.12.
10 }
11 );
12
13 jQuery( 'input.has-inside-hint' ).on(
14 'blur',
15 function () {
16 if ( '' === this.value ) {
17 jQuery( this ).siblings( '.inside_hint' ).css( 'visibility', '' ); // FixIn: 8.7.11.12.
18 }
19 }
20 ).on(
21 'focus',
22 function () {
23 jQuery( this ).siblings( '.inside_hint' ).css( 'visibility', 'hidden' ); // FixIn: 8.7.11.12.
24 }
25 );
26
27 jQuery( '.booking_form_div input[type=button]' ).prop( "disabled", false );
28 }
29 );
30
31
32 // FixIn: 8.4.0.2.
33 /**
34 * Check errors in booking form fields, and show warnings if some errors exist.
35 * Check errors, like not selected dates or not filled requred form fields, or not correct entering email or phone
36 * fields, etc...
37 *
38 * @param bk_type int (ID of booking resource)
39 */
40 function wpbc_check_errors_in_booking_form( bk_type ) {
41
42 var is_error_in_field = false; // By default, all is good - no error.
43
44 var my_form = jQuery( '#booking_form' + bk_type );
45
46 if ( my_form.length ) {
47
48 var fields_with_errors_arr = [];
49
50 // Pseudo-selector that get form elements <input , <textarea , <select, <button...
51 my_form.find( ':input' ).each( function( index, el ) {
52
53 // Skip some elements
54 var skip_elements = [ 'hidden', 'button' ];
55
56 if ( -1 == skip_elements.indexOf( jQuery( el ).attr( 'type' ) ) ){
57
58 // Check Calendar Dates Selection
59 if ( ( 'date_booking' + bk_type ) == jQuery( el ).attr( 'name' ) ) {
60
61 // Show Warning only if the calendar visible ( we are at step with calendar)
62 if (
63 ( ( jQuery( '#calendar_booking' + bk_type ).is( ':visible' ) ) && ( '' == jQuery( el ).val() ) )
64 && ( wpbc_get_arr_of_selected_additional_calendars( bk_type ).length == 0 ) // FixIn: 8.5.2.26.
65 ){ // FixIn: 8.4.4.5.
66
67 var notice_message_id = wpbc_front_end__show_message__error_under_element( '#booking_form_div' + bk_type + ' .bk_calendar_frame', _wpbc.get_message( 'message_check_no_selected_dates' ) , 3000 );
68
69 //wpbc_do_scroll('#calendar_booking' + bk_type); // Scroll to the calendar // FixIn: 8.5.1.3.
70 is_error_in_field = true; // Error
71 }
72 }
73
74 // Check only visible elements at this step
75 if ( jQuery( el ).is( ':visible' ) ){
76 // console.log( '|id, type, val, visible|::', jQuery( el ).attr( 'name' ), '|' + jQuery( el ).attr( 'type' ) + '|', jQuery( el ).val(), jQuery( el ).is( ':visible' ) );
77
78 // Is Required
79 if ( jQuery( el ).hasClass( 'wpdev-validates-as-required' ) ){
80
81 // Checkboxes
82 if ( 'checkbox' == jQuery( el ).attr( 'type' ) ){
83
84 if (
85 ( ! jQuery( el ).is( ':checked' ))
86 && ( ! jQuery( ':checkbox[name="' + el.name + '"]', my_form ).is( ":checked" ) ) // FixIn: 8.5.2.12.
87 ){
88 var checkbox_parent_element;
89
90 if ( jQuery( el ).parents( '.wpdev-form-control-wrap' ).length > 0 ){
91
92 checkbox_parent_element = jQuery( el ).parents( '.wpdev-form-control-wrap' );
93
94 } else if ( jQuery( el ).parents( '.controls' ).length > 0 ){
95
96 checkbox_parent_element = jQuery( el ).parents( '.controls' );
97
98 } else {
99
100 checkbox_parent_element = jQuery( el );
101 }
102 var notice_message_id = wpbc_front_end__show_message__warning( checkbox_parent_element, _wpbc.get_message( 'message_check_required_for_check_box' ) );
103
104 fields_with_errors_arr.push( el );
105 is_error_in_field = true; // Error
106 }
107
108 // Radio boxes
109 } else if ( 'radio' == jQuery( el ).attr( 'type' ) ){
110
111 if ( !jQuery( ':radio[name="' + jQuery( el ).attr( 'name' ) + '"]', my_form ).is( ':checked' ) ){
112 var notice_message_id = wpbc_front_end__show_message__warning( jQuery( el ).parents('.wpdev-form-control-wrap'), _wpbc.get_message( 'message_check_required_for_radio_box' ) );
113 fields_with_errors_arr.push( el );
114 is_error_in_field = true; // Error
115 }
116
117 // Other elements
118 } else {
119
120 var inp_value = jQuery( el ).val();
121
122 if ( '' === wpbc_trim( inp_value ) ){ //FixIn: 8.8.1.3 // FixIn: 8.7.11.12.
123
124 var notice_message_id = wpbc_front_end__show_message__warning( el, _wpbc.get_message( 'message_check_required' ) );
125
126 fields_with_errors_arr.push( el );
127 is_error_in_field = true; // Error
128 }
129 }
130 }
131
132 // Validate Email
133 if ( jQuery( el ).hasClass( 'wpdev-validates-as-email' ) ){
134 var inp_value = jQuery( el ).val();
135 inp_value = inp_value.replace( /^\s+|\s+$/gm, '' ); // Trim white space //FixIn: 5.4.5
136 var reg = /^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,})$/;
137 if ( (inp_value != '') && (reg.test( inp_value ) == false) ){
138
139 var notice_message_id = wpbc_front_end__show_message__warning( el, _wpbc.get_message( 'message_check_email' ) );
140 fields_with_errors_arr.push( el );
141 is_error_in_field = true; // Error
142 }
143 }
144
145 // Validate For digit entering - for example for - Phone
146 // <p>Digit Field:<br />[text* dig_field class:validate_as_digit] </p>
147 // <p>Phone:<br />[text* phone class:validate_digit_8] </p>
148
149 var classList = jQuery( el ).attr( 'class' );
150
151 if ( classList ){
152
153 classList = classList.split( /\s+/ );
154
155 jQuery.each( classList, function ( cl_index, cl_item ){
156
157 ////////////////////////////////////////////////////////////////////////////////////////////
158
159 // Validate field value as "Date" [CSS class - 'validate_as_digit']
160 if ( 'validate_as_date' === cl_item ) {
161
162 // Valid values: 09-25-2018, 09/25/2018, 09-25-2018, 31-9-1918 --- m/d/Y, m.d.Y, m-d-Y, d/m/Y, d.m.Y, d-m-Y
163 var regex = new RegExp( '^[0-3]?\\d{1}[\\/\\.\\-]+[0-3]?\\d{1}[\\/\\.\\-]+[0-2]+\\d{3}$' ); // Check for Date 09/25/2018
164 var message_verif_phone = 'This field must be valid date like this ' + '09/25/2018';
165 var inp_value = jQuery( el ).val();
166
167 if ( ( inp_value != '' ) && ( regex.test( inp_value ) == false ) ){
168 wpbc_front_end__show_message__warning( el, message_verif_phone );
169 fields_with_errors_arr.push( el );
170 is_error_in_field = true; // Error
171 }
172 }
173
174 ////////////////////////////////////////////////////////////////////////////////////////////
175
176 // Validate field value as "DIGIT" [CSS class - 'validate_as_digit']
177 if ( 'validate_as_digit' === cl_item ) {
178
179 var regex = new RegExp( '^[0-9]+\\.?[0-9]*$' ); // Check for digits
180 var message_verif_phone = 'This field must contain only digits';
181 var inp_value = jQuery( el ).val();
182
183 if ( ( inp_value != '' ) && ( regex.test( inp_value ) == false ) ){
184 wpbc_front_end__show_message__warning( el, message_verif_phone );
185 fields_with_errors_arr.push( el );
186 is_error_in_field = true; // Error
187 }
188 }
189
190 ////////////////////////////////////////////////////////////////////////////////////////////
191
192 // Validate field value as "Phone" number or any other valid number wth specific number of digits [CSS class - 'validate_digit_8' || 'validate_digit_10' ]
193 var is_validate_digit = cl_item.substring( 0, 15 );
194
195 // Check if class start with 'validate_digit_'
196 if ( 'validate_digit_' === is_validate_digit ){
197
198 // Get number of digit in class: validate_digit_8 => 8 or validate_digit_10 => 10
199 var digits_to_check = parseInt( cl_item.substring( 15 ) );
200
201 // Check about any errors in
202 if ( !isNaN( digits_to_check ) ){
203
204 var regex = new RegExp( '^\\d{' + digits_to_check + '}$' ); // We was valid it as parseInt - only integer variable - digits_to_check
205 var message_verif_phone = 'This field must contain ' + digits_to_check + ' digits';
206 var inp_value = jQuery( el ).val();
207
208 if ( ( inp_value != '' ) && ( regex.test( inp_value ) == false ) ){
209 wpbc_front_end__show_message__warning( el, message_verif_phone );
210 fields_with_errors_arr.push( el );
211 is_error_in_field = true; // Error
212 }
213 }
214 }
215
216 ////////////////////////////////////////////////////////////////////////////////////////////
217
218 });
219 }
220 }
221 }
222 } );
223
224 if ( fields_with_errors_arr.length > 0 ){
225 jQuery( fields_with_errors_arr[ 0 ] ).trigger( 'focus' ); // FixIn: 9.3.1.9.
226 }
227 }
228
229 return is_error_in_field;
230 }
231
232
233 // FixIn: 8.6.1.15.
234 /**
235 * Go to next specific step in Wizard style booking form, with
236 * check all required elements specific step, otherwise show warning message!
237 *
238 * @param el
239 * @param step_num
240 * @returns {boolean}
241 */
242 function wpbc_wizard_step(el, step_num, step_from) {
243 var br_id = jQuery( el ).closest( 'form' ).find( 'input[name^="bk_type"]' ).val();
244
245 // FixIn: 8.8.1.5.
246 if ( (undefined == step_from) || (step_num > step_from) ) {
247 if ( 1 != step_num ) { // FixIn: 8.7.7.8.
248 var is_error = wpbc_check_errors_in_booking_form( br_id );
249 if ( is_error ) {
250 return false;
251 }
252 }
253 }
254
255 if ( wpbc_is_some_elements_visible( br_id, [ 'rangetime', 'durationtime', 'starttime', 'endtime' ] ) ) {
256 if ( wpbc_is_this_time_selection_not_available( br_id, document.getElementById( 'booking_form' + br_id ) ) ) {
257 return false;
258 }
259 }
260
261 if ( br_id != undefined ) {
262 jQuery( "#booking_form" + br_id + " .wpbc_wizard_step" ).css( { "display": "none" } ).removeClass( 'wpbc_wizard_step_hidden' );
263 jQuery( "#booking_form" + br_id + " .wpbc_wizard_step" + step_num ).css( { "display": "block" } );
264 return jQuery( "#booking_form" + br_id + " .wpbc_wizard_step" + step_num );
265 }
266 }
267
268
269 /**
270 * Init Buttons in Booking form Wizard
271 */
272 function wpbc_hook__init_booking_form_wizard_buttons() {
273
274 // CSS classes in Wizard Next / Prior links can be like this: <a class="wpbc_button_light wpbc_wizard_step_button wpbc_wizard_step_1">Step 1</a> | <a class="wpbc_button_light wpbc_wizard_step_button wpbc_wizard_step_2">Step 2</a> .
275
276 jQuery( '.wpbc_wizard_step_button' ).attr(
277 {
278 href: 'javascript:void(0)',
279 }
280 );
281
282 jQuery( '.wpbc_wizard_step_button' ).on(
283 'click',
284 function (event) {
285 var found_steps_arr = jQuery( this ).attr( 'class' ).match( /wpbc\_wizard\_step\_([\d]+)([\s'"]+|$)/ );
286
287 if ( (null !== found_steps_arr) && (found_steps_arr.length > 2) ) {
288 var step = parseInt( found_steps_arr[1] );
289 if ( step > 0 ) {
290 var jq_step_element;
291 // Check actual step in booking form for getting step_from number.
292 var this_formsteps_arr = jQuery( this ).parents( '.wpbc_wizard_step' ).attr( 'class' ).match( /wpbc\_wizard\_step([\d]+)([\s'"]+|$)/ );
293 if ( (null !== this_formsteps_arr) && (this_formsteps_arr.length > 2) ) {
294 var step_from = parseInt( this_formsteps_arr[1] );
295 jq_step_element = wpbc_wizard_step( this, step, step_from );
296 } else {
297 jq_step_element = wpbc_wizard_step( this, step );
298 }
299 // Do Scroll.
300 if ( false !== jq_step_element ) {
301 wpbc_do_scroll( jq_step_element ); // wpbc_do_scroll( jQuery('.wpbc_wizard_step:visible') );.
302 }
303 }
304 }
305 }
306 );
307 }
308
309 // FixIn: 10.1.3.2.
310 jQuery( document ).ready( function (){
311 wpbc_hook__init_booking_form_wizard_buttons();
312 } );
313
314
315 // FixIn: 8.6.1.15.
316 /**
317 * Check if at least one element from array of elements names in booking form visible or not.
318 * Usage Example: if ( wpbc_is_some_elements_visible( br_id, ['rangetime', 'durationtime', 'starttime', 'endtime'] )
319 * ){ ... }
320 *
321 * @param bk_type
322 * @param elements_names
323 * @returns {boolean}
324 */
325 function wpbc_is_some_elements_visible( bk_type, elements_names ){
326
327 var is_some_elements_visible = false;
328
329 var my_form = jQuery( '#booking_form' + bk_type );
330
331 if ( my_form.length ){
332
333 // Pseudo-selector that get form elements <input , <textarea , <select, <button...
334 my_form.find( ':input' ).each( function ( index, el ){
335
336 // Skip some elements
337 var skip_elements = ['hidden', 'button'];
338
339 if ( -1 == skip_elements.indexOf( jQuery( el ).attr( 'type' ) ) ){
340
341 for ( var ei = 0; ei < ( elements_names.length - 1) ; ei++ ){
342
343 // Check Calendar Dates Selection
344 if ( (elements_names[ ei ] + bk_type) == jQuery( el ).attr( 'name' ) ){
345
346 if ( jQuery( el ).is( ':visible' ) ){
347 is_some_elements_visible = true;
348 }
349 }
350 }
351 }
352 } );
353 }
354 return is_some_elements_visible;
355 }
356
357 // == Days Selections - support functions ==============================================================================
358
359 /**
360 * Get first day of selection
361 *
362 * @param dates
363 * @returns {string|*}
364 */
365 function get_first_day_of_selection(dates) {
366
367 // Multiple days selections
368 if ( dates.indexOf( ',' ) != -1 ){
369 var dates_array = dates.split( /,\s*/ );
370 var length = dates_array.length;
371 var element = null;
372 var new_dates_array = [];
373
374 for ( var i = 0; i < length; i++ ){
375
376 element = dates_array[ i ].split( /\./ );
377
378 new_dates_array[ new_dates_array.length ] = element[ 2 ] + '.' + element[ 1 ] + '.' + element[ 0 ]; //2013.12.20
379 }
380 new_dates_array.sort();
381
382 element = new_dates_array[ 0 ].split( /\./ );
383
384 return element[ 2 ] + '.' + element[ 1 ] + '.' + element[ 0 ]; //20.12.2013
385 }
386
387 // Range days selection
388 if ( dates.indexOf( ' - ' ) != -1 ){
389 var start_end_date = dates.split( " - " );
390 return start_end_date[ 0 ];
391 }
392
393 // Single day selection
394 return dates; //20.12.2013
395 }
396
397 // Get last day of selection
398 function get_last_day_of_selection(dates) {
399
400 // Multiple days selections
401 if ( dates.indexOf(',') != -1 ){
402 var dates_array =dates.split(/,\s*/);
403 var length = dates_array.length;
404 var element = null;
405 var new_dates_array = [];
406
407 for (var i = 0; i < length; i++) {
408
409 element = dates_array[i].split(/\./);
410
411 new_dates_array[new_dates_array.length] = element[2]+'.' + element[1]+'.' + element[0]; //2013.12.20
412 }
413 new_dates_array.sort();
414
415 element = new_dates_array[(new_dates_array.length-1)].split(/\./);
416
417 return element[2]+'.' + element[1]+'.' + element[0]; //20.12.2013
418 }
419
420 // Range days selection
421 if ( dates.indexOf(' - ') != -1 ){
422 var start_end_date = dates.split(" - ");
423 return start_end_date[(start_end_date.length-1)];
424 }
425
426 // Single day selection
427 return dates; //20.12.2013
428 }
429
430
431 /**
432 * Check ID of selected additional calendars
433 *
434 * @param int bk_type
435 * @returns array
436 */
437 function wpbc_get_arr_of_selected_additional_calendars( bk_type ){ // FixIn: 8.5.2.26.
438
439 var selected_additionl_calendars = [];
440
441 // Checking according additional calendars
442 if ( document.getElementById( 'additional_calendars' + bk_type ) != null ){
443
444 var id_additional_str = document.getElementById( 'additional_calendars' + bk_type ).value;
445 var id_additional_arr = id_additional_str.split( ',' );
446
447 var is_all_additional_days_unselected = true;
448
449 for ( var ia = 0; ia < id_additional_arr.length; ia++ ){
450 if ( document.getElementById( 'date_booking' + id_additional_arr[ ia ] ).value != '' ){
451 selected_additionl_calendars.push( id_additional_arr[ ia ] );
452 }
453 }
454 }
455 return selected_additionl_calendars;
456 }
457
458 // ---------------------------------------------------------------------------------------------------------------------
459 // Elementor Ready Widget Update.
460 // ---------------------------------------------------------------------------------------------------------------------
461 jQuery( function ($) {
462 // FixIn: 10.14.15.1.
463 if ( (window.elementorFrontend) && ('undefined' !== typeof (elementorFrontend.hooks)) ) {
464
465 elementorFrontend.hooks.addAction( 'frontend/element_ready/wpbc_widget_booking_form_1.default', function ($scope) {
466 // Simulate DOM ready, after updating Elementor Widget.
467 jQuery( document ).trigger( 'wpbc_elementor_ready' );
468 } );
469
470 // Catch all widget re-renders.
471 // elementorFrontend.hooks.addAction( 'frontend/element_ready/global', function ($scope) {
472 // console.log( 'Some widget was re-rendered:', $scope );
473 // } );
474 }
475 } );
476
477 // Elementor widget reinit. So we need to reinit all "jQuery( document ).ready( ...) " again with custom 'wpbc_elementor_ready' event.
478 jQuery( document ).on( 'wpbc_elementor_ready', function () {
479
480 wpbc_hook__init_booking_form_wizard_buttons();
481
482 if ( 'function' === typeof (wpbc_hook__init_timeselector) ) {
483 wpbc_hook__init_timeselector();
484 }
485
486 if ( 'function' === typeof (wpbc_update_capacity_hint) ) {
487 jQuery( '.booking_form_div' ).on( 'wpbc_booking_date_or_option_selected', function (event, resource_id) {
488 wpbc_update_capacity_hint( resource_id );
489 } );
490 }
491
492 // TODO:
493 // <?php if ('wpbc_theme_dark_1' === get_bk_option( 'booking_form_theme' ) ){ ?>
494 // jQuery( '.wpbc_widget_preview_booking_form .wpbc_center_preview,.wpbc_widget_preview_booking_form .wpbc_container.wpbc_container_booking_form,.wpbc_widget_preview_booking_form .wpbc_widget_content' ).addClass( 'wpbc_theme_dark_1' );
495 // <?php } ?>
496
497 } );
498