PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 4.11.02
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v4.11.02
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / js / formidable.js

formidable.js in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 4.11.02, at js/formidable.js

1,440 lines 40.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* exported frmRecaptcha, frmAfterRecaptcha, frmUpdateField, frmDeleteEntry, frmOnSubmit, frm_resend_email */
2
3 var frmFrontForm;
4
5 function frmFrontFormJS() {
6 'use strict';
7
8 /*global jQuery:false, frm_js, grecaptcha, frmProForm, tinyMCE */
9 /*global frmThemeOverride_jsErrors, frmThemeOverride_frmPlaceError, frmThemeOverride_frmAfterSubmit */
10
11 var action = '';
12 var jsErrors = [];
13
14 function maybeShowLabel() {
15 /*jshint validthis:true */
16 var $field = jQuery( this ),
17 $label = $field.closest( '.frm_inside_container' ).find( '.frm_primary_label' ),
18 val = $field.val();
19
20 if ( val !== null && val.length > 0 ) {
21 $label.addClass( 'frm_visible' );
22 } else {
23 $label.removeClass( 'frm_visible' );
24 }
25 }
26
27 /* Get the ID of the field that changed*/
28 function getFieldId( field, fullID ) {
29 var nameParts, fieldId,
30 isRepeating = false,
31 fieldName = '';
32 if ( field instanceof jQuery ) {
33 fieldName = field.attr( 'name' );
34 } else {
35 fieldName = field.name;
36 }
37
38 if ( typeof fieldName === 'undefined' ) {
39 fieldName = '';
40 }
41
42 if ( fieldName === '' ) {
43 if ( field instanceof jQuery ) {
44 fieldName = field.data( 'name' );
45 } else {
46 fieldName = field.getAttribute( 'data-name' );
47 }
48
49 if ( typeof fieldName === 'undefined' ) {
50 fieldName = '';
51 }
52
53 if ( fieldName !== '' && fieldName ) {
54 return fieldName;
55 }
56 return 0;
57 }
58
59 nameParts = fieldName.replace( 'item_meta[', '' ).replace( '[]', '' ).split( ']' );
60 //TODO: Fix this for checkboxes and address fields
61 if ( nameParts.length < 1 ) {
62 return 0;
63 }
64 nameParts = nameParts.filter( function( n ) {
65 return n !== '';
66 });
67
68 fieldId = nameParts[0];
69
70 if ( nameParts.length === 1 ) {
71 return fieldId;
72 }
73
74 if ( nameParts[1] === '[form' || nameParts[1] === '[row_ids' ) {
75 return 0;
76 }
77
78 // Check if 'this' is in a repeating section
79 if ( jQuery( 'input[name="item_meta[' + fieldId + '][form]"]' ).length ) {
80
81 // this is a repeatable section with name: item_meta[repeating-section-id][row-id][field-id]
82 fieldId = nameParts[2].replace( '[', '' );
83 isRepeating = true;
84 }
85
86 // Check if 'this' is an other text field and get field ID for it
87 if ( 'other' === fieldId ) {
88 if ( isRepeating ) {
89 // name for other fields: item_meta[370][0][other][414]
90 fieldId = nameParts[3].replace( '[', '' );
91 } else {
92 // Other field name: item_meta[other][370]
93 fieldId = nameParts[1].replace( '[', '' );
94 }
95 }
96
97 if ( fullID === true ) {
98 // For use in the container div id
99 if ( fieldId === nameParts[0]) {
100 fieldId = fieldId + '-' + nameParts[1].replace( '[', '' );
101 } else {
102 fieldId = fieldId + '-' + nameParts[0] + '-' + nameParts[1].replace( '[', '' );
103 }
104 }
105
106 return fieldId;
107 }
108
109 /**
110 * Disable the submit button for a given jQuery form object
111 *
112 * @since 2.03.02
113 *
114 * @param {object} $form
115 */
116 function disableSubmitButton( $form ) {
117 $form.find( 'input[type="submit"], input[type="button"], button[type="submit"]' ).attr( 'disabled', 'disabled' );
118 }
119
120 /**
121 * Enable the submit button for a given jQuery form object
122 *
123 * @since 2.03.02
124 *
125 * @param {object} $form
126 */
127 function enableSubmitButton( $form ) {
128 $form.find( 'input[type="submit"], input[type="button"], button[type="submit"]' ).prop( 'disabled', false );
129 }
130
131 /**
132 * Disable the save draft link for a given jQuery form object
133 *
134 * @since 4.04.03
135 *
136 * @param {object} $form
137 */
138 function disableSaveDraft( $form ) {
139 $form.find( 'a.frm_save_draft' ).css( 'pointer-events', 'none' );
140 }
141
142 /**
143 * Enable the save draft link for a given jQuery form object
144 *
145 * @since 4.04.03
146 *
147 * @param {object} $form
148 */
149 function enableSaveDraft( $form ) {
150 $form.find( 'a.frm_save_draft' ).css( 'pointer-events', '' );
151 }
152
153 function validateForm( object ) {
154 var r, rl, n, nl, fields, field, value, requiredFields,
155 errors = [];
156
157 // Make sure required text field is filled in
158 requiredFields = jQuery( object ).find(
159 '.frm_required_field:visible input, .frm_required_field:visible select, .frm_required_field:visible textarea'
160 ).filter( ':not(.frm_optional)' );
161 if ( requiredFields.length ) {
162 for ( r = 0, rl = requiredFields.length; r < rl; r++ ) {
163 errors = checkRequiredField( requiredFields[r], errors );
164 }
165 }
166
167 fields = jQuery( object ).find( 'input,select,textarea' );
168 if ( fields.length ) {
169 for ( n = 0, nl = fields.length; n < nl; n++ ) {
170 field = fields[n];
171 value = field.value;
172 if ( value !== '' ) {
173 if ( field.type === 'hidden' ) {
174 // don't validate
175 } else if ( field.type === 'number' ) {
176 errors = checkNumberField( field, errors );
177 } else if ( field.type === 'email' ) {
178 errors = checkEmailField( field, errors );
179 } else if ( field.type === 'password' ) {
180 errors = checkPasswordField( field, errors );
181 } else if ( field.type === 'url' ) {
182 errors = checkUrlField( field, errors );
183 } else if ( field.pattern !== null ) {
184 errors = checkPatternField( field, errors );
185 }
186 }
187 }
188 }
189
190 errors = validateRecaptcha( object, errors );
191
192 return errors;
193 }
194
195 function maybeValidateChange( fieldId, field ) {
196 if ( field.type === 'url' ) {
197 maybeAddHttpToUrl( field );
198 }
199 if ( jQuery( field ).closest( 'form' ).hasClass( 'frm_js_validate' ) ) {
200 validateField( fieldId, field );
201 }
202 }
203
204 function maybeAddHttpToUrl( field ) {
205 var url = field.value;
206 var matches = url.match( /^(https?|ftps?|mailto|news|feed|telnet):/ );
207 if ( field.value !== '' && matches === null ) {
208 field.value = 'http://' + url;
209 }
210 }
211
212 function validateField( fieldId, field ) {
213 var key,
214 errors = [];
215
216 var $fieldCont = jQuery( field ).closest( '.frm_form_field' );
217 if ( $fieldCont.hasClass( 'frm_required_field' ) && ! jQuery( field ).hasClass( 'frm_optional' ) ) {
218 errors = checkRequiredField( field, errors );
219 }
220
221 if ( errors.length < 1 ) {
222 if ( field.type === 'email' ) {
223 errors = checkEmailField( field, errors );
224 } else if ( field.type === 'password' ) {
225 errors = checkPasswordField( field, errors );
226 } else if ( field.type === 'number' ) {
227 errors = checkNumberField( field, errors );
228 } else if ( field.type === 'url' ) {
229 errors = checkUrlField( field, errors );
230 } else if ( field.pattern !== null ) {
231 errors = checkPatternField( field, errors );
232 }
233 }
234
235 removeFieldError( $fieldCont );
236 if ( Object.keys( errors ).length > 0 ) {
237 for ( key in errors ) {
238 addFieldError( $fieldCont, key, errors );
239 }
240 }
241 }
242
243 function checkRequiredField( field, errors ) {
244 var checkGroup, fieldClasses, tempVal, i, placeholder,
245 val = '',
246 fieldID = '',
247 fileID = field.getAttribute( 'data-frmfile' );
248
249 if ( field.type === 'hidden' && fileID === null ) {
250 return errors;
251 }
252
253 if ( field.type === 'checkbox' || field.type === 'radio' ) {
254 checkGroup = jQuery( 'input[name="' + field.name + '"]' ).closest( '.frm_required_field' ).find( 'input:checked' );
255 jQuery( checkGroup ).each( function() {
256 val = this.value;
257 });
258 } else if ( field.type === 'file' || fileID ) {
259 if ( typeof fileID === 'undefined' ) {
260 fileID = getFieldId( field, true );
261 fileID = fileID.replace( 'file', '' );
262 }
263
264 if ( typeof errors[ fileID ] === 'undefined' ) {
265 val = getFileVals( fileID );
266 }
267 fieldID = fileID;
268 } else {
269 fieldClasses = field.className;
270 if ( fieldClasses.indexOf( 'frm_pos_none' ) !== -1 ) {
271 // skip hidden other fields
272 return errors;
273 }
274
275 val = jQuery( field ).val();
276 if ( val === null ) {
277 val = '';
278 } else if ( typeof val !== 'string' ) {
279 tempVal = val;
280 val = '';
281 for ( i = 0; i < tempVal.length; i++ ) {
282 if ( tempVal[i] !== '' ) {
283 val = tempVal[i];
284 }
285 }
286 }
287
288 if ( fieldClasses.indexOf( 'frm_other_input' ) === -1 ) {
289 fieldID = getFieldId( field, true );
290 } else {
291 fieldID = getFieldId( field, false );
292 }
293
294 if ( fieldClasses.indexOf( 'frm_time_select' ) !== -1 ) {
295 // set id for time field
296 fieldID = fieldID.replace( '-H', '' ).replace( '-m', '' );
297 }
298
299 placeholder = field.getAttribute( 'data-frmplaceholder' );
300 if ( placeholder !== null && val === placeholder ) {
301 val = '';
302 }
303 }
304
305 if ( val === '' ) {
306 if ( fieldID === '' ) {
307 fieldID = getFieldId( field, true );
308 }
309 if ( ! ( fieldID in errors ) ) {
310 errors[ fieldID ] = getFieldValidationMessage( field, 'data-reqmsg' );
311 }
312 }
313
314 return errors;
315 }
316
317 function getFileVals( fileID ) {
318 var val = '',
319 fileFields = jQuery( 'input[name="file' + fileID + '"], input[name="file' + fileID + '[]"], input[name^="item_meta[' + fileID + ']"]' );
320
321 fileFields.each( function() {
322 if ( val === '' ) {
323 val = this.value;
324 }
325 });
326 return val;
327 }
328
329 function checkUrlField( field, errors ) {
330 var fieldID,
331 url = field.value;
332
333 if ( url !== '' && ! /^http(s)?:\/\/(?:localhost|(?:[\da-z\.-]+\.[\da-z\.-]+))/i.test( url ) ) {
334 fieldID = getFieldId( field, true );
335 if ( ! ( fieldID in errors ) ) {
336 errors[ fieldID ] = getFieldValidationMessage( field, 'data-invmsg' );
337 }
338 }
339 return errors;
340 }
341
342 function checkEmailField( field, errors ) {
343 var fieldID = getFieldId( field, true ),
344 pattern = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i;
345
346 // validate the current field we're editing first
347 if ( '' !== field.value && pattern.test( field.value ) === false ) {
348 errors[ fieldID ] = getFieldValidationMessage( field, 'data-invmsg' );
349 }
350
351 confirmField( field, errors );
352 return errors;
353 }
354
355 function checkPasswordField( field, errors ) {
356 confirmField( field, errors );
357 return errors;
358 }
359
360 function confirmField( field, errors ) {
361 var value, confirmValue, firstField,
362 fieldID = getFieldId( field, true ),
363 strippedId = field.id.replace( 'conf_', '' ),
364 strippedFieldID = fieldID.replace( 'conf_', '' ),
365 confirmField = document.getElementById( strippedId.replace( 'field_', 'field_conf_' ) );
366
367 if ( confirmField === null || typeof errors[ 'conf_' + strippedFieldID ] !== 'undefined' ) {
368 return;
369 }
370
371 if ( fieldID !== strippedFieldID ) {
372 firstField = document.getElementById( strippedId );
373 value = firstField.value;
374 confirmValue = confirmField.value;
375 if ( '' !== value && '' !== confirmValue && value !== confirmValue ) {
376 errors[ 'conf_' + strippedFieldID ] = getFieldValidationMessage( confirmField, 'data-confmsg' );
377 }
378 } else {
379 validateField( 'conf_' + strippedFieldID, confirmField );
380 }
381 }
382
383 function checkNumberField( field, errors ) {
384 var fieldID,
385 number = field.value;
386
387 if ( number !== '' && isNaN( number / 1 ) !== false ) {
388 fieldID = getFieldId( field, true );
389 if ( ! ( fieldID in errors ) ) {
390 errors[ fieldID ] = getFieldValidationMessage( field, 'data-invmsg' );
391 }
392 }
393 return errors;
394 }
395
396 function checkPatternField( field, errors ) {
397 var fieldID,
398 text = field.value,
399 format = getFieldValidationMessage( field, 'pattern' );
400
401 if ( format !== '' && text !== '' ) {
402 fieldID = getFieldId( field, true );
403 if ( ! ( fieldID in errors ) ) {
404 format = new RegExp( '^' + format + '$', 'i' );
405 if ( format.test( text ) === false ) {
406 errors[ fieldID ] = getFieldValidationMessage( field, 'data-invmsg' );
407 }
408 }
409 }
410 return errors;
411 }
412
413 function hasInvisibleRecaptcha( object ) {
414 var recaptcha, recaptchaID, alreadyChecked;
415
416 if ( isGoingToPrevPage( object ) ) {
417 return false;
418 }
419
420 recaptcha = jQuery( object ).find( '.frm-g-recaptcha[data-size="invisible"], .g-recaptcha[data-size="invisible"]' );
421 if ( recaptcha.length ) {
422 recaptchaID = recaptcha.data( 'rid' );
423 alreadyChecked = grecaptcha.getResponse( recaptchaID );
424 if ( alreadyChecked.length === 0 ) {
425 return recaptcha;
426 } else {
427 return false;
428 }
429 } else {
430 return false;
431 }
432 }
433
434 function executeInvisibleRecaptcha( invisibleRecaptcha ) {
435 var recaptchaID = invisibleRecaptcha.data( 'rid' );
436 grecaptcha.reset( recaptchaID );
437 grecaptcha.execute( recaptchaID );
438 }
439
440 function validateRecaptcha( form, errors ) {
441 var recaptchaID, response, fieldContainer, fieldID,
442 $recaptcha = jQuery( form ).find( '.frm-g-recaptcha' );
443 if ( $recaptcha.length ) {
444 recaptchaID = $recaptcha.data( 'rid' );
445
446 try {
447 response = grecaptcha.getResponse( recaptchaID );
448 } catch ( e ) {
449 if ( jQuery( form ).find( 'input[name="recaptcha_checked"]' ).length ) {
450 return errors;
451 } else {
452 response = '';
453 }
454 }
455
456 if ( response.length === 0 ) {
457 fieldContainer = $recaptcha.closest( '.frm_form_field' );
458 fieldID = fieldContainer.attr( 'id' ).replace( 'frm_field_', '' ).replace( '_container', '' );
459 errors[ fieldID ] = '';
460 }
461 }
462 return errors;
463 }
464
465 function getFieldValidationMessage( field, messageType ) {
466 var msg = field.getAttribute( messageType );
467 if ( msg === null ) {
468 msg = '';
469 }
470 return msg;
471 }
472
473 function shouldJSValidate( object ) {
474 var validate = jQuery( object ).hasClass( 'frm_js_validate' );
475 if ( validate && typeof frmProForm !== 'undefined' && ( frmProForm.savingDraft( object ) || frmProForm.goingToPreviousPage( object ) ) ) {
476 validate = false;
477 }
478
479 return validate;
480 }
481
482 function getFormErrors( object, action ) {
483 var fieldset;
484
485 if ( typeof action === 'undefined' ) {
486 jQuery( object ).find( 'input[name="frm_action"]' ).val();
487 }
488
489 fieldset = jQuery( object ).find( '.frm_form_field' );
490 fieldset.addClass( 'frm_doing_ajax' );
491 jQuery.ajax({
492 type: 'POST', url: frm_js.ajax_url,
493 data: jQuery( object ).serialize() + '&action=frm_entries_' + action + '&nonce=' + frm_js.nonce,
494 success: function( response ) {
495 var formID, replaceContent, pageOrder, formReturned, contSubmit, delay,
496 $fieldCont, key, inCollapsedSection, frmTrigger,
497 defaultResponse = { 'content': '', 'errors': {}, 'pass': false };
498 if ( response === null ) {
499 response = defaultResponse;
500 }
501
502 response = response.replace( /^\s+|\s+$/g, '' );
503 if ( response.indexOf( '{' ) === 0 ) {
504 response = JSON.parse( response );
505 } else {
506 response = defaultResponse;
507 }
508
509 if ( typeof response.redirect !== 'undefined' ) {
510 jQuery( document ).trigger( 'frmBeforeFormRedirect', [ object, response ]);
511 window.location = response.redirect;
512 } else if ( response.content !== '' ) {
513 // the form or success message was returned
514
515 removeSubmitLoading( jQuery( object ) );
516 if ( frm_js.offset != -1 ) {
517 frmFrontForm.scrollMsg( jQuery( object ), false );
518 }
519 formID = jQuery( object ).find( 'input[name="form_id"]' ).val();
520 response.content = response.content.replace( / frm_pro_form /g, ' frm_pro_form frm_no_hide ' );
521 replaceContent = jQuery( object ).closest( '.frm_forms' );
522 removeAddedScripts( replaceContent, formID );
523 delay = maybeSlideOut( replaceContent, response.content );
524
525 setTimeout(
526 function() {
527 var container, input, previousInput;
528
529 replaceContent.replaceWith( response.content );
530
531 addUrlParam( response );
532
533 if ( typeof frmThemeOverride_frmAfterSubmit === 'function' ) { // eslint-disable-line camelcase
534 pageOrder = jQuery( 'input[name="frm_page_order_' + formID + '"]' ).val();
535 formReturned = jQuery( response.content ).find( 'input[name="form_id"]' ).val();
536 frmThemeOverride_frmAfterSubmit( formReturned, pageOrder, response.content, object );
537 }
538
539 if ( typeof response.recaptcha !== 'undefined' ) {
540 container = jQuery( '#frm_form_' + formID + '_container' ).find( '.frm_fields_container' );
541 input = '<input type="hidden" name="recaptcha_checked" value="' + response.recaptcha + '">';
542 previousInput = container.find( 'input[name="recaptcha_checked"]' );
543
544 if ( previousInput.length ) {
545 previousInput.replaceWith( input );
546 } else {
547 container.append( input );
548 }
549 }
550
551 afterFormSubmitted( object, response );
552 },
553 delay
554 );
555 } else if ( Object.keys( response.errors ).length ) {
556 // errors were returned
557
558 removeSubmitLoading( jQuery( object ), 'enable' );
559
560 //show errors
561 contSubmit = true;
562 removeAllErrors();
563
564 $fieldCont = null;
565
566 for ( key in response.errors ) {
567 $fieldCont = jQuery( object ).find( '#frm_field_' + key + '_container' );
568
569 if ( $fieldCont.length ) {
570 if ( ! $fieldCont.is( ':visible' ) ) {
571 inCollapsedSection = $fieldCont.closest( '.frm_toggle_container' );
572 if ( inCollapsedSection.length ) {
573 frmTrigger = inCollapsedSection.prev();
574 if ( ! frmTrigger.hasClass( 'frm_trigger' ) ) {
575 // If the frmTrigger object is the section description, check to see if the previous element is the trigger
576 frmTrigger = frmTrigger.prev( '.frm_trigger' );
577 }
578 frmTrigger.trigger( 'click' );
579 }
580 }
581
582 if ( $fieldCont.is( ':visible' ) ) {
583 addFieldError( $fieldCont, key, response.errors );
584 contSubmit = false;
585 }
586 }
587 }
588
589 jQuery( object ).find( '.frm-g-recaptcha, .g-recaptcha' ).each( function() {
590 var $recaptcha = jQuery( this ),
591 recaptchaID = $recaptcha.data( 'rid' );
592
593 if ( typeof grecaptcha !== 'undefined' && grecaptcha ) {
594 if ( recaptchaID ) {
595 grecaptcha.reset( recaptchaID );
596 } else {
597 grecaptcha.reset();
598 }
599 }
600 });
601
602 jQuery( document ).trigger( 'frmFormErrors', [ object, response ]);
603
604 fieldset.removeClass( 'frm_doing_ajax' );
605 scrollToFirstField( object );
606
607 if ( contSubmit ) {
608 object.submit();
609 } else {
610 jQuery( object ).prepend( response.error_message );
611 }
612 } else {
613 // there may have been a plugin conflict, or the form is not set to submit with ajax
614
615 showFileLoading( object );
616
617 object.submit();
618 }
619 },
620 error: function() {
621 jQuery( object ).find( 'input[type="submit"], input[type="button"]' ).prop( 'disabled', false );
622 object.submit();
623 }
624 });
625 }
626
627 function afterFormSubmitted( object, response ) {
628 var formCompleted = jQuery( response.content ).find( '.frm_message' );
629 if ( formCompleted.length ) {
630 jQuery( document ).trigger( 'frmFormComplete', [ object, response ]);
631 } else {
632 jQuery( document ).trigger( 'frmPageChanged', [ object, response ]);
633 }
634 }
635
636 function removeAddedScripts( formContainer, formID ) {
637 var endReplace = jQuery( '.frm_end_ajax_' + formID );
638 if ( endReplace.length ) {
639 formContainer.nextUntil( '.frm_end_ajax_' + formID ).remove();
640 endReplace.remove();
641 }
642 }
643
644 function maybeSlideOut( oldContent, newContent ) {
645 var c,
646 newClass = 'frm_slideout';
647 if ( newContent.indexOf( ' frm_slide' ) !== -1 ) {
648 c = oldContent.children();
649 if ( newContent.indexOf( ' frm_going_back' ) !== -1 ) {
650 newClass += ' frm_going_back';
651 }
652 c.removeClass( 'frm_going_back' );
653 c.addClass( newClass );
654 return 300;
655 }
656 return 0;
657 }
658
659 function addUrlParam( response ) {
660 var url;
661 if ( history.pushState && typeof response.page !== 'undefined' ) {
662 url = addQueryVar( 'frm_page', response.page );
663 window.history.pushState({ 'html': response.html }, '', '?' + url );
664 }
665 }
666
667 function addQueryVar( key, value ) {
668 var kvp, i, x;
669
670 key = encodeURI( key );
671 value = encodeURI( value );
672
673 kvp = document.location.search.substr( 1 ).split( '&' );
674
675 i = kvp.length;
676 while ( i-- ) {
677 x = kvp[i].split( '=' );
678
679 if ( x[0] == key ) {
680 x[1] = value;
681 kvp[i] = x.join( '=' );
682 break;
683 }
684 }
685
686 if ( i < 0 ) {
687 kvp[ kvp.length ] = [ key, value ].join( '=' );
688 }
689
690 return kvp.join( '&' );
691 }
692
693 function addFieldError( $fieldCont, key, jsErrors ) {
694 var input, id, describedBy;
695 if ( $fieldCont.length && $fieldCont.is( ':visible' ) ) {
696 $fieldCont.addClass( 'frm_blank_field' );
697 input = $fieldCont.find( 'input, select, textarea' );
698 id = 'frm_error_field_' + key;
699 describedBy = input.attr( 'aria-describedby' );
700
701 if ( typeof frmThemeOverride_frmPlaceError === 'function' ) { // eslint-disable-line camelcase
702 frmThemeOverride_frmPlaceError( key, jsErrors );
703 } else {
704 $fieldCont.append( '<div class="frm_error" id="' + id + '">' + jsErrors[key] + '</div>' );
705
706 if ( typeof describedBy === 'undefined' ) {
707 describedBy = id;
708 } else if ( describedBy.indexOf( id ) === -1 ) {
709 describedBy = describedBy + ' ' + id;
710 }
711 input.attr( 'aria-describedby', describedBy );
712 }
713 input.attr( 'aria-invalid', true );
714
715 jQuery( document ).trigger( 'frmAddFieldError', [ $fieldCont, key, jsErrors ]);
716 }
717 }
718
719 function removeFieldError( $fieldCont ) {
720 var errorMessage = $fieldCont.find( '.frm_error' ),
721 errorId = errorMessage.attr( 'id' ),
722 input = $fieldCont.find( 'input, select, textarea' ),
723 describedBy = input.attr( 'aria-describedby' );
724
725 $fieldCont.removeClass( 'frm_blank_field has-error' );
726 errorMessage.remove();
727 input.attr( 'aria-invalid', false );
728
729 if ( typeof describedBy !== 'undefined' ) {
730 describedBy = describedBy.replace( errorId, '' );
731 input.attr( 'aria-describedby', describedBy );
732 }
733 }
734
735 function removeAllErrors() {
736 jQuery( '.form-field' ).removeClass( 'frm_blank_field has-error' );
737 jQuery( '.form-field .frm_error' ).replaceWith( '' );
738 jQuery( '.frm_error_style' ).remove();
739 }
740
741 function scrollToFirstField( object ) {
742 var field = jQuery( object ).find( '.frm_blank_field' ).first();
743 if ( field.length ) {
744 frmFrontForm.scrollMsg( field, object, true );
745 }
746 }
747
748 function showSubmitLoading( $object ) {
749 showLoadingIndicator( $object );
750 disableSubmitButton( $object );
751 disableSaveDraft( $object );
752 }
753
754 function showLoadingIndicator( $object ) {
755 if ( ! $object.hasClass( 'frm_loading_form' ) && ! $object.hasClass( 'frm_loading_prev' ) ) {
756 addLoadingClass( $object );
757 $object.trigger( 'frmStartFormLoading' );
758 }
759 }
760
761 function addLoadingClass( $object ) {
762 var loadingClass = isGoingToPrevPage( $object ) ? 'frm_loading_prev' : 'frm_loading_form';
763
764 $object.addClass( loadingClass );
765 }
766
767 function isGoingToPrevPage( $object ) {
768 return ( typeof frmProForm !== 'undefined' && frmProForm.goingToPreviousPage( $object ) );
769 }
770
771 function removeSubmitLoading( $object, enable, processesRunning ) {
772 var loadingForm;
773
774 if ( processesRunning > 0 ) {
775 return;
776 }
777
778 loadingForm = jQuery( '.frm_loading_form' );
779 loadingForm.removeClass( 'frm_loading_form' );
780 loadingForm.removeClass( 'frm_loading_prev' );
781
782 loadingForm.trigger( 'frmEndFormLoading' );
783
784 if ( enable === 'enable' ) {
785 enableSubmitButton( loadingForm );
786 enableSaveDraft( loadingForm );
787 }
788 }
789
790 function showFileLoading( object ) {
791 var fileval,
792 loading = document.getElementById( 'frm_loading' );
793 if ( loading !== null ) {
794 fileval = jQuery( object ).find( 'input[type=file]' ).val();
795 if ( typeof fileval !== 'undefined' && fileval !== '' ) {
796 setTimeout( function() {
797 jQuery( loading ).fadeIn( 'slow' );
798 }, 2000 );
799 }
800 }
801 }
802
803 function clearDefault() {
804 /*jshint validthis:true */
805 toggleDefault( jQuery( this ), 'clear' );
806 }
807
808 function replaceDefault() {
809 /*jshint validthis:true */
810 toggleDefault( jQuery( this ), 'replace' );
811 }
812
813 function toggleDefault( $thisField, e ) {
814 // TODO: Fix this for a default value that is a number or array
815 var thisVal,
816 v = $thisField.data( 'frmval' ).replace( /(\n|\r\n)/g, '\r' );
817 if ( v === '' || typeof v === 'undefined' ) {
818 return false;
819 }
820 thisVal = $thisField.val().replace( /(\n|\r\n)/g, '\r' );
821
822 if ( 'replace' === e ) {
823 if ( thisVal === '' ) {
824 $thisField.addClass( 'frm_default' ).val( v );
825 }
826 } else if ( thisVal == v ) {
827 $thisField.removeClass( 'frm_default' ).val( '' );
828 }
829 }
830
831 function resendEmail() {
832 /*jshint validthis:true */
833 var $link = jQuery( this ),
834 entryId = this.getAttribute( 'data-eid' ),
835 formId = this.getAttribute( 'data-fid' ),
836 label = $link.find( '.frm_link_label' );
837 if ( label.length < 1 ) {
838 label = $link;
839 }
840 label.append( '<span class="frm-wait"></span>' );
841
842 jQuery.ajax({
843 type: 'POST',
844 url: frm_js.ajax_url,
845 data: {
846 action: 'frm_entries_send_email',
847 entry_id: entryId,
848 form_id: formId,
849 nonce: frm_js.nonce
850 },
851 success: function( msg ) {
852 var admin = document.getElementById( 'wpbody' );
853 if ( admin === null ) {
854 label.html( msg );
855 } else {
856 label.html( '' );
857 $link.after( msg );
858 }
859 }
860 });
861 return false;
862 }
863
864 /**********************************************
865 * General Helpers
866 *********************************************/
867
868 function confirmClick() {
869 /*jshint validthis:true */
870 var message = jQuery( this ).data( 'frmconfirm' );
871 return confirm( message );
872 }
873
874 function toggleDiv() {
875 /*jshint validthis:true */
876 var div = jQuery( this ).data( 'frmtoggle' );
877 if ( jQuery( div ).is( ':visible' ) ) {
878 jQuery( div ).slideUp( 'fast' );
879 } else {
880 jQuery( div ).slideDown( 'fast' );
881 }
882 return false;
883 }
884
885 /**********************************************
886 * Fallback functions
887 *********************************************/
888
889 function addIndexOfFallbackForIE8() {
890 var len, from;
891
892 if ( ! Array.prototype.indexOf ) {
893 Array.prototype.indexOf = function( elt /*, from*/ ) {
894 len = this.length >>> 0;
895
896 from = Number( arguments[1]) || 0;
897 from = ( from < 0 ) ? Math.ceil( from ) : Math.floor( from );
898 if ( from < 0 ) {
899 from += len;
900 }
901
902 for ( ; from < len; from++ ) {
903 if ( from in this && this[from] === elt ) {
904 return from;
905 }
906 }
907 return -1;
908 };
909 }
910 }
911
912 function addTrimFallbackForIE8() {
913 if ( typeof String.prototype.trim !== 'function' ) {
914 String.prototype.trim = function() {
915 return this.replace( /^\s+|\s+$/g, '' );
916 };
917 }
918 }
919
920 function addFilterFallbackForIE8() {
921 var t, len, res, thisp, i, val;
922
923 if ( ! Array.prototype.filter ) {
924
925 Array.prototype.filter = function( fun /*, thisp */ ) {
926
927 if ( this === void 0 || this === null ) {
928 throw new TypeError();
929 }
930
931 t = Object( this );
932 len = t.length >>> 0;
933 if ( typeof fun !== 'function' ) {
934 throw new TypeError();
935 }
936
937 res = [];
938 thisp = arguments[1];
939 for ( i = 0; i < len; i++ ) {
940 if ( i in t ) {
941 val = t[i]; // in case fun mutates this
942 if ( fun.call( thisp, val, i, t ) ) {
943 res.push( val );
944 }
945 }
946 }
947
948 return res;
949 };
950 }
951 }
952
953 function addKeysFallbackForIE8() {
954 var keys, i;
955
956 if ( ! Object.keys ) {
957 Object.keys = function( obj ) {
958 keys = [];
959
960 for ( i in obj ) {
961 if ( obj.hasOwnProperty( i ) ) {
962 keys.push( i );
963 }
964 }
965
966 return keys;
967 };
968 }
969 }
970
971 /**
972 * Check for -webkit-box-shadow css value for input:-webkit-autofill selector.
973 * If this is a match, the User is autofilling the input on a Webkit browser.
974 * We want to delete the Honeypot field, otherwise it will get triggered as spam on autocomplete.
975 */
976 function onHoneypotFieldChange() {
977 var css = jQuery( this ).css( 'box-shadow' );
978 if ( css.match( /inset/ ) ) {
979 this.parentNode.removeChild( this );
980 }
981 }
982
983 /**
984 * Focus on the first sub field when clicking to the primary label of combo field.
985 *
986 * @since 4.10.02
987 */
988 function changeFocusWhenClickComboFieldLabel() {
989 let label;
990
991 const comboInputsContainer = document.querySelectorAll( '.frm_combo_inputs_container' );
992 comboInputsContainer.forEach( function( inputsContainer ) {
993 if ( ! inputsContainer.closest( '.frm_form_field' ) ) {
994 return;
995 }
996
997 label = inputsContainer.closest( '.frm_form_field' ).querySelector( '.frm_primary_label' );
998 if ( ! label ) {
999 return;
1000 }
1001
1002 label.addEventListener( 'click', function( e ) {
1003 inputsContainer.querySelector( '.frm_form_field:first-child input, .frm_form_field:first-child select, .frm_form_field:first-child textarea' ).focus();
1004 });
1005 });
1006 }
1007
1008 return {
1009 init: function() {
1010 jQuery( document ).off( 'submit.formidable', '.frm-show-form' );
1011 jQuery( document ).on( 'submit.formidable', '.frm-show-form', frmFrontForm.submitForm );
1012
1013 jQuery( '.frm-show-form input[onblur], .frm-show-form textarea[onblur]' ).each( function() {
1014 if ( jQuery( this ).val() === '' ) {
1015 jQuery( this ).trigger( 'blur' );
1016 }
1017 });
1018
1019 jQuery( document ).on( 'focus', '.frm_toggle_default', clearDefault );
1020 jQuery( document ).on( 'blur', '.frm_toggle_default', replaceDefault );
1021 jQuery( '.frm_toggle_default' ).trigger( 'blur' );
1022
1023 jQuery( document.getElementById( 'frm_resend_email' ) ).on( 'click', resendEmail );
1024
1025 jQuery( document ).on( 'change', '.frm-show-form input[name^="item_meta"], .frm-show-form select[name^="item_meta"], .frm-show-form textarea[name^="item_meta"]', frmFrontForm.fieldValueChanged );
1026 jQuery( document ).on( 'change keyup', '.frm-show-form .frm_inside_container input, .frm-show-form .frm_inside_container select, .frm-show-form .frm_inside_container textarea', maybeShowLabel );
1027
1028 jQuery( document ).on( 'change', '[id^=frm_email_]', onHoneypotFieldChange );
1029
1030 jQuery( document ).on( 'click', 'a[data-frmconfirm]', confirmClick );
1031 jQuery( 'a[data-frmtoggle]' ).on( 'click', toggleDiv );
1032
1033 // Focus on the first sub field when clicking to the primary label of combo field.
1034 changeFocusWhenClickComboFieldLabel();
1035
1036 // Add fallbacks for the beloved IE8
1037 addIndexOfFallbackForIE8();
1038 addTrimFallbackForIE8();
1039 addFilterFallbackForIE8();
1040 addKeysFallbackForIE8();
1041 },
1042
1043 getFieldId: function( field, fullID ) {
1044 return getFieldId( field, fullID );
1045 },
1046
1047 renderRecaptcha: function( captcha ) {
1048 var formID, recaptchaID,
1049 size = captcha.getAttribute( 'data-size' ),
1050 rendered = captcha.getAttribute( 'data-rid' ) !== null,
1051 params = {
1052 'sitekey': captcha.getAttribute( 'data-sitekey' ),
1053 'size': size,
1054 'theme': captcha.getAttribute( 'data-theme' )
1055 };
1056
1057 if ( rendered ) {
1058 return;
1059 }
1060
1061 if ( size === 'invisible' ) {
1062 formID = jQuery( captcha ).closest( 'form' ).find( 'input[name="form_id"]' ).val();
1063 jQuery( captcha ).closest( '.frm_form_field .frm_primary_label' ).hide();
1064 params.callback = function( token ) {
1065 frmFrontForm.afterRecaptcha( token, formID );
1066 };
1067 }
1068
1069 recaptchaID = grecaptcha.render( captcha.id, params );
1070
1071 captcha.setAttribute( 'data-rid', recaptchaID );
1072 },
1073
1074 afterSingleRecaptcha: function() {
1075 var object = jQuery( '.frm-show-form .g-recaptcha' ).closest( 'form' )[0];
1076 frmFrontForm.submitFormNow( object );
1077 },
1078
1079 afterRecaptcha: function( token, formID ) {
1080 var object = jQuery( '#frm_form_' + formID + '_container form' )[0];
1081 frmFrontForm.submitFormNow( object );
1082 },
1083
1084 submitForm: function( e ) {
1085 frmFrontForm.submitFormManual( e, this );
1086 },
1087
1088 submitFormManual: function( e, object ) {
1089 var isPro, errors,
1090 invisibleRecaptcha = hasInvisibleRecaptcha( object ),
1091 classList = object.className.trim().split( /\s+/gi );
1092
1093 if ( classList && invisibleRecaptcha.length < 1 ) {
1094 isPro = classList.indexOf( 'frm_pro_form' ) > -1;
1095 if ( ! isPro ) {
1096 return;
1097 }
1098 }
1099
1100 if ( jQuery( 'body' ).hasClass( 'wp-admin' ) && jQuery( object ).closest( '.frmapi-form' ).length < 1 ) {
1101 return;
1102 }
1103
1104 e.preventDefault();
1105
1106 if ( typeof frmProForm !== 'undefined' && typeof frmProForm.submitAllowed === 'function' ) {
1107 if ( ! frmProForm.submitAllowed( object ) ) {
1108 return;
1109 }
1110 }
1111
1112 if ( invisibleRecaptcha.length ) {
1113 showLoadingIndicator( jQuery( object ) );
1114 executeInvisibleRecaptcha( invisibleRecaptcha );
1115 } else {
1116
1117 errors = frmFrontForm.validateFormSubmit( object );
1118
1119 if ( Object.keys( errors ).length === 0 ) {
1120 showSubmitLoading( jQuery( object ) );
1121
1122 frmFrontForm.submitFormNow( object, classList );
1123 }
1124 }
1125 },
1126
1127 submitFormNow: function( object ) {
1128 var hasFileFields, antispamInput,
1129 classList = object.className.trim().split( /\s+/gi );
1130
1131 if ( object.hasAttribute( 'data-token' ) && null === object.querySelector( '[name="antispam_token"]' ) ) {
1132 // include the antispam token on form submit.
1133 antispamInput = document.createElement( 'input' );
1134 antispamInput.type = 'hidden';
1135 antispamInput.name = 'antispam_token';
1136 antispamInput.value = object.getAttribute( 'data-token' );
1137 object.appendChild( antispamInput );
1138 }
1139
1140 if ( classList.indexOf( 'frm_ajax_submit' ) > -1 ) {
1141 hasFileFields = jQuery( object ).find( 'input[type="file"]' ).filter( function() {
1142 return !! this.value;
1143 }).length;
1144 if ( hasFileFields < 1 ) {
1145 action = jQuery( object ).find( 'input[name="frm_action"]' ).val();
1146 frmFrontForm.checkFormErrors( object, action );
1147 } else {
1148 object.submit();
1149 }
1150 } else {
1151 object.submit();
1152 }
1153 },
1154
1155 validateFormSubmit: function( object ) {
1156 if ( typeof tinyMCE !== 'undefined' && jQuery( object ).find( '.wp-editor-wrap' ).length ) {
1157 tinyMCE.triggerSave();
1158 }
1159
1160 jsErrors = [];
1161
1162 if ( shouldJSValidate( object ) ) {
1163 frmFrontForm.getAjaxFormErrors( object );
1164
1165 if ( Object.keys( jsErrors ).length ) {
1166 frmFrontForm.addAjaxFormErrors( object );
1167 }
1168 }
1169
1170 return jsErrors;
1171 },
1172
1173 getAjaxFormErrors: function( object ) {
1174 var customErrors, key;
1175
1176 jsErrors = validateForm( object );
1177 if ( typeof frmThemeOverride_jsErrors === 'function' ) { // eslint-disable-line camelcase
1178 action = jQuery( object ).find( 'input[name="frm_action"]' ).val();
1179 customErrors = frmThemeOverride_jsErrors( action, object );
1180 if ( Object.keys( customErrors ).length ) {
1181 for ( key in customErrors ) {
1182 jsErrors[ key ] = customErrors[ key ];
1183 }
1184 }
1185 }
1186
1187 return jsErrors;
1188 },
1189
1190 addAjaxFormErrors: function( object ) {
1191 var key, $fieldCont;
1192 removeAllErrors();
1193
1194 for ( key in jsErrors ) {
1195 $fieldCont = jQuery( object ).find( '#frm_field_' + key + '_container' );
1196
1197 if ( $fieldCont.length ) {
1198 addFieldError( $fieldCont, key, jsErrors );
1199 } else {
1200 // we are unable to show the error, so remove it
1201 delete jsErrors[ key ];
1202 }
1203 }
1204
1205 scrollToFirstField( object );
1206 },
1207
1208 checkFormErrors: function( object, action ) {
1209 getFormErrors( object, action );
1210 },
1211
1212 checkRequiredField: function( field, errors ) {
1213 return checkRequiredField( field, errors );
1214 },
1215
1216 showSubmitLoading: function( $object ) {
1217 showSubmitLoading( $object );
1218 },
1219
1220 removeSubmitLoading: function( $object, enable, processesRunning ) {
1221 removeSubmitLoading( $object, enable, processesRunning );
1222 },
1223
1224 scrollToID: function( id ) {
1225 var object = jQuery( document.getElementById( id ) );
1226 frmFrontForm.scrollMsg( object, false );
1227 },
1228
1229 scrollMsg: function( id, object, animate ) {
1230 var newPos, m, b, screenTop, screenBottom,
1231 scrollObj = '';
1232 if ( typeof object === 'undefined' ) {
1233 scrollObj = jQuery( document.getElementById( 'frm_form_' + id + '_container' ) );
1234 if ( scrollObj.length < 1 ) {
1235 return;
1236 }
1237 } else if ( typeof id === 'string' ) {
1238 scrollObj = jQuery( object ).find( '#frm_field_' + id + '_container' );
1239 } else {
1240 scrollObj = id;
1241 }
1242
1243 jQuery( scrollObj ).trigger( 'focus' );
1244 newPos = scrollObj.offset().top;
1245 if ( ! newPos || frm_js.offset === '-1' ) {
1246 return;
1247 }
1248 newPos = newPos - frm_js.offset;
1249
1250 m = jQuery( 'html' ).css( 'margin-top' );
1251 b = jQuery( 'body' ).css( 'margin-top' );
1252 if ( m || b ) {
1253 newPos = newPos - parseInt( m ) - parseInt( b );
1254 }
1255
1256 if ( newPos && window.innerHeight ) {
1257 screenTop = document.documentElement.scrollTop || document.body.scrollTop;
1258 screenBottom = screenTop + window.innerHeight;
1259
1260 if ( newPos > screenBottom || newPos < screenTop ) {
1261 // Not in view
1262 if ( typeof animate === 'undefined' ) {
1263 jQuery( window ).scrollTop( newPos );
1264 } else {
1265 jQuery( 'html,body' ).animate({ scrollTop: newPos }, 500 );
1266 }
1267 return false;
1268 }
1269 }
1270 },
1271
1272 fieldValueChanged: function( e ) {
1273 /*jshint validthis:true */
1274
1275 var fieldId = frmFrontForm.getFieldId( this, false );
1276 if ( ! fieldId || typeof fieldId === 'undefined' ) {
1277 return;
1278 }
1279
1280 if ( e.frmTriggered && e.frmTriggered == fieldId ) {
1281 return;
1282 }
1283
1284 jQuery( document ).trigger( 'frmFieldChanged', [ this, fieldId, e ]);
1285
1286 if ( e.selfTriggered !== true ) {
1287 maybeValidateChange( fieldId, this );
1288 }
1289 },
1290
1291 savingDraft: function( object ) {
1292 console.warn( 'DEPRECATED: function frmFrontForm.savingDraft in v3.0 use frmProForm.savingDraft' );
1293 if ( typeof frmProForm !== 'undefined' ) {
1294 return frmProForm.savingDraft( object );
1295 }
1296 },
1297
1298 goingToPreviousPage: function( object ) {
1299 console.warn( 'DEPRECATED: function frmFrontForm.goingToPreviousPage in v3.0 use frmProForm.goingToPreviousPage' );
1300 if ( typeof frmProForm !== 'undefined' ) {
1301 return frmProForm.goingToPreviousPage( object );
1302 }
1303 },
1304
1305 hideOrShowFields: function() {
1306 console.warn( 'DEPRECATED: function frmFrontForm.hideOrShowFields in v3.0 use frmProForm.hideOrShowFields' );
1307 if ( typeof frmProForm !== 'undefined' ) {
1308 frmProForm.hideOrShowFields();
1309 }
1310 },
1311
1312 hidePreviouslyHiddenFields: function() {
1313 console.warn( 'DEPRECATED: function frmFrontForm.hidePreviouslyHiddenFields in v3.0 use frmProForm.hidePreviouslyHiddenFields' );
1314 if ( typeof frmProForm !== 'undefined' ) {
1315 frmProForm.hidePreviouslyHiddenFields();
1316 }
1317 },
1318
1319 checkDependentDynamicFields: function( ids ) {
1320 console.warn( 'DEPRECATED: function frmFrontForm.checkDependentDynamicFields in v3.0 use frmProForm.checkDependentDynamicFields' );
1321 if ( typeof frmProForm !== 'undefined' ) {
1322 frmProForm.checkDependentDynamicFields( ids );
1323 }
1324 },
1325
1326 checkDependentLookupFields: function( ids ) {
1327 console.warn( 'DEPRECATED: function frmFrontForm.checkDependentLookupFields in v3.0 use frmProForm.checkDependentLookupFields' );
1328 if ( typeof frmProForm !== 'undefined' ) {
1329 frmProForm.checkDependentLookupFields( ids );
1330 }
1331 },
1332
1333 loadGoogle: function() {
1334 console.warn( 'DEPRECATED: function frmFrontForm.loadGoogle in v3.0 use frmProForm.loadGoogle' );
1335 frmProForm.loadGoogle();
1336 },
1337
1338 escapeHtml: function( text ) {
1339 return text
1340 .replace( /&/g, '&amp;' )
1341 .replace( /</g, '&lt;' )
1342 .replace( />/g, '&gt;' )
1343 .replace( /"/g, '&quot;' )
1344 .replace( /'/g, '&#039;' );
1345 },
1346
1347 invisible: function( classes ) {
1348 jQuery( classes ).css( 'visibility', 'hidden' );
1349 },
1350
1351 visible: function( classes ) {
1352 jQuery( classes ).css( 'visibility', 'visible' );
1353 }
1354 };
1355 }
1356 frmFrontForm = frmFrontFormJS();
1357
1358 jQuery( document ).ready( function() {
1359 frmFrontForm.init();
1360 });
1361
1362 function frmRecaptcha() {
1363 var c, cl,
1364 captchas = jQuery( '.frm-g-recaptcha' );
1365 for ( c = 0, cl = captchas.length; c < cl; c++ ) {
1366 frmFrontForm.renderRecaptcha( captchas[c]);
1367 }
1368 }
1369
1370 function frmAfterRecaptcha( token ) {
1371 frmFrontForm.afterSingleRecaptcha( token );
1372 }
1373
1374 function frmUpdateField( entryId, fieldId, value, message, num ) {
1375 jQuery( document.getElementById( 'frm_update_field_' + entryId + '_' + fieldId + '_' + num ) ).html( '<span class="frm-loading-img"></span>' );
1376 jQuery.ajax({
1377 type: 'POST',
1378 url: frm_js.ajax_url,
1379 data: {
1380 action: 'frm_entries_update_field_ajax',
1381 entry_id: entryId,
1382 field_id: fieldId,
1383 value: value,
1384 nonce: frm_js.nonce
1385 },
1386 success: function() {
1387 if ( message.replace( /^\s+|\s+$/g, '' ) === '' ) {
1388 jQuery( document.getElementById( 'frm_update_field_' + entryId + '_' + fieldId + '_' + num ) ).fadeOut( 'slow' );
1389 } else {
1390 jQuery( document.getElementById( 'frm_update_field_' + entryId + '_' + fieldId + '_' + num ) ).replaceWith( message );
1391 }
1392 }
1393 });
1394 }
1395
1396 function frmDeleteEntry( entryId, prefix ) {
1397 console.warn( 'DEPRECATED: function frmDeleteEntry in v2.0.13 use frmFrontForm.deleteEntry' );
1398 jQuery( document.getElementById( 'frm_delete_' + entryId ) ).replaceWith( '<span class="frm-loading-img" id="frm_delete_' + entryId + '"></span>' );
1399 jQuery.ajax({
1400 type: 'POST',
1401 url: frm_js.ajax_url,
1402 data: {
1403 action: 'frm_entries_destroy',
1404 entry: entryId,
1405 nonce: frm_js.nonce
1406 },
1407 success: function( html ) {
1408 if ( html.replace( /^\s+|\s+$/g, '' ) === 'success' ) {
1409 jQuery( document.getElementById( prefix + entryId ) ).fadeOut( 'slow' );
1410 } else {
1411 jQuery( document.getElementById( 'frm_delete_' + entryId ) ).replaceWith( html );
1412 }
1413 }
1414 });
1415 }
1416
1417 function frmOnSubmit( e ) {
1418 console.warn( 'DEPRECATED: function frmOnSubmit in v2.0 use frmFrontForm.submitForm' );
1419 frmFrontForm.submitForm( e, this );
1420 }
1421
1422 function frm_resend_email( entryId, formId ) { // eslint-disable-line camelcase
1423 var $link = jQuery( document.getElementById( 'frm_resend_email' ) );
1424 console.warn( 'DEPRECATED: function frm_resend_email in v2.0' );
1425 $link.append( '<span class="spinner" style="display:inline"></span>' );
1426 jQuery.ajax({
1427 type: 'POST',
1428 url: frm_js.ajax_url,
1429 data: {
1430 action: 'frm_entries_send_email',
1431 entry_id: entryId,
1432 form_id: formId,
1433 nonce: frm_js.nonce
1434 },
1435 success: function( msg ) {
1436 $link.replaceWith( msg );
1437 }
1438 });
1439 }
1440