PluginProbe
Booking Calendar / 11.8.3
Booking Calendar v11.8.3
11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 All 203 releases
← All changes | js/client.js +282 -586 10.1111.8.3 View file →
@@ -1,392 +1,234 @@
1 -// == Submit Booking Data ==============================================================================================
1 +/**
2 + * Check errors in booking form fields, and show warnings if some errors exist.
3 + * Check errors, like not selected dates or not filled requred form fields, or not correct entering email or phone
4 + * fields, etc...
5 + *
6 + * @param resource_id int (ID of booking resource)
7 + */
8 +function wpbc_check_errors_in_booking_form( resource_id ) {
9 + var $form = jQuery( '#booking_form' + resource_id );
10 + var fields_with_errors_arr = [];
11 + var is_error_in_field = false;
12 + var skip_element_types = [ 'hidden', 'button' ];
2 13
3 -// Check fields at form and then send request
4 -function mybooking_submit( submit_form , bk_type, wpdev_active_locale){
14 + if ( ! $form.length ) {
15 + return false;
16 + }
5 17
6 - var target_elm = jQuery( ".booking_form_div" ).trigger( "booking_form_submit_click", [bk_type, submit_form, wpdev_active_locale] ); // FixIn: 8.8.3.13.
7 - if (
8 - ( jQuery( target_elm ).find( 'input[name="booking_form_show_summary"]' ).length > 0 )
9 - && ( 'pause_submit' === jQuery( target_elm ).find( 'input[name="booking_form_show_summary"]' ).val() )
10 - )
11 - {
12 - return false;
13 - }
18 + /**
19 + * Show a validation warning and register the related field as invalid.
20 + *
21 + * @param {HTMLElement|null} field Field to focus after validation.
22 + * @param {HTMLElement|jQuery|string} target Warning message target.
23 + * @param {string} message Warning message.
24 + */
25 + function add_validation_error( field, target, message ) {
26 + wpbc_front_end__show_message__warning( target, message, 'text' );
27 + is_error_in_field = true;
14 28
15 - // FixIn: 8.4.0.2.
16 - var is_error = wpbc_check_errors_in_booking_form( bk_type );
17 - if ( is_error ) { return false; }
29 + if ( field ) {
30 + fields_with_errors_arr.push( field );
31 + }
32 + }
18 33
19 - // Show message if no selected days in Calendar(s)
20 - if (document.getElementById('date_booking' + bk_type).value == '') {
34 + /**
35 + * Validate a required field.
36 + *
37 + * @param {HTMLElement} field Form field.
38 + * @param {jQuery} $field Cached jQuery field.
39 + * @param {string} field_type Field type.
40 + */
41 + function validate_required_field( field, $field, field_type ) {
42 + var warning_target;
21 43
22 - var arr_of_selected_additional_calendars = wpbc_get_arr_of_selected_additional_calendars( bk_type ); // FixIn: 8.5.2.26.
44 + if ( ! $field.hasClass( 'wpdev-validates-as-required' ) ) {
45 + return;
46 + }
23 47
24 - if ( arr_of_selected_additional_calendars.length == 0 ) {
25 - 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 );
26 - return;
27 - }
28 - }
48 + if ( 'checkbox' === field_type ) {
49 + if ( ! $field.is( ':checked' ) && ! jQuery( ':checkbox[name="' + field.name + '"]', $form ).is( ':checked' ) ) {
50 + warning_target = $field.parents( '.wpdev-form-control-wrap' ).last();
29 51
30 - var count = submit_form.elements.length;
31 - var formdata = '';
32 - var inp_value;
33 - var element;
34 - var el_type;
52 + if ( ! warning_target.length ) {
53 + warning_target = $field.parents( '.controls' ).last();
54 + }
55 + if ( ! warning_target.length ) {
56 + warning_target = $field;
57 + }
35 58
59 + add_validation_error( field, warning_target, _wpbc.get_message( 'message_check_required_for_check_box' ) );
60 + }
61 + return;
62 + }
36 63
37 - // FixIn: 6.1.1.3.
38 - if( typeof( wpbc_is_this_time_selection_not_available ) == 'function' ) {
64 + if ( 'radio' === field_type ) {
65 + if ( ! jQuery( ':radio[name="' + field.name + '"]', $form ).is( ':checked' ) ) {
66 + add_validation_error( field, $field.parents( '.wpdev-form-control-wrap' ), _wpbc.get_message( 'message_check_required_for_radio_box' ) );
67 + }
68 + return;
69 + }
39 70
40 - if ( document.getElementById('date_booking' + bk_type).value == '' ) { // Primary calendar not selected.
71 + if ( '' === wpbc_trim( $field.val() ) ) {
72 + add_validation_error( field, field, _wpbc.get_message( 'message_check_required' ) );
73 + }
74 + }
41 75
42 - if ( document.getElementById('additional_calendars' + bk_type ) != null ) { // Checking additional calendars.
76 + /**
77 + * Validate an email field and return its trimmed value.
78 + *
79 + * @param {HTMLElement} field Form field.
80 + * @param {jQuery} $field Cached jQuery field.
81 + * @returns {string}
82 + */
83 + function validate_email_field( field, $field ) {
84 + var email_value = String( $field.val() || '' ).replace( /^\s+|\s+$/gm, '' );
85 + var email_regex = /^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,})$/;
43 86
44 - var id_additional_str = document.getElementById('additional_calendars' + bk_type).value; //Loop have to be here based on , sign
45 - var id_additional_arr = id_additional_str.split(',');
46 - var is_times_dates_ok = false;
47 - for ( var ia=0;ia<id_additional_arr.length;ia++ ) {
48 - if (
49 - ( document.getElementById('date_booking' + id_additional_arr[ia] ).value != '' )
50 - && ( ! wpbc_is_this_time_selection_not_available( id_additional_arr[ia], submit_form.elements ) )
51 - ){
52 - is_times_dates_ok = true;
53 - }
54 - }
55 - if ( ! is_times_dates_ok ) return;
56 - }
57 - } else { //Primary calendar selected.
58 - if ( wpbc_is_this_time_selection_not_available( bk_type, submit_form.elements ) )
59 - return;
60 - }
61 - }
87 + if ( '' !== email_value && ! email_regex.test( email_value ) ) {
88 + add_validation_error( field, field, _wpbc.get_message( 'message_check_email' ) );
89 + }
62 90
91 + return email_value;
92 + }
63 93
94 + /**
95 + * Validate a confirmation email field using its same_as_NAME class.
96 + *
97 + * @param {HTMLElement} field Form field.
98 + * @param {string} email_value Trimmed confirmation email value.
99 + */
100 + function validate_confirmation_email_field( field, email_value ) {
101 + var primary_email_match;
102 + var primary_email_name;
103 + var $primary_email_field;
64 104
65 - // Serialize form here
66 - for ( var i = 0; i < count; i++ ){ // FixIn: 9.1.5.1.
67 - element = submit_form.elements[i];
105 + if ( field.className.indexOf( 'same_as_' ) === -1 ) {
106 + return;
107 + }
68 108
69 - if ( jQuery( element ).closest( '.booking_form_garbage' ).length ) {
70 - continue; // Skip elements from garbage // FixIn: 7.1.2.14.
71 - }
109 + primary_email_match = field.className.match( /same_as_([^\s])+/gi );
110 + if ( null === primary_email_match ) {
111 + return;
112 + }
72 113
73 - if (
74 - ( element.type !== 'button' )
75 - && ( element.type !== 'hidden' )
76 - && ( element.name !== ( 'date_booking' + bk_type ) )
77 - // && ( jQuery( element ).is( ':visible' ) ) //FixIn: 7.2.1.12.2 // Its prevent of saving hints, and some other hidden element
78 - ) { // Skip buttons and hidden element - type // FixIn: 7.2.1.12.
114 + primary_email_name = primary_email_match[ 0 ].substr( 8 );
115 + $primary_email_field = $form.find( '[name="' + primary_email_name + resource_id + '"]' );
79 116
117 + if ( $primary_email_field.length && $primary_email_field.val() !== email_value ) {
118 + add_validation_error( field, field, _wpbc.get_message( 'message_check_same_email' ) );
119 + }
120 + }
80 121
81 - // Get Element Value
82 - if ( element.type == 'checkbox' ){
122 + /**
123 + * Validate fields using the validate_as_date, validate_as_digit, or validate_digit_N classes.
124 + *
125 + * @param {HTMLElement} field Form field.
126 + * @param {jQuery} $field Cached jQuery field.
127 + */
128 + function validate_custom_field_classes( field, $field ) {
129 + var class_list = $field.attr( 'class' );
130 + var field_value;
83 131
84 - if (element.value == '') {
85 - inp_value = element.checked;
86 - } else {
87 - if (element.checked) inp_value = element.value;
88 - else inp_value = '';
89 - }
132 + if ( ! class_list ) {
133 + return;
134 + }
90 135
91 - } else if ( element.type == 'radio' ) {
136 + field_value = $field.val();
92 137
93 - if (element.checked) {
94 - inp_value = element.value;
95 - } else {
96 - // Check if this radio required, and if it does not check, then show warning, otherwise if it is not required or some other option checked skip this loop
97 - // We need to check it here, because radio have the several options with same name and type, and otherwise we will save several options with selected and empty values.
98 - if ( // FixIn: 7.0.1.62.
99 - ( element.className.indexOf('wpdev-validates-as-required') !== -1 )
100 - && ( jQuery( element ).is( ':visible' ) ) //FixIn: 7.2.1.12.2 // Its prevent of saving hints, and some other hidden element
101 - && ( ! jQuery(':radio[name="'+element.name+'"]', submit_form).is(":checked") ) ) {
102 - wpbc_front_end__show_message__warning( element, _wpbc.get_message( 'message_check_required_for_radio_box' ) ); // FixIn: 8.5.1.3.
103 - return;
104 - }
105 - continue;
106 - }
107 - } else {
108 - inp_value = element.value;
109 - }
138 + jQuery.each( class_list.split( /\s+/ ), function ( class_index, class_name ) {
139 + var digits_to_check;
140 + var message;
141 + var validation_regex;
110 142
111 - var inp_title_value = '';
143 + if ( 'validate_as_date' === class_name ) {
144 + validation_regex = new RegExp( '^[0-3]?\\d{1}[\\/\\.\\-]+[0-3]?\\d{1}[\\/\\.\\-]+[0-2]+\\d{3}$' );
145 + message = _wpbc.get_message( 'message_check_valid_date' ).replace( '{date_example}', '09/25/2018' );
112 146
113 - var input_element_type = ('input' === jQuery( element )[0].tagName.toString().toLowerCase())
114 - ? jQuery( jQuery( element )[0] ).prop( "type" ).toLowerCase()
115 - : jQuery( element )[0].tagName.toLowerCase();
147 + if ( '' !== field_value && ! validation_regex.test( field_value ) ) {
148 + add_validation_error( field, field, message );
149 + }
150 + return;
151 + }
116 152
117 - switch ( input_element_type ) {
118 - case 'text':
119 - inp_title_value = inp_value;
120 - break;
121 - case 'email':
122 - inp_title_value = inp_value;
123 - break;
124 - case 'select':
125 - inp_title_value = jQuery( element ).find( "option:selected" ).text();
126 - break;
127 - case 'radio':
128 - if ( jQuery( element ).is( ':checked' ) ) {
129 - var label_element = jQuery( element ).parents( '.wpdev-list-item' ).find( '.wpdev-list-item-label' );
130 - if ( label_element.length ) {
131 - inp_title_value = label_element.html();
132 - }
133 - }
134 - break;
135 - case 'checkbox':
136 - if ( jQuery( element ).is( ':checked' ) ) {
137 - var label_element = jQuery( element ).parents( '.wpdev-list-item' ).find( '.wpdev-list-item-label' );
138 - if ( label_element.length ) {
139 - inp_title_value = label_element.html();
140 - }
141 - }
142 - break;
143 - default:
144 - inp_title_value = inp_value;
145 - }
153 + if ( 'validate_as_digit' === class_name ) {
154 + validation_regex = new RegExp( '^[0-9]+\\.?[0-9]*$' );
146 155
156 + if ( '' !== field_value && ! validation_regex.test( field_value ) ) {
157 + add_validation_error( field, field, _wpbc.get_message( 'message_check_digits_only' ) );
158 + }
159 + return;
160 + }
147 161
148 - // Get value in selectbox of multiple selection
149 - if ( (element.type == 'selectbox-multiple') || (element.type == 'select-multiple') ){
150 - inp_value = jQuery('[name="'+element.name+'"]').val() ;
151 - if (( inp_value == null ) || (inp_value.toString() == '' ))
152 - inp_value='';
153 - }
162 + if ( 'validate_digit_' !== class_name.substring( 0, 15 ) ) {
163 + return;
164 + }
154 165
155 - // Make validation only for visible elements
156 - if ( jQuery( element ).is( ':visible' ) ) { //FixIn: 7.2.1.12.2
166 + digits_to_check = parseInt( class_name.substring( 15 ), 10 );
167 + if ( isNaN( digits_to_check ) ) {
168 + return;
169 + }
157 170
171 + validation_regex = new RegExp( '^\\d{' + digits_to_check + '}$' );
172 + message = _wpbc.get_message( 'message_check_digits_count' ).replace( '{digits}', digits_to_check );
158 173
159 - // Recheck for max num. available visitors selection
160 - if ( typeof (wpbc__is_less_than_required__of_max_available_slots__bl) == 'function' ){
161 - if ( wpbc__is_less_than_required__of_max_available_slots__bl( bk_type, element ) ){
162 - return;
163 - }
164 - }
174 + if ( '' !== field_value && ! validation_regex.test( field_value ) ) {
175 + add_validation_error( field, field, message );
176 + }
177 + } );
178 + }
165 179
180 + $form.find( ':input' ).each( function () {
181 + var field = this;
182 + var $field = jQuery( field );
183 + var field_type = $field.attr( 'type' );
184 + var email_value;
166 185
167 - // Phone validation
168 - /*if ( element.name == ('phone'+bk_type) ) {
169 - // we validate a phone number of 10 digits with no comma, no spaces, no punctuation and there will be no + sign in front the number - See more at: http://www.w3resource.com/javascript/form/phone-no-validation.php#sthash.U9FHwcdW.dpuf
170 - var reg = /^\d{10}$/;
171 - var message_verif_phone = "Please enter correctly phone number";
172 - if ( inp_value != '' )
173 - if(reg.test(inp_value) == false) {wpbc_front_end__show_message__warning( element , message_verif_phone );return;}
174 - }*/
186 + if ( -1 !== skip_element_types.indexOf( field_type ) ) {
187 + return;
188 + }
175 189
176 - // Validation Check --- Requred fields
177 - if ( element.className.indexOf('wpdev-validates-as-required') !== -1 ){
178 - if ((element.type =='checkbox') && ( element.checked === false)) {
179 - if ( ! jQuery(':checkbox[name="'+element.name+'"]', submit_form).is(":checked") ) {
180 - wpbc_front_end__show_message__warning( element , _wpbc.get_message( 'message_check_required_for_check_box' ) ); // FixIn: 8.5.1.3.
181 - return;
182 - }
183 - }
184 - if (element.type =='radio') {
185 - if ( ! jQuery(':radio[name="'+element.name+'"]', submit_form).is(":checked") ) {
186 - wpbc_front_end__show_message__warning( element , _wpbc.get_message( 'message_check_required_for_radio_box' ) ); // FixIn: 8.5.1.3.
187 - return;
188 - }
189 - }
190 + if ( '1' === String( $field.attr( 'data-wpbc-booking-submit-ignore' ) || '' ) ) {
191 + return;
192 + }
190 193
191 - if ( (element.type != 'checkbox') && (element.type != 'radio') && ( '' === wpbc_trim( inp_value ) ) ){ //FixIn: 8.8.1.3 //FixIn:7.0.1.39 // FixIn: 8.7.11.12.
192 - wpbc_front_end__show_message__warning( element , _wpbc.get_message( 'message_check_required' ) ); // FixIn: 8.5.1.3.
193 - return;
194 - }
195 - }
194 + if (
195 + ( 'date_booking' + resource_id === $field.attr( 'name' ) ) &&
196 + jQuery( '#calendar_booking' + resource_id ).is( ':visible' ) &&
197 + ( '' === $field.val() ) &&
198 + ( 0 === wpbc_get_arr_of_selected_additional_calendars( resource_id ).length )
199 + ) {
200 + add_validation_error(
201 + null,
202 + '#booking_form_div' + resource_id + ' .bk_calendar_frame',
203 + _wpbc.get_message( 'message_check_no_selected_dates' )
204 + );
205 + }
196 206
197 - // Validation Check --- Email correct filling field
198 - if ( element.className.indexOf('wpdev-validates-as-email') !== -1 ){
199 - inp_value = inp_value.replace(/^\s+|\s+$/gm,''); // Trim white space //FixIn: 5.4.5
200 - var reg = /^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,})$/;
201 - if ( inp_value != '' )
202 - if(reg.test(inp_value) == false) {
203 - wpbc_front_end__show_message__warning( element , _wpbc.get_message( 'message_check_email' ) ); // FixIn: 8.5.1.3.
204 - return;
205 - }
206 - }
207 + if ( ! $field.is( ':visible' ) ) {
208 + return;
209 + }
207 210
208 - // Validation Check --- Same Email Field
209 - if ( ( element.className.indexOf('wpdev-validates-as-email') !== -1 ) && ( element.className.indexOf('same_as_') !== -1 ) ) {
211 + validate_required_field( field, $field, field_type );
210 212
211 - // Get the name of Primary Email field from the "same_as_NAME" class
212 - var primary_email_name = element.className.match(/same_as_([^\s])+/gi);
213 - if (primary_email_name != null) { // We found
214 - primary_email_name = primary_email_name[0].substr(8);
213 + if ( $field.hasClass( 'wpdev-validates-as-email' ) ) {
214 + email_value = validate_email_field( field, $field );
215 + validate_confirmation_email_field( field, email_value );
216 + }
215 217
216 - // Recehck if such primary email field exist in the booking form
217 - if (jQuery('[name="' + primary_email_name + bk_type + '"]').length > 0) {
218 + validate_custom_field_classes( field, $field );
219 + } );
218 220
219 - // Recheck the values of the both emails, if they do not equla show warning
220 - if ( jQuery('[name="' + primary_email_name + bk_type + '"]').val() !== inp_value ) {
221 - wpbc_front_end__show_message__warning( element , _wpbc.get_message( 'message_check_same_email' ) ); // FixIn: 8.5.1.3.
222 - return;
223 - }
224 - }
225 - }
226 - // Skip one loop for the email veryfication field
227 - continue; // FixIn: 8.1.2.15.
228 - }
221 + if ( fields_with_errors_arr.length ) {
222 + jQuery( fields_with_errors_arr[ 0 ] ).trigger( 'focus' );
223 + }
229 224
230 - }
231 -
232 - // Get Form Data
233 - if ( element.name !== ('captcha_input' + bk_type) ) {
234 - if (formdata !=='') formdata += '~'; // next field element
235 -
236 - el_type = element.type;
237 - if ( element.className.indexOf('wpdev-validates-as-email') !== -1 ) el_type='email';
238 - if ( element.className.indexOf('wpdev-validates-as-coupon') !== -1 ) el_type='coupon';
239 -
240 - inp_value = inp_value + '';
241 - inp_value = inp_value.replace(new RegExp("\\^",'g'), '&#94;'); // replace registered characters
242 - inp_value = inp_value.replace(new RegExp("~",'g'), '&#126;'); // replace registered characters
243 -
244 - inp_value = inp_value.replace(/"/g, '&#34;'); // replace double quot
245 - inp_value = inp_value.replace(/'/g, '&#39;'); // replace single quot
246 -
247 - if ( 'select-one' == el_type ){
248 - el_type = 'selectbox-one';
249 - }
250 - if ( 'select-multiple' == el_type ){
251 - el_type = 'selectbox-multiple';
252 - }
253 -
254 - formdata += el_type + '^' + element.name + '^' + inp_value ; // element attr
255 -
256 - var clean_field_name = element.name;
257 - clean_field_name = clean_field_name.replaceAll( /\[\]/gi, '' );
258 - clean_field_name = clean_field_name.substr( 0, (clean_field_name.length - bk_type.toString().length) );
259 - formdata += '~' + el_type + '^' + clean_field_name + '_val' + bk_type + '^' + inp_title_value;
260 - }
261 - }
262 -
263 - } // End Fields Loop
264 -
265 -
266 - // TODO: here was function for 'Check if visitor finish dates selection.
267 -
268 -
269 - // Cpatch verify
270 - var captcha = document.getElementById('wpdev_captcha_challenge_' + bk_type);
271 -
272 - //Disable Submit button
273 - if (captcha != null) form_submit_send( bk_type, formdata, captcha.value, document.getElementById('captcha_input' + bk_type).value ,wpdev_active_locale);
274 - else form_submit_send( bk_type, formdata, '', '' , wpdev_active_locale);
275 - return;
225 + return is_error_in_field;
276 226 }
277 227
278 -
279 -// Gathering params for sending Ajax request and then send it
280 -function form_submit_send( bk_type, formdata, captcha_chalange, user_captcha ,wpdev_active_locale){
281 -
282 - var my_booking_form = '';
283 - if ( document.getElementById( 'booking_form_type' + bk_type ) != undefined ){
284 - my_booking_form = document.getElementById( 'booking_form_type' + bk_type ).value;
285 - }
286 -
287 - var my_booking_hash = '';
288 - if ( _wpbc.get_other_param( 'this_page_booking_hash' ) != '' ){
289 - my_booking_hash = _wpbc.get_other_param( 'this_page_booking_hash' );
290 - }
291 -
292 - var is_send_emeils = 1;
293 - if ( jQuery('#is_send_email_for_pending').length ) {
294 - is_send_emeils = jQuery( '#is_send_email_for_pending' ).is( ':checked' ); // FixIn: 8.7.9.5.
295 - if ( false === is_send_emeils ) { is_send_emeils = 0; }
296 - else { is_send_emeils = 1; }
297 - }
298 -
299 - if ( document.getElementById( 'date_booking' + bk_type ).value != '' ){ // FixIn: 6.1.1.3.
300 - send_ajax_submit( bk_type, formdata, captcha_chalange, user_captcha, is_send_emeils, my_booking_hash, my_booking_form, wpdev_active_locale ); // Ajax sending request
301 - } else {
302 - jQuery( '#booking_form_div' + bk_type ).hide();
303 - jQuery( '#submiting' + bk_type ).hide();
304 - }
305 -
306 - var formdata_additional_arr;
307 - var formdata_additional;
308 - var my_form_field;
309 - var id_additional;
310 - var id_additional_str;
311 - var id_additional_arr;
312 - if ( document.getElementById( 'additional_calendars' + bk_type ) != null ){
313 -
314 - id_additional_str = document.getElementById('additional_calendars' + bk_type).value; //Loop have to be here based on , sign
315 - id_additional_arr = id_additional_str.split(',');
316 - //FixIn: 10.9.4.1.
317 - for ( var ia = 0; ia < id_additional_arr.length; ia++ ) {
318 - id_additional_arr[ia] = parseInt( id_additional_arr[ia] );
319 - }
320 - if ( ! jQuery( '#booking_form_div' + bk_type ).is( ':visible' ) ) {
321 - wpbc_booking_form__spin_loader__show( bk_type ); // Show Spinner
322 - }
323 -
324 - for ( var ia = 0; ia < id_additional_arr.length; ia++ ){
325 - //FixIn: 10.9.4.1.
326 - if ( id_additional_arr[ia] <=0 ) {
327 - continue;
328 - }
329 -
330 -
331 - formdata_additional_arr = formdata;
332 - formdata_additional = '';
333 - id_additional = id_additional_arr[ia];
334 -
335 -
336 - formdata_additional_arr = formdata_additional_arr.split('~');
337 - for (var j=0;j<formdata_additional_arr.length;j++) {
338 - my_form_field = formdata_additional_arr[j].split('^');
339 - if (formdata_additional !=='') formdata_additional += '~';
340 -
341 - if (my_form_field[1].substr( (my_form_field[1].length -2),2)=='[]')
342 - my_form_field[1] = my_form_field[1].substr(0, (my_form_field[1].length - (''+bk_type).length ) - 2 ) + id_additional + '[]';
343 - else
344 - my_form_field[1] = my_form_field[1].substr(0, (my_form_field[1].length - (''+bk_type).length ) ) + id_additional ;
345 -
346 -
347 - formdata_additional += my_form_field[0] + '^' + my_form_field[1] + '^' + my_form_field[2];
348 - }
349 -
350 - if ( jQuery('#gateway_payment_forms' + bk_type).length > 0 ) { // If Payment form for main booking resources is showing then append payment form for additional calendars.
351 - jQuery('#gateway_payment_forms' + bk_type).after('<div id="gateway_payment_forms'+id_additional+'"></div>');
352 - jQuery('#gateway_payment_forms' + bk_type).after('<div id="ajax_respond_insert'+id_additional+'" style="display:none;"></div>');
353 - }
354 - // FixIn: 8.5.2.17.
355 - send_ajax_submit( id_additional ,formdata_additional,captcha_chalange,user_captcha,is_send_emeils,my_booking_hash,my_booking_form ,wpdev_active_locale ); // Submit
356 - }
357 - }
358 -}
359 -
360 -
361 -
362 -function send_ajax_submit( resource_id, formdata, captcha_chalange, user_captcha, is_send_emeils, my_booking_hash, my_booking_form, wpdev_active_locale ){
363 -
364 - // Disable Submit | Show spin loader
365 - wpbc_booking_form__on_submit__ui_elements_disable( resource_id )
366 -
367 - var is_exit = wpbc_ajx_booking__create( {
368 - 'resource_id' : resource_id,
369 - 'dates_ddmmyy_csv' : document.getElementById( 'date_booking' + resource_id ).value,
370 - 'formdata' : formdata,
371 - 'booking_hash' : my_booking_hash,
372 - 'custom_form' : my_booking_form,
373 - 'aggregate_resource_id_arr': ( ( null !== _wpbc.booking__get_param_value( resource_id, 'aggregate_resource_id_arr' ))
374 - ? _wpbc.booking__get_param_value( resource_id, 'aggregate_resource_id_arr' ).join( ',' ) : ''),
375 - 'captcha_chalange' : captcha_chalange,
376 - 'captcha_user_input' : user_captcha,
377 -
378 - 'is_emails_send' : is_send_emeils,
379 - 'active_locale' : wpdev_active_locale
380 - } );
381 - if ( true === is_exit ){
382 - return;
383 - }
384 -}
385 -
386 -
387 -
388 -// Hint labels inside of input boxes.
228 +/**
229 + * Hint labels inside of input boxes.
230 + */
389 231 jQuery( document ).ready(
390 232 function () {
391 233
392 234 jQuery( 'div.inside_hint' ).on(
@@ -391,9 +233,9 @@
391 233
392 234 jQuery( 'div.inside_hint' ).on(
393 235 'click',
394 236 function () {
395 - jQuery( this ).css( 'visibility', 'hidden' ).siblings( '.has-inside-hint' ).trigger( 'focus' ); // FixIn: 8.7.11.12.
237 + jQuery( this ).css( 'visibility', 'hidden' ).siblings( '.has-inside-hint' ).trigger( 'focus' );
396 238 }
397 239 );
398 240
399 241 jQuery( 'input.has-inside-hint' ).on(
@@ -399,15 +241,15 @@
399 241 jQuery( 'input.has-inside-hint' ).on(
400 242 'blur',
401 243 function () {
402 244 if ( '' === this.value ) {
403 - jQuery( this ).siblings( '.inside_hint' ).css( 'visibility', '' ); // FixIn: 8.7.11.12.
245 + jQuery( this ).siblings( '.inside_hint' ).css( 'visibility', '' );
404 246 }
405 247 }
406 248 ).on(
407 249 'focus',
408 250 function () {
409 - jQuery( this ).siblings( '.inside_hint' ).css( 'visibility', 'hidden' ); // FixIn: 8.7.11.12.
251 + jQuery( this ).siblings( '.inside_hint' ).css( 'visibility', 'hidden' );
410 252 }
411 253 );
412 254
413 255 jQuery( '.booking_form_div input[type=button]' ).prop( "disabled", false );
@@ -413,211 +255,11 @@
413 255 jQuery( '.booking_form_div input[type=button]' ).prop( "disabled", false );
414 256 }
415 257 );
416 258
259 +// == WIZARD ===========================================================================================================
417 260
418 -// FixIn: 8.4.0.2.
419 261 /**
420 - * Check errors in booking form fields, and show warnings if some errors exist.
421 - * Check errors, like not selected dates or not filled requred form fields, or not correct entering email or phone fields, etc...
422 - *
423 - * @param bk_type int (ID of booking resource)
424 - */
425 -function wpbc_check_errors_in_booking_form( bk_type ) {
426 -
427 - var is_error_in_field = false; // By default, all is good - no error.
428 -
429 - var my_form = jQuery( '#booking_form' + bk_type );
430 -
431 - if ( my_form.length ) {
432 -
433 - var fields_with_errors_arr = [];
434 -
435 - // Pseudo-selector that get form elements <input , <textarea , <select, <button...
436 - my_form.find( ':input' ).each( function( index, el ) {
437 -
438 - // Skip some elements
439 - var skip_elements = [ 'hidden', 'button' ];
440 -
441 - if ( -1 == skip_elements.indexOf( jQuery( el ).attr( 'type' ) ) ){
442 -
443 - // Check Calendar Dates Selection
444 - if ( ( 'date_booking' + bk_type ) == jQuery( el ).attr( 'name' ) ) {
445 -
446 - // Show Warning only if the calendar visible ( we are at step with calendar)
447 - if (
448 - ( ( jQuery( '#calendar_booking' + bk_type ).is( ':visible' ) ) && ( '' == jQuery( el ).val() ) )
449 - && ( wpbc_get_arr_of_selected_additional_calendars( bk_type ).length == 0 ) // FixIn: 8.5.2.26.
450 - ){ // FixIn: 8.4.4.5.
451 -
452 - 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 );
453 -
454 - //wpbc_do_scroll('#calendar_booking' + bk_type); // Scroll to the calendar // FixIn: 8.5.1.3.
455 - is_error_in_field = true; // Error
456 - }
457 - }
458 -
459 - // Check only visible elements at this step
460 - if ( jQuery( el ).is( ':visible' ) ){
461 -// console.log( '|id, type, val, visible|::', jQuery( el ).attr( 'name' ), '|' + jQuery( el ).attr( 'type' ) + '|', jQuery( el ).val(), jQuery( el ).is( ':visible' ) );
462 -
463 - // Is Required
464 - if ( jQuery( el ).hasClass( 'wpdev-validates-as-required' ) ){
465 -
466 - // Checkboxes
467 - if ( 'checkbox' == jQuery( el ).attr( 'type' ) ){
468 -
469 - if (
470 - ( ! jQuery( el ).is( ':checked' ))
471 - && ( ! jQuery( ':checkbox[name="' + el.name + '"]', my_form ).is( ":checked" ) ) // FixIn: 8.5.2.12.
472 - ){
473 - var checkbox_parent_element;
474 -
475 - if ( jQuery( el ).parents( '.wpdev-form-control-wrap' ).length > 0 ){
476 -
477 - checkbox_parent_element = jQuery( el ).parents( '.wpdev-form-control-wrap' );
478 -
479 - } else if ( jQuery( el ).parents( '.controls' ).length > 0 ){
480 -
481 - checkbox_parent_element = jQuery( el ).parents( '.controls' );
482 -
483 - } else {
484 -
485 - checkbox_parent_element = jQuery( el );
486 - }
487 - var notice_message_id = wpbc_front_end__show_message__warning( checkbox_parent_element, _wpbc.get_message( 'message_check_required_for_check_box' ) );
488 -
489 - fields_with_errors_arr.push( el );
490 - is_error_in_field = true; // Error
491 - }
492 -
493 - // Radio boxes
494 - } else if ( 'radio' == jQuery( el ).attr( 'type' ) ){
495 -
496 - if ( !jQuery( ':radio[name="' + jQuery( el ).attr( 'name' ) + '"]', my_form ).is( ':checked' ) ){
497 - 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' ) );
498 - fields_with_errors_arr.push( el );
499 - is_error_in_field = true; // Error
500 - }
501 -
502 - // Other elements
503 - } else {
504 -
505 - var inp_value = jQuery( el ).val();
506 -
507 - if ( '' === wpbc_trim( inp_value ) ){ //FixIn: 8.8.1.3 // FixIn: 8.7.11.12.
508 -
509 - var notice_message_id = wpbc_front_end__show_message__warning( el, _wpbc.get_message( 'message_check_required' ) );
510 -
511 - fields_with_errors_arr.push( el );
512 - is_error_in_field = true; // Error
513 - }
514 - }
515 - }
516 -
517 - // Validate Email
518 - if ( jQuery( el ).hasClass( 'wpdev-validates-as-email' ) ){
519 - var inp_value = jQuery( el ).val();
520 - inp_value = inp_value.replace( /^\s+|\s+$/gm, '' ); // Trim white space //FixIn: 5.4.5
521 - var reg = /^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,})$/;
522 - if ( (inp_value != '') && (reg.test( inp_value ) == false) ){
523 -
524 - var notice_message_id = wpbc_front_end__show_message__warning( el, _wpbc.get_message( 'message_check_email' ) );
525 - fields_with_errors_arr.push( el );
526 - is_error_in_field = true; // Error
527 - }
528 - }
529 -
530 - // Validate For digit entering - for example for - Phone
531 - // <p>Digit Field:<br />[text* dig_field class:validate_as_digit] </p>
532 - // <p>Phone:<br />[text* phone class:validate_digit_8] </p>
533 -
534 - var classList = jQuery( el ).attr( 'class' );
535 -
536 - if ( classList ){
537 -
538 - classList = classList.split( /\s+/ );
539 -
540 - jQuery.each( classList, function ( cl_index, cl_item ){
541 -
542 - ////////////////////////////////////////////////////////////////////////////////////////////
543 -
544 - // Validate field value as "Date" [CSS class - 'validate_as_digit']
545 - if ( 'validate_as_date' === cl_item ) {
546 -
547 - // 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
548 - var regex = new RegExp( '^[0-3]?\\d{1}[\\/\\.\\-]+[0-3]?\\d{1}[\\/\\.\\-]+[0-2]+\\d{3}$' ); // Check for Date 09/25/2018
549 - var message_verif_phone = 'This field must be valid date like this ' + '09/25/2018';
550 - var inp_value = jQuery( el ).val();
551 -
552 - if ( ( inp_value != '' ) && ( regex.test( inp_value ) == false ) ){
553 - wpbc_front_end__show_message__warning( el, message_verif_phone );
554 - fields_with_errors_arr.push( el );
555 - is_error_in_field = true; // Error
556 - }
557 - }
558 -
559 - ////////////////////////////////////////////////////////////////////////////////////////////
560 -
561 - // Validate field value as "DIGIT" [CSS class - 'validate_as_digit']
562 - if ( 'validate_as_digit' === cl_item ) {
563 -
564 - var regex = new RegExp( '^[0-9]+\\.?[0-9]*$' ); // Check for digits
565 - var message_verif_phone = 'This field must contain only digits';
566 - var inp_value = jQuery( el ).val();
567 -
568 - if ( ( inp_value != '' ) && ( regex.test( inp_value ) == false ) ){
569 - wpbc_front_end__show_message__warning( el, message_verif_phone );
570 - fields_with_errors_arr.push( el );
571 - is_error_in_field = true; // Error
572 - }
573 - }
574 -
575 - ////////////////////////////////////////////////////////////////////////////////////////////
576 -
577 - // Validate field value as "Phone" number or any other valid number wth specific number of digits [CSS class - 'validate_digit_8' || 'validate_digit_10' ]
578 - var is_validate_digit = cl_item.substring( 0, 15 );
579 -
580 - // Check if class start with 'validate_digit_'
581 - if ( 'validate_digit_' === is_validate_digit ){
582 -
583 - // Get number of digit in class: validate_digit_8 => 8 or validate_digit_10 => 10
584 - var digits_to_check = parseInt( cl_item.substring( 15 ) );
585 -
586 - // Check about any errors in
587 - if ( !isNaN( digits_to_check ) ){
588 -
589 - var regex = new RegExp( '^\\d{' + digits_to_check + '}$' ); // We was valid it as parseInt - only integer variable - digits_to_check
590 - var message_verif_phone = 'This field must contain ' + digits_to_check + ' digits';
591 - var inp_value = jQuery( el ).val();
592 -
593 - if ( ( inp_value != '' ) && ( regex.test( inp_value ) == false ) ){
594 - wpbc_front_end__show_message__warning( el, message_verif_phone );
595 - fields_with_errors_arr.push( el );
596 - is_error_in_field = true; // Error
597 - }
598 - }
599 - }
600 -
601 - ////////////////////////////////////////////////////////////////////////////////////////////
602 -
603 - });
604 - }
605 - }
606 - }
607 - } );
608 -
609 - if ( fields_with_errors_arr.length > 0 ){
610 - jQuery( fields_with_errors_arr[ 0 ] ).trigger( 'focus' ); // FixIn: 9.3.1.9.
611 - }
612 - }
613 -
614 - return is_error_in_field;
615 -}
616 -
617 -
618 -// FixIn: 8.6.1.15.
619 -/**
620 262 * Go to next specific step in Wizard style booking form, with
621 263 * check all required elements specific step, otherwise show warning message!
622 264 *
623 265 * @param el
@@ -624,8 +266,9 @@
624 266 * @param step_num
625 267 * @returns {boolean}
626 268 */
627 269 function wpbc_wizard_step(el, step_num, step_from) {
270 +
628 271 var br_id = jQuery( el ).closest( 'form' ).find( 'input[name^="bk_type"]' ).val();
629 272
630 273 // FixIn: 8.8.1.5.
631 274 if ( (undefined == step_from) || (step_num > step_from) ) {
@@ -643,9 +286,10 @@
643 286 }
644 287 }
645 288
646 289 if ( br_id != undefined ) {
647 - jQuery( "#booking_form" + br_id + " .wpbc_wizard_step" ).css( { "display": "none" } ).removeClass( 'wpbc_wizard_step_hidden' );
290 + jQuery( "#booking_form" + br_id + " .wpbc_wizard_step" ).css( { "display": "none" } )
291 + .removeClass( 'wpbc_wizard_step_hidden' );
648 292 jQuery( "#booking_form" + br_id + " .wpbc_wizard_step" + step_num ).css( { "display": "block" } );
649 293 return jQuery( "#booking_form" + br_id + " .wpbc_wizard_step" + step_num );
650 294 }
651 295 }
@@ -663,10 +307,10 @@
663 307 href: 'javascript:void(0)',
664 308 }
665 309 );
666 310
667 - jQuery( '.wpbc_wizard_step_button' ).on(
668 - 'click',
311 + jQuery( '.wpbc_wizard_step_button' ).off( 'click.wpbc_booking_form_wizard' ).on(
312 + 'click.wpbc_booking_form_wizard',
669 313 function (event) {
670 314 var found_steps_arr = jQuery( this ).attr( 'class' ).match( /wpbc\_wizard\_step\_([\d]+)([\s'"]+|$)/ );
671 315
672 316 if ( (null !== found_steps_arr) && (found_steps_arr.length > 2) ) {
@@ -690,57 +334,63 @@
690 334 }
691 335 );
692 336 }
693 337
694 -// FixIn: 10.1.3.2.
695 -jQuery( document ).ready( function (){
696 - wpbc_hook__init_booking_form_wizard_buttons();
697 -} );
698 338
699 -
700 -// FixIn: 8.6.1.15.
701 339 /**
702 340 * Check if at least one element from array of elements names in booking form visible or not.
703 - * Usage Example: if ( wpbc_is_some_elements_visible( br_id, ['rangetime', 'durationtime', 'starttime', 'endtime'] ) ){ ... }
341 + * Usage Example: if ( wpbc_is_some_elements_visible( br_id, ['rangetime', 'durationtime', 'starttime', 'endtime'] )
342 + * ){ ... }
704 343 *
705 - * @param bk_type
344 + * @param resource_id
706 345 * @param elements_names
707 346 * @returns {boolean}
708 347 */
709 -function wpbc_is_some_elements_visible( bk_type, elements_names ){
348 +function wpbc_is_some_elements_visible(resource_id, elements_names) {
710 349
711 - var is_some_elements_visible = false;
350 + var my_form = jQuery( '#booking_form' + resource_id );
712 351
713 - var my_form = jQuery( '#booking_form' + bk_type );
352 + if ( ! my_form.length ) {
353 + return false;
354 + }
714 355
715 - if ( my_form.length ){
356 + var is_some_elements_visible = false;
357 + // Pseudo-selector that get form elements <input , <textarea , <select, <button...
358 + my_form.find( ':input' ).each(
359 + function (index, el) {
716 360
717 - // Pseudo-selector that get form elements <input , <textarea , <select, <button...
718 - my_form.find( ':input' ).each( function ( index, el ){
361 + // Skip some elements.
362 + var skip_elements = [ 'hidden', 'button' ];
719 363
720 - // Skip some elements
721 - var skip_elements = ['hidden', 'button'];
364 + if ( -1 == skip_elements.indexOf( jQuery( el ).attr( 'type' ) ) ) {
722 365
723 - if ( -1 == skip_elements.indexOf( jQuery( el ).attr( 'type' ) ) ){
366 + for ( var ei = 0; ei < (elements_names.length - 1); ei++ ) {
724 367
725 - for ( var ei = 0; ei < ( elements_names.length - 1) ; ei++ ){
368 + // Check Calendar Dates Selection.
369 + if ( (elements_names[ei] + resource_id) == jQuery( el ).attr( 'name' ) ) {
726 370
727 - // Check Calendar Dates Selection
728 - if ( (elements_names[ ei ] + bk_type) == jQuery( el ).attr( 'name' ) ){
371 + if ( jQuery( el ).is( ':visible' ) ) {
372 + is_some_elements_visible = true;
373 + }
374 + }
375 + }
376 + }
377 + }
378 + );
729 379
730 - if ( jQuery( el ).is( ':visible' ) ){
731 - is_some_elements_visible = true;
732 - }
733 - }
734 - }
735 - }
736 - } );
737 - }
738 - return is_some_elements_visible;
380 + return is_some_elements_visible;
739 381 }
740 382
741 -// == Days Selections - support functions ==============================================================================
742 383
384 +jQuery( document ).ready(
385 + function () {
386 + wpbc_hook__init_booking_form_wizard_buttons();
387 + }
388 +);
389 +
390 +
391 +// == DAYS_SELECTIONS ==================================================================================================
392 +
743 393 /**
744 394 * Get first day of selection
745 395 *
746 396 * @param dates
@@ -777,9 +427,15 @@
777 427 // Single day selection
778 428 return dates; //20.12.2013
779 429 }
780 430
781 -// Get last day of selection
431 +
432 +/**
433 + * Get last day of selection.
434 + *
435 + * @param dates
436 + * @returns {*|string}
437 + */
782 438 function get_last_day_of_selection(dates) {
783 439
784 440 // Multiple days selections
785 441 if ( dates.indexOf(',') != -1 ){
@@ -827,10 +483,8 @@
827 483
828 484 var id_additional_str = document.getElementById( 'additional_calendars' + bk_type ).value;
829 485 var id_additional_arr = id_additional_str.split( ',' );
830 486
831 - var is_all_additional_days_unselected = true;
832 -
833 487 for ( var ia = 0; ia < id_additional_arr.length; ia++ ){
834 488 if ( document.getElementById( 'date_booking' + id_additional_arr[ ia ] ).value != '' ){
835 489 selected_additionl_calendars.push( id_additional_arr[ ia ] );
836 490 }
@@ -837,4 +491,46 @@
837 491 }
838 492 }
839 493 return selected_additionl_calendars;
840 494 }
495 +
496 +
497 +// == ELEMENTOR Ready Widget Update ====================================================================================
498 +
499 +jQuery( function ($) {
500 + // FixIn: 10.14.15.1.
501 + if ( (window.elementorFrontend) && ('undefined' !== typeof (elementorFrontend.hooks)) ) {
502 +
503 + elementorFrontend.hooks.addAction( 'frontend/element_ready/wpbc_widget_booking_form_1.default', function ($scope) {
504 + // Simulate DOM ready, after updating Elementor Widget.
505 + jQuery( document ).trigger( 'wpbc_elementor_ready' );
506 + } );
507 +
508 + // Catch all widget re-renders.
509 + // elementorFrontend.hooks.addAction( 'frontend/element_ready/global', function ($scope) {
510 + // console.log( 'Some widget was re-rendered:', $scope );
511 + // } );
512 + }
513 +} );
514 +
515 +// Elementor widget reinit. So we need to reinit all "jQuery( document ).ready( ...) " again with custom 'wpbc_elementor_ready' event.
516 +jQuery( document ).on(
517 + 'wpbc_elementor_ready',
518 + function () {
519 +
520 + wpbc_hook__init_booking_form_wizard_buttons();
521 +
522 + if ( 'function' === typeof (wpbc_hook__init_timeselector) ) {
523 + wpbc_hook__init_timeselector();
524 + }
525 +
526 + if ( 'function' === typeof (wpbc_update_capacity_hint) ) {
527 + jQuery( '.booking_form_div' ).on(
528 + 'wpbc_booking_date_or_option_selected',
529 + function (event, resource_id) {
530 + wpbc_update_capacity_hint( resource_id );
531 + }
532 + );
533 + }
534 +
535 + }
536 +);