PluginProbe
Booking Calendar / 11.1
Booking Calendar v11.1
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 10.11.3 All 202 releases
booking / js / client.js

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

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