PageSourceSearch

https://www.ooida.com/wp-content/plugins/codemonkeys-hipaa-forms/js/script.js?ver=3.3.0%26time%3D1790280976

js ooida.com collected 2026-09-24 20:16:52 UTC 243,155 bytes, 3,817 lines download raw bytes

1/**
2 * V3.3.0
3 */
4
5// IE FIX FOR startsWith METHOD
6if (!String.prototype.startsWith) {
7    String.prototype.startsWith = function(searchString, position) {
8        position = position || 0;
9        return this.indexOf(searchString, position) === position;
10    };
11}
12// AJAX JSON compatibility helper.
13// wp_send_json() may be auto-parsed by jQuery, while legacy endpoints may still arrive as JSON strings.
14// Keep throwing on non-JSON strings so the existing try/catch error handling remains intact.
15function cmHipaaParseAjaxJson(data) {
16    if (data && typeof data === 'object') {
17        return data;
18    }
19
20    if (typeof data === 'string') {
21        return JSON.parse(data.trim ? data.trim() : data);
22    }
23
24    return JSON.parse(data);
25}
26
27// Remove executable JavaScript from the cloned form before it is attached or submitted.
28// Gravity/Caldera HTML blocks can legitimately contain scripts that populate visible fields.
29// Those scripts should keep working on the live form, but they must not be stored with the
30// printable submitted-form HTML. Removing the complete <script> node also removes its text;
31// wp_kses() alone removes only the tag and would leave the JavaScript visible to staff.
32function cmHipaaStripHiddenFormScripts(formClone) {
33    if (!formClone || !formClone.length) {
34        return formClone;
35    }
36
37    formClone.find('script').remove();
38
39    // Remove inline JavaScript hooks from the saved clone without changing the live form.
40    formClone.find('*').add(formClone).each(function() {
41        if (!this.attributes) {
42            return;
43        }
44
45        for (var attributeIndex = this.attributes.length - 1; attributeIndex >= 0; attributeIndex--) {
46            var attribute = this.attributes[attributeIndex];
47            var attributeName = attribute.name ? attribute.name.toLowerCase() : '';
48            var attributeValue = attribute.value || '';
49
50            if (attributeName.indexOf('on') === 0) {
51                this.removeAttribute(attribute.name);
52                continue;
53            }
54
55            if (
56                (attributeName === 'href' ||
57                    attributeName === 'src' ||
58                    attributeName === 'xlink:href' ||
59                    attributeName === 'formaction') &&
60                /^\s*javascript\s*:/i.test(attributeValue)
61            ) {
62                this.removeAttribute(attribute.name);
63            }
64        }
65    });
66
67    return formClone;
68}
69
70
71jQuery(document).ready(function() {
72    /*** CHECK IF FORMS ON THE PAGE ***/
73    var forms = jQuery('form');
74    var formBuilder = cmHipaaScript.formBuilder;
75
76    var calderaEnabledForms;
77    if(cmHipaaScript.calderaEnabledForms) {
78        calderaEnabledForms = JSON.parse(cmHipaaScript.calderaEnabledForms);
79    }
80
81    var gravityEnabledForms;
82    if(cmHipaaScript.gravityEnabledForms) {
83        gravityEnabledForms = JSON.parse(cmHipaaScript.gravityEnabledForms);
84    }
85
86    var enabledFormsSettings;
87    if(cmHipaaScript.enabledFormsSettings) {
88        enabledFormsSettings = JSON.parse(cmHipaaScript.enabledFormsSettings);
89    }
90
91    formIds = [];
92    // LOOP ENABLED CALDERA FORMS AND PUSH IDS TO ARRAY - DEPRECATED
93    for(var i = 0; i < calderaEnabledForms.length; i++){
94        if(calderaEnabledForms[i]) {
95            formIds.push(calderaEnabledForms[i]);
96        }
97    }
98
99    // LOOP ENABLED GRAVITY FORMS AND PUSH IDS TO ARRAY - DEPRECATED
100    for(var i = 0; i < gravityEnabledForms.length; i++){
101        if(gravityEnabledForms[i]) {
102            formIds.push('gform_' + gravityEnabledForms[i]);
103        }
104    }
105    /*** LOOP FORMS ***/
106    forms.each(function() {
107        var form = jQuery(this);
108        var formMainId = form.attr('id');
109        var formId = form.attr('data-form-id');
110        if(!formId) {
111            formId = formMainId;
112        }
113
114        // SET NEW SUBMIT BUTTON
115        var newSubmitButton;
116        if(formId && formId.startsWith('gform_')) {
117            newSubmitButton = '<div class="cm-hipaa-forms-submit gravity cm-hipaa-forms-button active" role="button" tabindex="0" ><i class="material-icons">lock</i> SUBMIT</div>';
118        } else {
119            newSubmitButton = '<div class="cm-hipaa-forms-submit caldera cm-hipaa-forms-button active" role="button" tabindex="0" ><i class="material-icons">lock</i> SUBMIT</div>';
120        }
121
122        var showSig;
123        if(!enabledFormsSettings) {
124            // IF NEW ENABLED FORMS SETTINGS DOESN'T EXIST SET SIGNATURE TO YES
125            showSig = 'yes';
126        }
127
128        // CHECK IF FORM OBJECT EXISTS IN ARRAY - NEW FORMS SETTINGS JSON OBJECT ARRAY METHOD
129        var formFound;
130        if(cmHipaaScript.enabledFormsSettings) {
131            enabledFormsSettings.some(function (el) {
132                if (el.id === formId && el.enabled === 'yes' || el.form_builder === 'gravity' && 'gform_' + el.id === formId && el.enabled === 'yes') {
133                    formFound = true;
134
135                    // IF SIGNATURE OPTION HAS VALUE SET IT
136                    if(el.show_signature) {
137                        showSig = el.show_signature;
138                    }
139                    // SET SUBMIT BUTTON
140                    if(el.submit_btn_text){
141                        if(el.form_builder === 'gravity' && 'gform_' + el.id === formId){
142                            newSubmitButton = '<div class="cm-hipaa-forms-submit gravity cm-hipaa-forms-button active" role="button" tabindex="0" >
142' + el.submit_btn_text + '</div>';
143                        } else {
144                            newSubmitButton = '<div class="cm-hipaa-forms-submit caldera cm-hipaa-forms-button active" role="button" tabindex="0" >' + el.submit_btn_text + '</div>';
145                        }
146                    }
147                }
148            });
149        }
150        // IF FORM ID IN DEPRECATED METHOD OR FORM FOUND IN NEW JSON OBJECT ARRAY METHOD
151        if(jQuery.inArray(formId, formIds) !== -1 || formFound) {
152            // CHECK IF SSL ENABLED
153            var protocol = document.location.protocol;
154
155            // ADD CM-HIPAA-FORM-ENABLED CLASS TO FORM
156            jQuery(this).addClass('cm-hipaa-form-enabled');
157
158            // SET INITIAL VALUES
159            var submitButton = jQuery(this).find('input[type="submit"]');
160            var gravityFileUploadEle = jQuery(this).find('.ginput_container_fileupload');
161            var calderaFileUploadEle = jQuery(this).find('.file-prevent-overflow').parent();
162            var calderaMultiFileUploadEle = jQuery(this).find('.cf-uploader-trigger').parent();
163            var calderaAdvancedFileUploadEle = jQuery(this).find('.cf2-field-wrapper'); // EXPERIMENTAL - WILL OTHER NON-FILE UPLOAD FIELDS USE THIS CLASS IN THE FUTURE?
164
165            if(calderaAdvancedFileUploadEle.length > 0) {
166                jQuery.each(calderaAdvancedFileUploadEle,function (){
167                    calderaMultiFileUploadEle.push(this);
168                })
169                //calderaMultiFileUploadEle.push(calderaAdvancedFileUploadEle); // EXPERIMENTAL
170            }
171
172            var gravitySflEle = jQuery(this).find('.gform_save_link');
173            var calderaFormPages;
174            var gravityFormPages;
175            var appendEle;
176
177            calderaFormPages = jQuery(this).find('[data-formpage]');
178            gravityFormPages = jQuery(this).find('.gform_page');
179
180            // CHECK IF MULTI-PAGE FORM
181            if(calderaFormPages.length) {
182                appendEle = calderaFormPages.last();
183            } else if(gravityFormPages.length) {
184                appendEle = gravityFormPages.last();
185
186                // STRIP PREVIOUS & NEXT ONCLICK & ONKEYPRESS METHODS (IE FIX SETS ATTRIBUTE BLANK AS REMOVEATTR DOESN'T PLAY WELL WITH THAT ANTIQUE PIECE OF JUNK)
187                jQuery(this).find('.gform_next_button, .gform_previous_button').prop('onclick', '').prop('onkeypress', '').removeAttr('onclick').removeAttr('onkeypress');
188
189                // LOOP PAGES AND ADD PREVIOUS/NEXT BUTTONS
190                gravityFormPages.each(function(index) {
191                    index = +index+1;
192                    var pageFooter = jQuery(this).find('.gform_page_footer');
193                    var inputIndex = jQuery(this).find('.gform_page_fields input[tabindex]').last().attr('tabindex');
194                    var previousButtonIndex;
195
196                    // PREPEND PREVIOUS BUTTON TO LAST PAGE (NOT SURE WHY ONLY THAT PAGE DOESN'T GET IT)
197                    if(index > 1 && index === gravityFormPages.length) {
198                        previousButtonIndex = +inputIndex+1;
199
200                        pageFooter.prepend('<input type="button" id="gform_previous_button_12" class="gform_previous_button button" value="Previous" tabindex="' + previousButtonIndex + '">');
201                    }
202                });
203            } else {
204                appendEle = form;
205            }
206            // REMOVE FORM ACTION TO ONLY SUBMIT THROUGH AJAX
207            jQuery(this).attr('action','');
208
209            // STOP FORMS FROM USING GENERIC SUBMIT BUTTON
210            jQuery(document).on('click', '#'+ formMainId +' input[type="submit"], #'+ formMainId +' button[type="submit"], #'+ formMainId +' [id^=gform_submit_button], #'+ formMainId +' input[type="submit"], #'+ formMainId +' button[type="submit"] ', function(e) {
211                e.preventDefault();
212                alert('ERROR:  This form submission is being overridden be the HIPAA Forms Plugin and was not submitted!');
213            });
214
215            // SET LOADING ICON
216            appendEle.append('<div class="cm-hipaa-forms-loading"><img src="' + cmHipaaScript.pluginUrl + '/images/loading/loading16.gif" alt="Securing Form" /><br /><br />SECURING FORM</div>');
217
218            // ENSURE SSL ENABLED IF FORM SELECTED AS HIPAA COMPLIANT (checks both Wordpress is_ssl AND document protocol for good measure)
219            if(protocol === 'https:' && cmHipaaScript.ssl === '1') {
220                /*** VALIDATE ACCOUNT ***/
221                jQuery.ajax({
222                    method: 'POST',
223                    type: 'POST',
224                    url: cmHipaaScript.ajax_url,
225                    data: {
226                        'action': 'cm_hipaa_validate_account',
227                        'nonce': cmHipaaScript.nonce
228                    },
229                    success: function (data) {
230                        // REMOVE LOADING ICON
231                        jQuery('.cm-hipaa-forms-loading').remove();
232
233                        //var resultData = JSON.parse(data);
234                        var resultData;
235                        try {
236                            resultData = cmHipaaParseAjaxJson(data);
237                        } catch (e) {
238                            console.log(data);
239                            appendEle.append('<div class="cm-hipaa-field-error">There was an Ajax Error!</div>');
240                            return false;
241                        }
242
243                        if(resultData.success === 'success') {
244                            // CHECK IF STAGING
245                            var stagingMessage = '';
246                            if(resultData.staging) {
247                                stagingMessage = resultData.staging;
248                            }
249
250                            /*** CHECK IF FILE UPLOAD ENABLED ***/
251                            var validatedAddOns = resultData.add_ons;
252                            var validatedAddOnsArray = '';
253                            if(validatedAddOns && validatedAddOns !== null && validatedAddOns !== 'null' && validatedAddOns !== ''){
254                                if(Array.isArray(validatedAddOns)){
255                                    validatedAddOnsArray = validatedAddOns.split(',');
256                                }else{
257                                    validatedAddOnsArray = validatedAddOns;
258                                }
259
260                            }
261                            var fileUploadEnabled = 'no';
262                            if(Array.isArray(validatedAddOnsArray) && validatedAddOnsArray.indexOf('fileupload') !== -1) {
263                                fileUploadEnabled = 'yes';
264                            } else if(validatedAddOns === 'fileupload') {
265                                fileUploadEnabled = 'yes';
266                            }
267
268                            // SET BASIC PRODUCT BADGE
269                            var basicBadge = '';
270                            if(resultData.product === 'basic' || resultData.license_status === 'expired') {
271                                basicBadge = '<div class="cm-hipaa-powered-by-badge">POWERED BY <a href="https://www.hipaaforms.online" target="_blank">HIPAA FORMS</a> <i>for Wordpress</i></div>';
272                            }
273
274                            // IF BASIC PRODUCT CHECK IF MAX SUBMISSIONS REACHED
275                            var maxSubmissionsMessage;
276                            if(resultData.product === 'basic' && resultData.this_months_submissions >= 25) {
277                                // CHANGING THIS WILL ENABLE YOUR FORM BUT THE SUBMISSIONS WILL STILL BE BLOCKED BY THE API. UPGRADING IS ONLY $50/MO, CODE MONKEYS HAVE BILLS TO PAY TOO ;).
278                                maxSubmissionsMessage = '<div class="cm-hipaa-field-error">The maximum number of forms have been submitted for this month, please try again next month.</div>' + basicBadge;
279                            }
280
281                            if(submitButton.length > 0) {
282                                // DISABLE & REMOVE ORIGINAL SUBMIT BUTTON TO PREVENT ACCIDENTAL GENERAL SUBMISSION
283                                submitButton.attr('disabled', 'disabled').remove();
284                            }
285
286                            // CHECK IF GRAVITY FILE UPLOAD FIELD & FILE UPLOAD URL EXISTS & REPLACE WITH MESSAGE IF NO UPLOAD URL
287                            if(gravityFileUploadEle && fileUploadEnabled !== 'yes') {
288                                gravityFileUploadEle.html('<div class="cm-hipaa-field-error">Default file upload functionality is not HIPAA compliant & has been disabled, please upgrade HIPAA Forms for file upload capability.</div>');
289                            } else if(gravityFileUploadEle && fileUploadEnabled === 'yes') {
290                                // DISABLE GFORM THEME ON FILE UPLOAD ELEMENT (NEEDED SINCE ORBITAL THEME)
291                                gravityFileUploadEle.addClass('gform-theme__disable');
292
293                                // LOOP FILE INPUT FIELDS & REPLACE MULTI-FILE UPLOAD IF EXISTS
294                                jQuery.each(gravityFileUploadEle, function() {
295                                    var gfMultiFile = jQuery(this).find('.gform_fileupload_multifile');
296                                    var fieldId = jQuery(this).parent().attr('id');
297                                    var fileInputId = fieldId.replace('field', 'input');
298                                    var fileInputEnd = fieldId.split('_').pop();
299                                    var fileInputName = 'input_' + fileInputEnd;
300                                    var fileInputDescribed = fieldId.replace('field', 'extensions_message');
301                                    var tabIndex = jQuery(this).find('.gform_button_select_files').attr('tabindex');
302
303                                    var gfAcceptAttr = jQuery(this).find('.gform_fileupload_multifile input[type="file"]').attr('accept');
304                                    var gfMaxFileSize = 0;
305                                    var gfDisallowedExtensions = "php,asp,aspx,cmd,csh,bat,html,htm,hta,jar,exe,com,js,lnk,htaccess,phtml,ps1,ps2,php3,php4,php5,php6,py,rb,tmp";
306                                    var gfFileMimeTypesExtensions = "*";
307                                    var gfMaxFiles = 0;
308
309                                    var gfFileInputSettings = "";
310                                    if(gfMultiFile && gfMultiFile.data('settings')){
311                                        var gfFileDataSettings = gfMultiFile.data('settings');
312                                        if(gfFileDataSettings.filters.max_file_size){
313                                            gfMaxFileSize = gfFileDataSettings.filters.max_file_size
314                                        }
315                                        var gfFileMimeTypesTitle = "";
316                                        if(gfFileDataSettings.filters.mime_types[0]){
317                                            var gfFileMimeTypes = gfFileDataSettings.filters.mime_types[0];
318                                            if(gfFileMimeTypes.title){
319                                                gfFileMimeTypesTitle = gfFileMimeTypes.title
320                                            }
321                                            if(gfFileMimeTypes.extensions){
322                                                gfFileMimeTypesExtensions = gfFileMimeTypes.extensions
323                                            }
324                                        }
325                                        if(gfFileDataSettings.gf_vars.disallowed_extensions){
326                                            gfDisallowedExtensions = gfFileDataSettings.gf_vars.disallowed_extensions
327                                        }
328                                        if(gfFileDataSettings.gf_vars.max_files){
329                                            gfMaxFiles = gfFileDataSettings.gf_vars.max_files
330                                        }
331                                        gfFileInputSettings = '{"maxfilesize":"'+gfMaxFileSize+'","allowedextensions":"'+gfFileMimeTypesExtensions+'","disallowedextensions":"'+gfDisallowedExtensions+'","maxfiles":"'+gfMaxFiles+'"}';
332                                    }else if (gfMultiFile.length === 0){
333                                        gfMaxFileSize = jQuery(this).find("input[type='hidden'][name='MAX_FILE_SIZE']").first().val();
334                                        var uploadRulesTxt = jQuery(this).find(".gform_fileupload_rules").first().text();
335                                        var start = uploadRulesTxt.indexOf("Accepted file types: ");
336                                        var end = uploadRulesTxt.lastIndexOf(',');
337                                        if(start > -1 && end > -1){
338                                            gfFileMimeTypesExtensions = uploadRulesTxt.substring(21, end).replaceAll(' ','').split(',');
339                                        }
340
341
342                                        gfFileInputSettings = '{"maxfilesize":"'+gfMaxFileSize+'","allowedextensions":"'+gfFileMimeTypesExtensions+'","disallowedextensions":"'+gfDisallowedExtensions+'","maxfiles":"'+gfMaxFiles+'"}';
343                                    }
344
345                                    isRequired = jQuery(this).parent().hasClass('gfield_contains_required');
346
347                                    if(gfMultiFile.length > 0 && gfMaxFiles === "1") {
348                                        //maxfiles set to allow only 1 file
349                                        gfMultiFile.replaceWith('<input name="' + fileInputName + '" id="' + fileInputId + '" type="file" class="medium cm-hipaa-multifile-upload-input" aria-describedby="' + fileInputDescribed + '" aria-required="' + isRequired + '" data-settings=' + gfFileInputSettings + ' accept="'+gfAcceptAttr+'"  tabindex="' + tabIndex + '">');
350                                    }else if(gfMultiFile.length > 0 ){
351                                        gfMultiFile.replaceWith('<input name="' + fileInputName + '" id="' + fileInputId + '" type="file" class="medium cm-hipaa-multifile-upload-input" aria-describedby="' + fileInputDescribed + '" aria-required="' + isRequired + '" data-settings=' + gfFileInputSettings + ' accept="'+gfAcceptAttr+'"  tabindex="' + tabIndex + '"><div id="assocd_id_'+ fileInputId +'" class="cm-hipaa-gf-multifile-upload-button">Add Another File</div>');
352                                    }else if(gfMultiFile.length === 0 && gfMaxFiles === 0){
353                                        jQuery('#'+fileInputId).replaceWith('<input name="' + fileInputName + '" id="' + fileInputId + '" type="file" class="medium cm-hipaa-multifile-upload-input" aria-describedby="' + fileInputDescribed + '"  aria-required="' + isRequired + '" data-settings=' + gfFileInputSettings + ' tabindex="' + tabIndex + '">');
354                                    }
355                                });
356                            }
357
358                            // CHECK IF CALDERA FILE UPLOAD FIELD & FILE UPLOAD URL EXISTS & REPLACE WITH MESSAGE IF NO UPLOAD URL
359                            if((calderaFileUploadEle || calderaMultiFileUploadEle) && fileUploadEnabled !== 'yes') {
360                                calderaFileUploadEle.html('<div class="cm-hipaa-field-error">Default file upload functionality is not HIPAA compliant & has been disabled, please upgrade HIPAA Forms for file upload capability.</div>');
361                            } else if(calderaMultiFileUploadEle && fileUploadEnabled === 'yes') {
362                                // LOOP FILE INPUT FIELDS & REPLACE MULTI-FILE UPLOAD IF EXISTS
363                                jQuery.each(calderaMultiFileUploadEle, function() {
364                                    var fieldId = jQuery(this).parent().attr('data-field-wrapper');
365                                    if(!fieldId){
366                                        fieldId = jQuery(this).attr('data-field-id');
367                                    }
368                                    var cfInputField = jQuery("#"+fieldId);
369                                    var cfAcceptAttr = cfInputField.attr('accept');
370                                    var cfMaxFileSize = 0;
371                                    var cfDisallowedExtensions = "php,asp,aspx,cmd,csh,bat,html,htm,hta,jar,exe,com,js,lnk,htaccess,phtml,ps1,ps2,php3,php4,php5,php6,py,rb,tmp";
372                                    var cfFileMimeTypesExtensions = "*";
373                                    var cfMaxFiles = cfInputField.attr('multiple');
374
375                                    var cfFileInputSettings = '{"maxfilesize":"'+cfMaxFileSize+'","allowedextensions":"'+cfFileMimeTypesExtensions+'","disallowedextensions":"'+cfDisallowedExtensions+'","maxfiles":"'+cfMaxFiles+'"}';
376
377                                    if(cfMaxFiles === 'multiple'){
378                                        jQuery(this).replaceWith('<div class="file-prevent-overflow"><div id="' + fieldId + '_1_file_list" class="cf-multi-uploader-list"></div><input type="file" data-settings=' + cfFileInputSettings + ' accept="'+cfAcceptAttr+'" name="' + fieldId + '" value="" data-field="' + fieldId + '" class="" id="' + fieldId + '_1" aria-labelledby="' + fieldId + 'Label"><input type="hidden" name="' + fieldId + '"></div><div id="assocd_id_'+ fieldId +'" class="cm-hipaa-cf-multifile-upload-button">Add Another File</div>');
379                                    }else {
380                                        jQuery(this).replaceWith('<div class="file-prevent-overflow"><div id="' + fieldId + '_1_file_list" class="cf-multi-uploader-list"></div><input type="file" data-settings=' + cfFileInputSettings + ' accept="' + cfAcceptAttr + '" name="' + fieldId + '" value="" data-field="' + fieldId + '" class="" id="' + fieldId + '_1" aria-labelledby="' + fieldId + 'Label"><input type="hidden" name="' + fieldId + '">');
381                                    }
382                                });
383                            }
384
385                            // CHECK IF GRAVITY FORMS "SAVE FOR LATER" LINK EXISTS AND REPLACE WITH NON-COMPLIANT MESSAGE
386                            if(gravitySflEle) {
387                                gravitySflEle.replaceWith('<div class="cm-hipaa-field-error">"Save For Later" has been disabled due to HIPAA non-compliance</div>');
388                            }
389
390                            var sigField = '';
391                            if(showSig === 'yes') {
392                                sigField = '<div class="cm-hipaa-form-signature-wrapper"><div class="cm-hipaa-form-signature-inner"><div class="cm-hipaa-form-signature" style="min-height:150px;"></div><div class="cm-hipaa-form-signature-label"><span class="cm-hipaa-form-signature-label-text">To sign left click and drag mouse or use your finger or stylus if touch screen</span> <span class="cm-hipaa-form-signature-reset cm-ghost-button" class="cm-hipaa-forms-button">RESET</span><span style="clear:both;"></span></div></div></div>';
393                            }
394
395                            // SET HIPAA PRIVACY NOTICE
396                            var cmPrivacyNoticeMethod = cmHipaaScript.privacyNoticeMethod;
397                            var cmPrivacyNoticeLabel = cmHipaaScript.privacyNoticeLabel;
398                            var cmPrivacyNoticeCopy = cmHipaaScript.privacyNoticeCopy;
399                            var cmPrivacyNoticeLink = cmHipaaScript.privacyNoticeLink;
400                            var privacyStatement;
401
402                            if(!cmPrivacyNoticeLabel) {
403                                cmPrivacyNoticeLabel = 'I agree to the HIPAA Privacy Statement';
404                            }
405
406                            if(!cmPrivacyNoticeCopy) {
407                                cmPrivacyNoticeCopy = '<p>\n' +
408                                    'This "Notice of Information/Privacy Practices" is used to inform website visitors regarding our policies with the collection, use, and disclosure of Personal Information if anyone decided to use our Service.\n' +
409                                    '</p>\n' +
410                                    '<p>\n' +
411                                    'If you choose to use our Service, then you agree to the collection and use of information in relation with this policy. The Personal Information that we collect are used for providing and improving the Service. We will not use or share your information with anyone except as de
411scribed in this Privacy Policy.\n' +
412                                    '</p>\n' +
413                                    '<p>\n' +
414                                    '<h3>Information Collection and Use</h3>\n' +
415                                    'For a better experience while using our Service, we may require you to provide us with certain personally identifiable information, including but not limited to your name, phone number, and postal address. The information that we collect will be used to contact or identify you.\n' +
416                                    '</p>\n' +
417                                    '<p>\n' +
418                                    '<h3>Log Data</h3>\n' +
419                                    'We want to inform you that whenever you visit our Service, we collect information that your browser sends to us that is called Log Data. This Log Data may include information such as your computer’s Internet Protocol ("IP") address, browser version, pages of our Service that you visit, the time and date of your visit, the time spent on those pages, and other statistics.\n' +
420                                    '</p>\n' +
421                                    '<p>\n' +
422                                    '<h3>Cookies</h3>\n' +
423                                    'Cookies are files with small amount of data that is commonly used an anonymous unique identifier. These are sent to your browser from the website that you visit and are stored on your computer’s hard drive.\n' +
424                                    '</p>\n' +
425                                    '<p>\n' +
426                                    'Our website uses these "cookies" to collection information and to improve our Service. You have the option to either accept or refuse these cookies, and know when a cookie is being sent to your computer. If you choose to refuse our cookies, you may not be able to use some portions of our Service.\n' +
427                                    '</p>\n' +
428                                    '<p>\n' +
429                                    '<h3>Service Providers</h3>\n' +
430                                    'We may employ third-party companies and individuals due to the following reasons:\n' +
431                                    '<ul>\n' +
432                                    '<li>To facilitate our Service;</li>\n' +
433                                    '<li>To provide the Service on our behalf;</li>\n' +
434                                    '<li>To perform Service-related services; or</li>\n' +
435                                    '<li>To assist us in analyzing how our Service is used.</li>\n' +
436                                    '<p>\n' +
437                                    'We want to inform our Service users that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose.\n' +
438                                    '</p>\n' +
439                                    '</p>\n' +
440                                    '<p>\n' +
441                                    '<h3>Security</h3>\n' +
442                                    'We value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and we cannot guarantee its absolute security.\n' +
443                                    '</p>\n' +
444                                    '<p>\n' +
445                                    '<h3>Links to Other Sites</h3>\n' +
446                                    'Our Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by us. Therefore, we strongly advise you to review the Privacy Policy of these websites. We have no control over, and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.\n' +
447                                    '</p>\n' +
448                                    '<p>\n' +
449                                    '<h3>Changes to This Privacy Policy</h3>\n' +
450                                    'We may update our Privacy Policy from time to time. Thus, we advise you to review this page periodically for any changes. We will notify you of any changes by posting the new Privacy Policy on this page. These 
450changes are effective immediately, after they are posted on this page.\n' +
451                                    '</p>';
452                            }
453
454                            var modalHTML;
455                            if(cmPrivacyNoticeLink && cmPrivacyNoticeMethod === 'link') {
456                                privacyStatement = '<span class="cm-hipaa-privacy-statement-link"><a href="' + cmPrivacyNoticeLink + '" target="_blank" >' + cmPrivacyNoticeLabel + '</a></span>';
457                                modalHTML = '';
458                            } else {
459                                modalHTML = '<div class="cmprivacy-modal closed"><div class="cmprivacy-modal-inner"><div class="cmprivacy-modal-inner-top"><h2 class="cmprivacy-title">Notice of Information/Privacy Practices</h2><i class="cmprivacy-close-btn material-icons">cancel</i></div><div class="cmprivacy-content">'+ cmPrivacyNoticeCopy + '</div></div></div>';
460
461                                privacyStatement = '<span class="cm-hipaa-privacy-statement"><a href="#" >' + cmPrivacyNoticeLabel + '</a></span>';
462                            }
463
464                            // CREATE HONEYPOT INPUT
465                            var honeyPot = '<input type="hidden" class="cm-hipaa-required-extra" value="" />';
466
467                            if(maxSubmissionsMessage) {
468                                // PREPEND MAX FORM SUBMISSIONS MESSAGE
469                                form.prepend('<div class="cm-hipaa-forms-prepend">'+ maxSubmissionsMessage +'</div>');
470
471                                // APPEND MAX FORM SUBMISSIONS MESSAGE
472                                appendEle.append('<div class="cm-hipaa-forms-prepend">'+ maxSubmissionsMessage +'</div>');
473
474                                // DISABLE FORM INPUTS
475                                form.find('input, textarea').attr('readonly', 'readonly');
476                                form.find('select').attr('disabled', 'disabled');
477                                form.find('input[type="checkbox"], input[type="radio"]').prop('disabled', true);
478                            } else {
479                                // APPEND ADDITIONAL FIELDS, SUBMIT BUTTON AND BADGE TO THE FORM
480                                appendEle.append('<div class="cm-hipaa-forms-prepend gform-theme__disable">' + modalHTML + '<div class="cm-hipaa-forms-privacy-statement"><label for="cm-hipaa-forms-privacy-agree" class="sr-only"> ' + cmPrivacyNoticeLabel + '</label><input type="checkbox" id="cm-hipaa-forms-privacy-agree" class="cm-hipaa-forms-privacy-agree" name="cm-hipaa-forms-privacy-agree" aria-label="HIPAA Forms Privacy Statment" value="Yes" /> ' + privacyStatement + '</div><div class="cm-hipaa-forms-prepend-bottom gform-theme__disable"><div class="cm-hipaa-forms-ssl-notice"></div>' + sigField + '<div class="cm-hipaa-forms-submit-wrapper">' + honeyPot + newSubmitButton + '</div><div class="cm-hipaa-notice"></div>' + stagingMessage + '<div class="cm-hipaa-form-badge-wrapper"><img src="' + cmHipaaScript.pluginUrl + '/images/hipaa-compliant-badge.png" alt="HIPAA COMPLIANT FORM" /></div>' + basicBadge + '</div></div>').promise().done(function () {
481                                    if (showSig === 'yes') {
482                                        // INITIALIZE THE FORM SIGNATURE CANVAS FIELD IF VISIBLE
483                                        var signature = appendEle.find(".cm-hipaa-form-signature");
484                                        if (signature.is(':visible')) {
485                                            signature.jSignature({'background-color':'transparent'});
486                                        }
487                                    }
488                                });
489                            }
490                        } else {
491                            // DISABLE & REMOVE ORIGINAL SUBMIT BUTTON TO PREVENT ACCIDENTAL GENERAL SUBMISSION
492                            submitButton.attr('disabled', 'disabled').remove();
493
494                            appendEle.append(resultData.error);
495                        }
496                    },
497                    error: function (errorThrown) {
498                        // REMOVE LOADING ICON
499                        jQuery('.cm-hipaa-forms-loading').remove();
500
501                        console.log(errorThrown);
502                    }
503                });
504            } else {
505                // APPEND NOTICE THAT SSL IS NOT ENABLED
506                form.append('<div class="cm-hipaa-forms-ssl-notice">This form is designated as a HIPAA compliant form however SSL (https) is not enabled so the form has been disabled.<br />Please ask the website administrators to fix this issue.</div>');
507
508                // DISABLE AND REMOVE SUBMIT BUTTON TO ENSURE FORM CAN'T BE SUBMITTED
509                submitButton.attr('disabled', 'disabled').remove();
510            }
511        }
512    });
513
514    /*** REINITIALIZE JSIGNATURE IF MULTI-PAGE FORM - JSIGNATURE DOESN'T INIT PROPERLY WHEN IN A HIDDEN ELEMENT ***/
515    jQuery(document).on('click', '.cm-hipaa-form-enabled .cf-page-btn-next, .cm-hipaa-form-enabled .gform_next_button, .cm-hipaa-form-enabled .gf_step, .caldera_forms_form .breadcrumb a', function() {
516        var signature = jQuery(this).closest('form').find('.cm-hipaa-form-signature');
517
518        // SET TIMEOUT TO WAIT FOR FADEIN
519        setTimeout(function() {
520            if(signature.is(':visible') && signature.find('canvas').length === 0) {
521                signature.jSignature({'background-color':'transparent'});
522            }
523        },500);
524    });
525
526    /*** ADD VALID CLASS TO SIGNATURE FIELD ON CLICK ***/
527    jQuery(document).on('click', '.jSignature', function() {
528        if(!jQuery(this).hasClass('cm-valid-sig')) {
529            jQuery(this).addClass('cm-valid-sig');
530        }
531    });
532
533    /*** TOUCH EVENT VERSION ***/
534    jQuery(document).on('touchstart', '.jSignature', function() {
535        if(!jQuery(this).hasClass('cm-valid-sig')) {
536            jQuery(this).addClass('cm-valid-sig');
537        }
538    });
539
540    /*** REMOVE VALID CLASS FROM SIGNATURE FIELD ON RESET ***/
541    jQuery(document).on('click', '.cm-hipaa-form-signature-reset', function() {
542        jQuery(this).parent().parent().find('.jSignature').removeClass('cm-valid-sig');
543    });
544
545    /*** OVER-RIDE GRAVITY PREVIOUS/NEXT BUTTONS TO SHOW/HIDE INSTEAD OF RELOAD PAGE, DEFAULT FORM SUBMIT TO SELF ISN'T PROTECTED & NOT COMPLIANT! ***/
546    jQuery(document).on('click', '.cm-hipaa-form-enabled .gform_previous_button, .cm-hipaa-form-enabled .gform_next_button', function(e) {
547        var form = jQuery(this).closest('form');
548        var formId = form.attr('id');
549        var thisPage = jQuery(this).parent().parent();
550        var pages = form.find('.gform_page');
551        var pbPercent = Math.floor(100/pages.length);
552        var progressBarTitle = form.find('.gf_progressbar_title');
553        var progressBar = form.find('.gf_progressbar_percentage');
554        var stepsWrapper = form.find('.gf_page_steps');
555        var direction;
556
557        // CLEAR ERRORS
558        form.find('.gfield_error').removeClass('gfield_error');
559        form.find('.validation_error, .validation_message').remove();
560
561        if(jQuery(this).hasClass('gform_previous_button')) {
562            direction = 'previous';
563        } else if(jQuery(this).hasClass('gform_next_button')) {
564            direction = 'next';
565        }
566
567        // LOOP PAGES
568        pages.each(function(index) {
569            index = index+1;
570
571            if(jQuery(this).attr('id') === thisPage.attr('id') && direction === 'next') {
572                // VALIDATE REQUIRED FIELDS ON PAGE
573                var inputs = thisPage.find('input, select, textarea');
574                var errors = [];
575
576                // LOOP INPUTS
577                inputs.each(function() {
578                    var fieldWrapper = jQuery(this).closest('.gfield');
579                    var fieldType = jQuery(this).attr('type');
580                    var value = jQuery(this).val();
581                    var visibleSelect;
582                    var optionText;
583                    var fieldId = jQuery(this).attr('id');
584
585                    if (!fieldType) {
586                        if (jQuery(this).is('select')) {
587                            fieldType = 'select';
588                            visibleSelect = form.find('#' + fieldId);
589                            optionText = visibleSelect.find('option:selected').text();
590                            value = visibleSelect.val();
591                        } else if (jQuery(this).is('textarea')) {
592                            fieldType = 'textarea';
593                            var visibleTextArea = form.find('#' + fieldId);
594                            value = visibleTextArea.attr('value');
595                            // TRY THE VALUE ATTR FIRST AND IF NO VALUE TRY NORMAL JQUERY VAL(), NOT SURE WHY ONE WORKS OVER THE OTHER 
595SOMETIMES
596                            if (!value || value === 'undefined') {
597                                value = visibleTextArea.val();
598                            }
599                        }
600                    }
601                    // IF CHECKBOX OR RADIO SET OPTIONS
602                    var checkOrRadio = false;
603                    var cbOptionChecked;
604                    if(fieldType === 'checkbox' || fieldType === 'radio') {
605                        checkOrRadio = true;
606                        cbOptionChecked = jQuery(this).prop('checked');
607                    }
608
609                    // SET IF FIELD IS HIDDEN OR DISABLED
610                    var isVisible = jQuery(this).is(':visible');
611                    var isDisabled = jQuery(this).prop('disabled');
612
613                    // CHECK IF FIELD IS A NUMBER FIELD WITH MIN AND/OR MAX
614                    if (fieldType === 'number') {
615                        var val = jQuery(this).val();
616                        var num = parseFloat(val);
617                        if (val !== '') {
618                            if (jQuery.isNumeric(num)) {
619                                var min = parseFloat(jQuery(this).attr('min'));
620                                var max = parseFloat(jQuery(this).attr('max'));
621                                if (jQuery.isNumeric(min) && jQuery.isNumeric(max)) {
622                                    if ((Math.round(num * 100000) < Math.round(min * 100000)) || (Math.round(max * 100000) < Math.round(num * 100000))) {
623                                        errors.push(jQuery(this).attr('id'));
624                                    }
625                                } else if (jQuery.isNumeric(max)) {
626                                    if (Math.round(max * 100000) < Math.round(num * 100000)) {
627                                        errors.push(jQuery(this).attr('id'));
628                                    }
629                                } else if (jQuery.isNumeric(min)) {
630                                    if (Math.round(num * 100000) < Math.round(min * 100000)) {
631                                        errors.push(jQuery(this).attr('id'));
632                                    }
633                                }
634                            } else {
635                                errors.push(jQuery(this).attr('id'));
636                            }
637                        }
638
639                    }
640
641                    // CHECK IF FIELD IS AN EMAIL AND FORMATTED CORRECTLY
642                    if (fieldType === 'email'){
643                        var emailVal = jQuery(this).val();
644                        // pattern taken form https://emailregex.com/
645                        var emailReg = /^(([^<>()\[\]\\.,;:\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,}))$/;
646                        if ( emailVal !== '' ) {
647                            if(!emailReg.test( emailVal ) ){
648                                errors.push(jQuery(this).attr('id'));
649                            }
650                        }
651                    }
652
653                    // SET IF FIELD IS REQUIRED
654                    var required = false;
655                    if(isDisabled !== true && isVisible === true && !jQuery(this).parent().hasClass('name_prefix_select') && !jQuery(this).parent().hasClass('name_suffix') && !jQuery(this).parent().hasClass('ginput_address_line_2') && (jQuery(this).attr('required') === 'true' || jQuery(this).attr('aria-required') === 'true' || fieldWrapper.hasClass('gfield_contains_required') && checkOrRadio !== true && !jQuery(this).parent().hasClass('address_line_2'))) {
656                        required = true;
657                    }
658
659                    // IF REQUIRED FIELD WITH NO VALUE PUSH FIELD TO ERRORS ARRAY
660                    if (required && (!value || value == "") || isDisabled !== true && isVisible === true && checkOrRadio === true && fieldWrapper.hasClass('gfield_contains_required') && cbOptionChecked === false) {
661                        var invalidInputId;
662
663                        // IF CHECKBOX OR RADIO INPUT
664                        if(checkOrRadio === true) {
665                            var cbIsValid = false;
666
667                            // GROUP OPTION INPUTS
668                            var cbInputs = fieldWrapper.find('input');
669
670                            // LOOP OPTIONS
671                            cbInputs.each(function() {
672                                if(jQuery(this).prop('checked') === true) {
673                                    cbIsValid = true;
674                                }
675                            });
676
677                            // PUSH ID TO ERROR ARRAY IF INVALID
678                            if(cbIsValid !== true) {
679                                invalidInputId = fieldWrapper.attr('id');
680                            }
681                        } else if (jQuery(this).attr('id') === undefined){
682                            invalidInputId = fieldWrapper.attr('id');
683                        } else if (fieldType === 'select'){
684                            invalidInputId = fieldWrapper.attr('id');
685                        }else {
686                            invalidInputId = jQuery(this).attr('id');
687                        }
688
689                        if(invalidInputId && errors.indexOf(invalidInputId) === -1) {
690                            errors.push(invalidInputId);
691                        }
692                    }
693                });
694
695                if(errors.length > 0) {
696                    // SET FIRST INVALID FIELD
697                    var firstErrorId = errors[0];
698                    var firstInvalidInput = jQuery('#' + firstErrorId);
699                    var firstInvalidInputWrapper = firstInvalidInput.closest('.gfield');
700
701                    // ADD ERROR MESSAGE TO TOP OF FORM
702                    form.find('.gform_body').before('<div class="validation_error">There was a problem with your submission. Errors have been highlighted below.</div>');
703
704                    // LOOP INVALID INPUT ID'S
705                    for(i=0; i<errors.length; i++) {
706                        var invalidInput = jQuery('#' + errors[i]);
707                        var invalidFieldType = invalidInput.attr('type');
708
709                        // ADD ERROR CLASS & NOTICE MESSAGE
710                        var invalidInputWrapper;
711                        if(invalidFieldType === 'checkbox' || invalidFieldType === 'radio') {
712                            invalidInputWrapper = invalidInput.parent().parent().parent().parent();
713                            invalidInputWrapper.addClass('gfield_error').append('<div class="gfield_description validation_message">This field is required.</div>');
714                        } else {
715                            invalidInputWrapper = invalidInput.closest('.gfield');
716                            invalidInputWrapper.addClass('gfield_error').append('<div class="gfield_description validation_message">This field is required.</div>');
717                        }
718                    }
719
720                    // SCROLL TO FIRST INVALID FIELD
721                    jQuery('html, body').animate({
722                        scrollTop: firstInvalidInputWrapper.offset().top
723                    }, 500, 'linear');
724                } else {
725                    // FADE OUT THIS PAGE
726                    jQuery(this).fadeOut().promise().done(function () {
727                        // FADE IN NEXT PAGE
728                        var nextPageEle = jQuery(this).next('.gform_page');
729                        nextPageEle.fadeIn();
730
731                        var nextIndex = index + 1;
732
733                        // UPDATE PROGRESS BAR IF SET
734                        if(progressBar) {
735                            var nextPercent;
736                            if (index + 1 === pages.length) {
737                                nextPercent = 100;
738                            } else {
739                                nextPercent = (pbPercent * index) + pbPercent;
740                            }
741                            progressBar.css('width', nextPercent + '%').find('span').html(nextPercent + '%');
742                            progressBarTitle.html('Step ' + nextIndex + ' of ' + pages.length);
743                        }
744
745                        // UPDATE STEPS IF SET
746                        if(stepsWrapper) {
747                            var stepLinks = stepsWrapper.find('.gf_step');
748                            var pageId = nextPageEle.attr('id');
749                            var pageIdArr = pageId.split('_');
750
751                            var stepLinkId = 'gf_step_' + pageIdArr[2] + '_' + pageIdArr[3];
752
753                            // LOOP STEP LINK AND SET NEXT STEP ACTIVE
754                            jQuery.each(stepLinks, function() {
755                                if(jQuery(this).attr('id') === stepLinkId) {
756                                    jQuery(this).addClass('gf_step_active gpmpn-step-current');
757                                } else {
758                                    jQuery(this).removeClass('gf_step_active gpmpn-step-current');
759                                }
760                            });
761                        }
762
763                        // SCROLL TO FIRST INVALID FIELD
764                        jQuery('html, body').animate({
765                            scrollTop: form.offset().top
766                        }, 300, 'linear');
767                    });
768                }
769            } else if(jQuery(this).attr('id') === thisPage.attr('id') && direction === 'previous') {
770                // FADE OUT THIS PAGE
771                jQuery(this).fadeOut().promise().done(function() {
772                    // FADE IN PREVIOUS PAGE
773                    var prevPageEle = jQuery(this).prev('.gform_page');
774                    prevPageEle.fadeIn();
775
776                    var previousIndex = index - 1;
777
778                    // UPDATE PROGRESS BAR
779                    if(progressBar) {
780                        prevPercent = (pbPercent * index) - pbPercent;
781                        progressBar.css('width', prevPercent + '%').find('span').html(prevPercent + '%');
782                        progressBarTitle.html('Step ' + previousIndex + ' of ' + pages.length);
783                    }
784
785                    // UPDATE STEPS IF SET
786                    if(stepsWrapper) {
787                        var stepLinks = stepsWrapper.find('.gf_step');
788                        var pageId = prevPageEle.attr('id');
789                        var pageIdArr = pageId.split('_');
790
791                        var stepLinkId = 'gf_step_' + pageIdArr[2] + '_' + pageIdArr[3];
792
793                        // LOOP STEP LINK AND SET NEXT STEP ACTIVE
794                        jQuery.each(stepLinks, function() {
795                            if(jQuery(this).attr('id') === stepLinkId) {
796                                jQuery(this).addClass('gf_step_active gpmpn-step-current');
797                            } else {
798                                jQuery(this).removeClass('gf_step_active gpmpn-step-current');
799                            }
800                        });
801                    }
802
803                    // SCROLL TO FIRST INVALID FIELD
804                    jQuery('html, body').animate({
805                        scrollTop: form.offset().top
806                    }, 300, 'linear');
807                });
808            }
809        });
810    });
811
812    /*** ADD GRAVITY STEP LINK ACTION ***/
813    jQuery(document).on('click', '.cm-hipaa-form-enabled .gf_step', function() {
814        var form = jQuery(this).closest('form');
815        var stepsWrapper = form.find('.gf_page_steps');
816        var stepLinks = stepsWrapper.find('.gf_step');
817        var stepId = jQuery(this).attr('id');
818        var stepIdArr = stepId.split('_');
819        var pageId = 'gform_page_' + stepIdArr[2] + '_' + stepIdArr[3];
820        var curPage = form.find('.gform_page:visible');
821        var curPageIdArr = curPage.attr('id').split('_');
822
823        if(curPage.attr('id') !== pageId) {
824            if(stepIdArr[3] > curPageIdArr[3]) {
825                // CLEAR ERRORS
826                form.find('.gfield_error').removeClass('gfield_error');
827                form.find('.validation_error, .validation_message').remove();
828
829                // VALIDATE REQUIRED FIELDS ON PREVIOUS PAGES
830                var inputs = [];
831                jQuery.each(form.find('.gform_page'), function() {
832                    if(jQuery(this).attr('id').split('_')[3] < stepIdArr[3]) {
833                        var pageInputs = jQuery(this).find('input');
834
835                        pageInputs.each(function() {
836                            inputs.push(jQuery(this).attr('id'));
837                        });
838                    } else {
839                        return false;
840                    }
841                });
842
843                var errors = [];
844                // LOOP INPUTS
845                for(i=0; i<inputs.length; i++) {
846                    var curInput = jQuery('#' + inputs[i]);
847                    var fieldWrapper = curInput.closest('.gfield');
848                    var fieldType = curInput.attr('type');
849                    var value = curInput.val();
850
851                    // IF CHECKBOX OR RADIO SET OPTIONS
852                    var checkOrRadio = false;
853                    var cbOptionChecked;
854                    if(fieldType === 'checkbox' || fieldType === 'radio') {
855                        checkOrRadio = true;
856                        cbOptionChecked = curInput.prop('checked');
857                    }
858
859                    // SET IF FIELD IS HIDDEN OR DISABLED
860                    var isVisible = curInput.is(':visible');
861                    var isDisabled = curInput.prop('disabled');
862
863                    // CHECK IF FIELD IS A NUMBER FIELD WITH MIN AND/OR MAX
864                    if (fieldType === 'number') {
865                        var val = jQuery(this).val();
866                        var num = parseFloat(val);
867                        if (val !== '') {
868                            if (jQuery.isNumeric(num)) {
869                                var min = parseFloat(jQuery(this).attr('min'));
870                                var max = parseFloat(jQuery(this).attr('max'));
871                                if (jQuery.isNumeric(min) && jQuery.isNumeric(max)) {
872                                    if ((Math.round(num * 100000) < Math.round(min * 100000)) || (Math.round(max * 100000) < Math.round(num * 100000))) {
873                                        errors.push(jQuery(this).attr('id'));
874                                    }
875                                } else if (jQuery.isNumeric(max)) {
876                                    if (Math.round(max * 100000) < Math.round(num * 100000)) {
877                                        errors.push(jQuery(this).attr('id'));
878                                    }
879                                } else if (jQuery.isNumeric(min)) {
880                                    if (Math.round(num * 100000) < Math.round(min * 100000)) {
881                                        errors.push(jQuery(this).attr('id'));
882                                    }
883                                }
884                            } else {
885                                errors.push(jQuery(this).attr('id'));
886                            }
887                        }
888                    }
889
890                    // CHECK IF FIELD IS AN EMAIL AND FORMATTED CORRECTLY
891                    if (fieldType === 'email'){
892                        var emailVal = jQuery(this).val();
893                        // pattern taken form https://emailregex.com/
894                        var emailReg = /^(([^<>()\[\]\\.,;:\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,}))$/;
895                        if ( emailVal !== '' ) {
896                            if(!emailReg.test( emailVal ) ){
897                                errors.push(jQuery(this).attr('id'));
898                            }
899                        }
900                    }
901
902                    // SET IF FIELD IS REQUIRED
903                    var required = false;
904                    if(isDisabled !== true && isVisible === true && (curInput.attr('required') || curInput.attr('aria-required') || fieldWrapper.hasClass('gfield_contains_required') && checkOrRadio !== true && !curInput.parent().hasClass('address_line_2'))) {
905                        required = true;
906                    }
907
908                    if (required === true && !value || isDisabled !== true && isVisible === true && checkOrRadio === true && fieldWrapper.hasClass('gfield_contains_required') && cbOptionChecked === false) {
909                        var invalidInputId;
910
911                        // IF CHECKBOX OR RADIO INPUT
912                        if (fieldType === 'checkbox' || fieldType === 'radio') {
913                            var cbIsValid;
914
915                            // SET INPUT GROUP WRAPPER
916                            var cbInputWrapper = curInput.parent().parent().parent().parent();
917
918                            // GROUP OPTION INPUTS
919                            var cbInputs = cbInputWrapper.find('input');
920
921                            // LOOP OPTIONS
922                            cbInputs.each(function () {
923                                cbIsValid = false;
924
925                                if (jQuery(this).prop('checked') === true) {
926                                    cbIsValid = true;
927
928                                    return false;
929                                }
930                            });
931
932                            // PUSH ID TO ERROR ARRAY IF INVALID
933                            if (cbIsValid !== true) {
934                                invalidInputId = cbInputWrapper.attr('id');
935                            }
936                        } else {
937                            invalidInputId = curInput.attr('id');
938                        }
939                        if (invalidInputId && errors.indexOf(invalidInputId) === -1) {
940                            errors.push(invalidInputId);
941                        }
942                    }
943                }
944
945                if (errors.length > 0) {
946                    // SET FIRST INVALID FIELD
947                    var firstErrorId = errors[0];
948                    var firstInvalidInput = jQuery('#' + firstErrorId);
949                    var errorPage = firstInvalidInput.closest('.gform_page');
950                    var errorPageIdArr = errorPage.attr('id').split('_');
951                    var firstInvalidInputWrapper = firstInvalidInput.closest('.gfield');
952
953                    // ADD ERROR MESSAGE TO TOP OF FORM
954                    form.find('.gform_body').before('<div class="validation_error">There was a problem with your submission. Errors have been highlighted below.</div>');
955
956                    // LOOP INVALID INPUT ID'S
957                    for (i = 0; i < errors.length; i++) {
958                        var invalidInput = jQuery('#' + errors[i]);
959                        var invalidFieldType = invalidInput.attr('type');
960
961                        // ADD ERROR CLASS & NOTICE MESSAGE
962                        var invalidInputWrapper;
963                        if (invalidFieldType === 'checkbox' || invalidFieldType === 'radio') {
964                            invalidInputWrapper = invalidInput.parent().parent().parent().parent();
965                            invalidInputWrapper.addClass('gfield_error').append('<div class="gfield_description validation_message">This field is required.</div>');
966                        } else {
967                            invalidInputWrapper = invalidInput.closest('li');
968                            invalidInputWrapper.addClass('gfield_error').append('<div class="gfield_description validation_message">This field is required.</div>');
969                        }
970                    }
971
972                    if(errorPage.attr('id') !== curPage.attr('id')) {
973                        curPage.fadeOut().promise().done(function() {
974                            errorPage.fadeIn();
975
976                            // UPDATE LINKS
977                            jQuery.each(stepLinks, function () {
978                                if (jQuery(this).attr('id') === 'gf_step_' + errorPageIdArr[2] + '_' + errorPageIdArr[3]) {
979                                    jQuery(this).addClass('gf_step_active gpmpn-step-current');
980                                } else {
981                                    jQuery(this).removeClass('gf_step_active gpmpn-step-current');
982                                }
983                            });
984                        });
985                    }
986
987                    // SCROLL TO FIRST INVALID FIELD
988                    jQuery('html, body').animate({
989                        scrollTop: firstInvalidInputWrapper.offset().top
990                    }, 500, 'linear');
991                } else {
992                    // FADE OUT CURRENT PAGE
993                    curPage.fadeOut().promise().done(function () {
994                        // FADE IN SELECTED PAGE
995                        jQuery('#' + pageId).fadeIn();
996
997                        // UPDATE LINKS
998                        jQuery.each(stepLinks, function () {
999                            if (jQuery(this).attr('id') === stepId) {
1000                                jQuery(this).addClass('gf_step_active gpmpn-step-current');
1001                            } else {
1002                                jQuery(this).removeClass('gf_step_active gpmpn-step-current');
1003                            }
1004                        });
1005                    });
1006                }
1007            } else {
1008                // FADE OUT CURRENT PAGE
1009                curPage.fadeOut().promise().done(function () {
1010                    // FADE IN SELECTED PAGE
1011                    jQuery('#' + pageId).fadeIn();
1012                    // UPDATE LINKS
1013                    jQuery.each(stepLinks, function () {
1014                        if (jQuery(this).attr('id') === stepId) {
1015                            jQuery(this).addClass('gf_step_active gpmpn-step-current');
1016                        } else {
1017                            jQuery(this).removeClass('gf_step_active gpmpn-step-current');
1018                        }
1019                    });
1020                });
1021            }
1022        }
1023    });
1024
1025    /*** MULTI-FILE UPLOAD ***/
1026    jQuery(document).on('change', '.cm-hipaa-multifile-upload-input',function (){
1027        jQuery('body .cm-hipaa-multifile-errors').remove();
1028        var settings = jQuery(this).data('settings');
1029        var uploadPath = jQuery(this).val();
1030        var uploadExtension = uploadPath.substring(uploadPath.lastIndexOf(".")+1, uploadPath.length).toLowerCase();  // ADDED TOLOWERCASE
1031        //Default values
1032        var uploadValidationErrors = [];
1033        var maxFileSize = "";
1034        var isMaxFileSize = true;
1035        var isAllowedExtention = null;
1036        var isDisallowedExtention = null;
1037
1038        if(settings.maxfilesize){
1039            maxFileSize = settings.maxfilesize;
1040            var fileSize = jQuery(this).prop('files')[0].size;
1041            //maxFileSize = maxFileSize.substring(0,maxFileSize.length - 1); //No Longer needed
1042            if(fileSize > parseInt(maxFileSize)){
1043                uploadValidationErrors.push("<div class='cm-hipaa-field-error cm-hipaa-multifile-errors'>This file is too large.</div>");
1044            }
1045        }
1046
1047        var allowedExtentions = "";
1048        if(settings.allowedextensions){
1049            allowedExtentions = settings.allowedextensions;
1050        }
1051
1052        var disallowedExtentions = "";
1053        if(settings.disallowedextentions){
1054            disallowedExtentions = settings.disallowedextentions;
1055        }
1056
1057        if(allowedExtentions !== "*"){
1058            var allowedExtentionsArray = allowedExtentions.split(',');
1059            //if extention not found in array then error is given
1060            if(!allowedExtentionsArray.includes(uploadExtension)){
1061                uploadValidationErrors.push("<div class='cm-hipaa-field-error cm-hipaa-multifile-errors'>This file type is not allowed.</div>")
1062            }
1063        }else{
1064            var disallowedExtentionsArray = disallowedExtentions.split(',');
1065            //if extention is found in array then error is given
1066            if(disallowedExtentionsArray.includes(uploadExtension)){
1067                uploadValidationErrors.push("<div class='cm-hipaa-field-error cm-hipaa-multifile-errors'>This file type is not allowed.</div>")
1068            }
1069        }
1070
1071        var maxFiles = 0;
1072        if(settings.maxfiles){
1073            maxFiles = settings.maxfiles;
1074        }
1075
1076        if(uploadValidationErrors.length){
1077            jQuery(this).val("");
1078            for (i = 0; i < uploadValidationErrors.length; i++) {
1079                jQuery(this).before(uploadValidationErrors[i]);
1080            }
1081        }
1082    })
1083
1084    /*** GRAVITY MULTI-FILE UPLOAD ADD NEW FIELD ***/
1085    jQuery(document).on('click', '.cm-hipaa-gf-multifile-upload-button', function() {
1086        var fileUploadInputCount = jQuery(this).parent().find('input[type="file"]').length+1;
1087        var fieldId = jQuery(this).parent().parent().attr('id');
1088        var fileInputId = fieldId.replace('field', 'input');
1089        var fileInputEnd = fieldId.split('_').pop();
1090        var fileInputName = 'input_' + fileInputEnd;
1091        var fileInputDescribed = fieldId.replace('field', 'extensions_message');
1092        var gfFileInputSettings = JSON.stringify(jQuery('#'+fileInputId).data('settings'));
1093        var gfAcceptAttr = jQuery('#'+fileInputId).attr('accept');
1094        jQuery(this).before('<div class="multi-file-input-spacer"></div><input name="' + fileInputName + '_' + fileUploadInputCount + '" id="' + fileInputId + '_' + fileUploadInputCount + '" type="file" class="medium cm-hipaa-multifile-upload-input" data-settings=' + gfFileInputSettings + ' accept="'+gfAcceptAttr+'" aria-describedby="' + fileInputDescribed + '"><div class="cm-hipaa-gf-delete-file"><i class="material-icons">delete_forever</i></div>');
1095        gfAddAnotherFileBtn(fileInputId);
1096    });
1097
1098    /*** GRAVITY HANDLE MULTI-FILE ADD ANOTHER FILE BUTTON ***/
1099    function gfAddAnotherFileBtn(assocdInputId){
1100        var fileInputId = jQuery('#'+assocdInputId);
1101        var count = 0;
1102        count = fileInputId.parent().find('input[type="file"]').length;
1103        var fileInputSetting = fileInputId.data('settings');
1104        var max = parseInt(fileInputSetting.maxfiles);
1105        var addAnotherBtn = jQuery('#assocd_id_'+assocdInputId);
1106        var btnFound = false;
1107        if(addAnotherBtn.length > 0){
1108            btnFound = true;
1109        }
1110        if((!btnFound && max === 0) || (!btnFound && max > count)){
1111            fileInputId.parent().find('span.gform_fileupload_rules').before('<div id="assocd_id_'+ assocd
1111InputId +'" class="cm-hipaa-gf-multifile-upload-button">Add Another File</div>')
1112        }else if(btnFound && max <= count && max !== 0){
1113            addAnotherBtn.remove();
1114        }
1115    }
1116
1117    /*** CALDERA MULTI-FILE UPLOAD ADD NEW FIELD ***/
1118    jQuery(document).on('click', '.cm-hipaa-cf-multifile-upload-button', function() {
1119        var fileUploadInputCount = 0;
1120        fileUploadInputCount = jQuery(this).parent().find('input[type="file"]').length+1;
1121
1122        //var fieldId = jQuery(this).parent().attr('data-field-wrapper');
1123        var fieldId = jQuery(this).attr('id').replace('assocd_id_','');
1124        var firstFileUploadInput = jQuery('#'+fieldId+'_1');
1125        var cfFileInputSettings = firstFileUploadInput.data('settings');
1126        var cfAcceptAttr = firstFileUploadInput.attr('accept');
1127
1128        jQuery(this).before('<div class="multi-file-input-spacer"></div><div class="file-prevent-overflow"><div id="' + fieldId + '_' + fileUploadInputCount + '_file_list" class="cf-multi-uploader-list"></div><input type="file" data-settings=' + cfFileInputSettings + ' accept="'+cfAcceptAttr+'" name="' + fieldId + '_' + fileUploadInputCount + '" value="" data-field="' + fieldId + '" class="" id="' + fieldId + '_' + fileUploadInputCount + '" aria-labelledby="' + fieldId + 'Label"><input type="hidden" name="' + fieldId + '"></div><div class="cm-hipaa-cf-delete-file"><i class="material-icons">delete_forever</i></div>');
1129    });
1130
1131    /*** GRAVITY MULTI-FILE DELETE ***/
1132    jQuery(document).on('click', '.cm-hipaa-gf-delete-file', function() {
1133        var fileInputId = jQuery(this).parent().find('input[type="file"]').first().attr('id')
1134        jQuery(this).prev().prev().remove();
1135        jQuery(this).prev().remove();
1136        jQuery(this).remove();
1137        gfAddAnotherFileBtn(fileInputId);
1138    });
1139
1140    /*** CALDERA MULTI-FILE DELETE ***/
1141    jQuery(document).on('click', '.cm-hipaa-cf-delete-file', function() {
1142        jQuery(this).prev().prev().remove();
1143        jQuery(this).prev().remove();
1144        jQuery(this).remove();
1145    });
1146
1147    /*** TRIGGER CLICK EVENT ON ENTER/RETURN KEY CALDERA***/
1148    jQuery(document).on('keydown', 'form .cm-hipaa-forms-submit.caldera.active', function(e){
1149        if(e.keyCode===13){
1150            jQuery('form .cm-hipaa-forms-submit.caldera.active').trigger('click');
1151        }
1152    });
1153
1154    /*** TRIGGER CLICK EVENT ON ENTER/RETURN KEY GRAVITY***/
1155    jQuery(document).on('keyup', 'form .cm-hipaa-forms-submit.gravity.active', function(e){
1156        if(e.keyCode===13){
1157            jQuery('body form .cm-hipaa-forms-submit.gravity.active').trigger('click');
1158        }
1159    });
1160
1161    /*** SUBMIT HIPAA ENABLED CALDERA FORM ***/
1162    jQuery(document).on('click', 'form .cm-hipaa-forms-submit.caldera.active', function(e){
1163        var submitButton = jQuery(this);
1164        var form = jQuery(this).parents('form:first');
1165        var formHtml = form.html();
1166        var noticeEle = form.find('.cm-hipaa-notice');
1167        var formMainId = form.attr('id');
1168        var formId = form.attr('data-form-id');
1169        if(!formId) {
1170            formId = formMainId;
1171        }
1172
1173        // REMOVE ACTIVE CLASS FROM SUBMIT BUTTON TO PREVENT RE-SUBMITTING
1174        submitButton.removeClass('active').addClass('inactive');
1175
1176        var calderaEnabledForms = JSON.parse(cmHipaaScript.calderaEnabledForms); // DEPRECATED
1177        formIds = [];
1178
1179        // LOOP CALDERA FORMS AND PUSH IDS TO ARRAY - DEPRECATED
1180        for(var i = 0; i < calderaEnabledForms.length; i++){
1181            if(calderaEnabledForms[i]) {
1182                formIds.push(calderaEnabledForms[i]);
1183            }
1184        }
1185
1186        var enabledFormsSettings;
1187        if(cmHipaaScript.enabledFormsSettings) {
1188            enabledFormsSettings = JSON.parse(cmHipaaScript.enabledFormsSettings); // NEW JSON OBJECT ARRAY
1189        }
1190
1191
1192        // CHECK IF FORM OBJECT EXISTS IN ARRAY - NEW FORMS SETTINGS JSON OBJECT ARRAY METHOD
1193        var formFound = false;
1194        var successHandler;
1195        var successMessage;
1196        var successHideForm;
1197        var successRedirect;
1198        var successCallback;
1199        var successCallbackParams;
1200        var selectedUserSlug = '';
1201        var showSignature;
1202        var notificationOption = '';
1203
1204        if(cmHipaaScript.enabledFormsSettings) {
1205            enabledFormsSettings.some(function (el) {
1206                if (el.id === formId && el.enabled === 'yes') {
1207                    formFound = true;
1208                    successHandler = el.success_handler;
1209                    successMessage = el.success_message;
1210                    successHideForm = el.success_hide_form;
1211                    successRedirect = el.success_redirect;
1212                    successCallback = el.success_callback;
1213                    successCallbackParams = el.success_callback_params;
1214                    selectedUserSlug = el.selected_user_slug;
1215                    showSignature = el.show_signature;
1216                    notificationOption = el.notification_option;
1217                }
1218            });
1219        }
1220
1221        // SET SUCCESS MESSAGE IF NOT SET
1222        if(!successMessage) {
1223            successMessage = 'Thank you, your form has been encrypted to protect your privacy and submitted successfully!';
1224        }
1225
1226        // IF FORM ID IS IN ENABLED FORMS PREVENT DEFAULT SUBMIT AND SEND TO CODE MONKEYS
1227        if(jQuery.inArray(formId, formIds) !== -1 || formFound) {
1228            e.preventDefault(); //Prevent the normal submission action
1229            var defaultBorder;
1230
1231            // GET FILE INPUTS
1232            var fileInputs = form.find('input[type=file]');
1233
1234            // CLONE THE FORM AS A HIDDEN VERSION IN ORDER TO REPLACE INPUTS WITH VALUES AND FORMAT TO SAVE
1235            form.after('<div class="cm-hipaa-forms-hidden-form" style="display:none;"></div>');
1236            var hiddenFormClone = cmHipaaStripHiddenFormScripts(form.clone());
1237            hiddenFormClone.appendTo('.cm-hipaa-forms-hidden-form');
1238            var hiddenForm = jQuery('.cm-hipaa-forms-hidden-form form');
1239            var hiddenFormInputs = jQuery('.cm-hipaa-forms-hidden-form form :input');
1240
1241            // REMOVE THE UNWANTED APPENDED ITEMS AT BOTTOM OF FORM
1242            hiddenForm.find('.cm-hipaa-forms-prepend-bottom, .cmprivacy-modal, .cmprivacy-modal-overlay').remove();
1243
1244            // REMOVE STEP LINK BREADCRUMBS IF EXIST
1245            hiddenForm.find('.breadcrumb').remove();
1246
1247            // LOOP CLONED HIDDEN FORM INPUTS AND GET LABELS => VALUES & FULL HTML VERSION OF FORM
1248            var formFields = [];
1249            var validationErrors = [];
1250
1251            var inputs = jQuery('#' + formMainId + ' :input');
1252            hiddenFormInputs.each(function() {
1253                var label = form.find('label[for="' + jQuery(this).attr('id') + '"]').text().trim();
1254                var value = jQuery(this).val();
1255                var dataField = jQuery(this).attr('data-field');
1256                var fieldId = jQuery(this).attr('id');
1257                var fieldName = jQuery(this).attr('name');
1258                var fieldType = jQuery(this).attr('type');
1259                defaultBorder = jQuery(this).css('border');
1260                var required = jQuery(this).attr('required');
1261                var formGroup = jQuery(this).closest('.form-group');
1262                var checkboxParentLabel = '';
1263                var checkboxLabel = '';
1264                var radioValue = '';
1265                var checkboxValue = '';
1266                var fieldValue = '';
1267                var optionLabel = '';
1268                var optionValue = '';
1269
1270                // IGNORE INITIAL HIDDEN CALDERA FIELDS & NEXT/PREVIOUS BUTTONS
1271                if(fieldName !== '_cf_verify' && fieldName !== '_wp_http_referer' && fieldName !== '_cf_frm_id' && fieldName !== '_cf_frm_ct' && fieldName !== 'cfajax' && fieldName !== '_cf_cr_pst' && fieldType !== 'button' && !jQuery(this).hasClass('button_trigger_1') && !jQuery(this).hasClass('button_trigger_2') && fieldName !== 'pum_form_popup_id') {
1272                    if (!fieldType) {
1273                        if (jQuery(this).is('select')) {
1274                            fieldType = 'select';
1275                            var visibleSelect = form.find('#' + fieldId);
1276                            var optionText = visibleSelect.find('option:selected').text();
1277                            value = visibleSelect.val();
1278                            fieldValue = value;
1279                        } else if (jQuery(this).is('textarea')) {
1280                            fieldType = 'textarea';
1281                            var visibleTextArea = form.find('#' + fieldId);
1282                            value = visibleTextArea.attr('value');
1283                            fieldValue = value;
1284                            // TRY THE VALUE ATTR FIRST AND IF NO VALUE TRY NORMAL JQUERY VAL(), NOT SURE WHY ONE WORKS OVER THE OTHER SOMETIMES
1285                            if(!value || value === 'undefined') {
1286                                value = visibleTextArea.val();
1287                                fieldValue = value;
1288                            }
1289                        }
1290                    }
1291
1292                    // GET REQUIRED FIELDS THAT DO NOT HAVE A VALUE
1293                    if (required && !value && form.find('#' + fieldId).is(':visible') || (fieldType === 'checkbox' || fieldType === 'radio') && (required || jQuery(this).attr('data-parsley-required') === 'true') && jQuery(this).prop('checked') === false && form.find('#' + fieldId).is(':visible')) {
1294                        var errorExists;
1295
1296                        if(fieldType === 'checkbox' || fieldType === 'radio') {
1297                            var optionsGroup;
1298                            var visibleOptionsGroup;
1299                            if(fieldType === 'checkbox') {
1300                                optionsGroup = jQuery(this).data('parsley-group');
1301                                visibleOptionsGroup = form.find('input[data-parsley-group="' + optionsGroup + '"]');
1302                            } else if(fieldType === 'radio') {
1303                                optionsGroup = jQuery(this).data('radio-field');
1304                                visibleOptionsGroup = form.find('input[data-radio-field="' + optionsGroup + '"]');
1305                            }
1306                            var cbIgnore;
1307
1308                            visibleOptionsGroup.each(function() {
1309                                if(jQuery(this).prop('checked') === true) {
1310                                    cbIgnore = true;
1311
1312                                    return false;
1313                                }
1314                            });
1315
1316                            if(validationErrors.length > 0) {
1317                                validationErrors.some(function(el) {
1318                                    if(el.fieldId === fieldId || el.fieldGroup === optionsGroup) {
1319                                        errorExists = true;
1320                                    }
1321                                });
1322                            }
1323
1324                            if(!errorExists && !cbIgnore) {
1325                                validationErrors.push({
1326                                    'fieldId': fieldId,
1327                                    'label': form.find('label[for="' + optionsGroup + '"]').text(),
1328                                    'fieldType': fieldType,
1329                                    'fieldGroup': optionsGroup
1330                                });
1331                            }
1332                        } else {
1333                            validationErrors.push({
1334                                'fieldId': fieldId,
1335                                'label': form.find('label[for="' + jQuery(this).attr('id') + '"]').text(),
1336                                'fieldType': fieldType,
1337                                'fieldGroup': ''
1338                            });
1339                        }
1340                    }
1341
1342                    // SET CHECKBOX OR RADIO FIELD LABEL AND INPUT LABEL
1343                    if (fieldType === 'checkbox' || fieldType === 'radio') {
1344                        if (jQuery(this).prop('checked') === true) {
1345                            checkboxLabel = jQuery(this).parent().text().trim();
1346
1347                            if(jQuery(this).hasClass('cm-hipaa-forms-privacy-agree')) {
1348                                label = 'Privacy Agreement';
1349                            } else {
1350                                label = jQuery(this).parent().parent().parent().find('.control-label').text().trim();
1351
1352                                if(!label) {
1353                                    label = jQuery(this).parent().parent().parent().parent().find('.control-label').text().trim();
1354
1355                                    if(!label) {
1356                                        label = checkboxLabel;
1357                                    }
1358                                }
1359                            }
1360
1361                            checkboxParentLabel = label;
1362                            optionLabel = checkboxLabel;
1363                            optionValue = value;
1364                        }
1365                    }
1366
1367                    // REPLACE HIDDEN HTML VERSION INPUTS WITH VALUES
1368                    if (fieldType === 'select') {
1369                        jQuery(this).replaceWith(optionText);
1370                    } else if (fieldType === 'checkbox') {
1371                        // SET CHECKBOX VALUE IF DIFFERENT THAN LABEL
1372                        if(value !== checkboxLabel) {
1373                            checkboxValue = value;
1374                        }
1375
1376                        if (jQuery(this).prop('checked') === true) {
1377                            // SET CHECKED CHECKBOX IMAGE AND VALUE
1378                            value = '<span class="cm-hipaa-forms-checkbox-value cm-hipaa-forms-checkbox-checked" style="background: #f7f5a091;"><img src="https://www.hipaaforms.online/api-assets/checkbox.png" alt="Checked" style="height: 16px; padding-right: 5px; vertical-align: middle;" />' + checkboxValue + '</span>';
1379                            jQuery(this).parent().addClass('cm-hipaa-forms-checkbox-checked-wrapper');
1380                            if(checkboxParentLabel) {
1381                                fieldValue = 'checked';
1382                            }
1383                        } else {
1384                            // SET UNCHECKED CHECKBOX IMAGE AND VALUE
1385                            value = '<span class="cm-hipaa-forms-checkbox-value  cm-hipaa-forms-checkbox-not-checked"><img src="https://www.hipaaforms.online/api-assets/checkbox-unchecked.png" alt="Not Checked" style="height: 16px; padding-right: 5px; vertical-align: middle;" /></span>';
1386                            jQuery(this).parent().addClass('cm-hipaa-forms-checkbox-not-checked-wrapper');
1387                        }
1388                        jQuery(this).replaceWith(value);
1389                    } else if (fieldType === 'radio') {
1390                        // SET RADIO VALUE IF DIFFERENT THAN LABEL
1391                        if (value !== checkboxLabel) {
1392                            radioValue = value;
1393                        }
1394                        if (jQuery(this).prop('checked') === true) {
1395                            // SET CHECKED RADIO BUTTON IMAGE AND VALUE
1396                            value = '<span class="cm-hipaa-forms-radio-value cm-hipaa-forms-radio-checked" style="background: #f7f5a091;"><img src="https://www.hipaaforms.online/api-assets/radio-checked.png" alt="Selected" style="height: 16px; padding-right: 5px; vertical-align: middle;" />' + radioValue + '</span>';
1397                            jQuery(this).parent().addClass('cm-hipaa-forms-radio-checked-wrapper');
1398                            if (checkboxParentLabel) {
1399                                fieldValue = 'checked';
1400                            }
1401                        } else {
1402                            // SET UNCHECKED RADIO BUTTON IMAGE AND VALUE
1403                            value = '<span class="cm-hipaa-forms-radio-value cm-hipaa-forms-radio-not-checked"><img src="https://www.hipaaforms.online/api-assets/radio-unchecked.png" alt="Not Selected" style="height: 16px; padding-right: 5px; vertical-align: middle;" /></span>';
1404                            jQuery(this).parent().addClass('cm-hipaa-forms-radio-not-checked-wrapper');
1405                        }
1406                        jQuery(this).replaceWith(value);
1407                    } else if(fieldType === 'hidden') {
1408                        // NEED TO CREATE A WRAPPING ELEMENT AND PASS ATTRIBUTES FROM INPUT TO WRAPPER ELE
1409                        jQuery(this).replaceWith('<div data-field="' + jQuery(this).attr('data-field') + '" class="form-group ' + jQuery(this).attr('class') + '" id="' + jQuery(this).attr('id') + '">' + value + '</div>');
1410                    } else {
1411                        fieldValue = value;
1412                        jQuery(this).replaceWith(value);
1413                    }
1414
1415                    // ADD CUSTOM CLASS TO IDENTIFY IF FIELD VALUE IS EMPTY OR NOT
1416                    if(formGroup.hasClass('cm_hipaa_forms_field_not_empty') === false && (!fieldValue || fieldValue.length === 0)) {
1417                        formGroup.addClass('cm_hipaa_forms_field_empty');
1418                    } else {
1419                        formGroup.removeClass('cm_hipaa_forms_field_empty');
1420                        formGroup.addClass('cm_hipaa_forms_field_not_empty');
1421                    }
1422
1423
1424                    if (label && fieldValue) {
1425                        // IF LABEL EXISTS PUSH TO FIELDS ARRAY
1426                        formFields.push({
1427                            'label': label,
1428                            'option_label': optionLabel,
1429                            'option_value': optionValue,
1430                            'value': fieldValue,
1431                            'data_field': dataField,
1432                            'field_id': fieldId,
1433                            'field_type': fieldType,
1434                            'option_text': optionText
1435                        });
1436                    }
1437                }
1438            });
1439
1440            // GET SIGNATURE SVG BASE64 DATA
1441            var signatureEle = form.find('.cm-hipaa-form-signature');
1442            var datapair = signatureEle.jSignature("getData", "svgbase64");
1443            var signature;
1444            if(datapair) {
1445                signature = "data:" + datapair[0] + "," + datapair[1];
1446
1447                formFields.push({
1448                    'label': 'Signature',
1449                    'option_label': 'data:',
1450                    'option_value': datapair[0],
1451                    'value': datapair[1],
1452                    'data_field': '',
1453                    'field_id': '',
1454                    'field_type': 'signature',
1455                    'option_text': ''
1456                });
1457            }
1458
1459            // SET PRIVACY AGREEMENT ELEMENT
1460            var privacyAgreementEle = form.find('.cm-hipaa-forms-privacy-agree');
1461
1462            // RESET ERRORS
1463            //inputs.css('border', defaultBorder);
1464            jQuery('.form-group').removeClass('has-error');
1465            jQuery('input, select, textarea').removeAttr('aria-invalid').removeClass('parsley-error');
1466            jQuery('.caldera_ajax_error_block').remove();
1467            privacyAgreementEle.parent().css('border', '0');
1468            if(signatureEle) {
1469                signatureEle.find('.jSignature').css('border', '0');
1470            }
1471            noticeEle.html('');
1472
1473            // MULTI-PAGE FORM RENDERING
1474            var calderaFormPages = hiddenForm.find('[data-formpage]');
1475            calderaFormPages.each(function(index) {
1476                // MAKE PAGE ELEMENT VISIBLE
1477                jQuery(this).css({
1478                    'visibility': 'visible',
1479                    'display': 'block'
1480                });
1481
1482                // REMOVE BUTTONS
1483                jQuery(this).find('input[type="button"]').closest('.form-group').remove();
1484                jQuery(this).find('button').remove();
1485
1486                // APPEND PAGE BREAK TO END OF PAGE FOR MPDF IF NOT LAST ELEMENT
1487                if(index !== (calderaFormPages.length - 1)) {
1488                    jQuery(this).append('<pagebreak />');
1489                }
1490            });
1491
1492            var nonce = cmHipaaScript.nonce;
1493
1494            if(!jQuery.isEmptyObject(validationErrors) && validationErrors.length > 0) { // ADDED .LENGTH CHECK TO OBJECT TO PREVENT POTENTIAL UNDEFINED OBJ ISSUES
1495                // VALIDATE FIELDS
1496                jQuery.each(validationErrors, function(key, val) {
1497                    var invalidFieldId = val.fieldId;
1498                    var invalidFieldType = val.fieldType;
1499                    var invalidFieldGroup = val.fieldGroup;
1500                    var invalidInput = jQuery('#' + invalidFieldId);
1501                    var invalidFieldWrapper;
1502
1503                    if(invalidFieldGroup) {
1504                        invalidFieldWrapper = jQuery('#' + invalidFieldGroup + '-wrap');
1505                    } else {
1506                        invalidFieldWrapper = jQuery('#' + invalidFieldId + '-wrap');
1507                    }
1508
1509                    // ADD ERROR CLASS TO FIELD GROUP ELEMENT & INPUT
1510                    invalidFieldWrapper.addClass('has-error');
1511                    invalidInput.attr('aria-invalid', 'true').addClass('parsley-error');
1512                    jQuery('label[for="' + invalidFieldId + '"]').addClass('parsley-error');
1513
1514                    // APPEND NOTICE
1515                    invalidFieldWrapper.append('<span class="help-block caldera_ajax_error_block filled" aria-live="polite"><span class="parsley-required">This value is required.</span></span>');
1516
1517                    // UPDATE NOTICE ELEMENT
1518                    noticeEle.append('<p>' + val.label + ' is a required field!</p>');
1519                });
1520
1521                // REMOVE HIDDEN FORM
1522                jQuery('.cm-hipaa-forms-hidden-form').remove();
1523
1524                // SET FIRST INVALID FIELD DEPENDING ON IF CHECKBOX/FIELDGROUP
1525                var scrollTopEle;
1526                if(validationErrors[0].fieldGroup) {
1527                    //if(validationErrors[0].hasOwnProperty('fieldGroup')) { // CHANGED TO PREVENT POTENTIAL UNDEFINED ISSUES
1528                    scrollTopEle = '#' + validationErrors[0].fieldGroup + '-wrap';
1529                } else {
1530                    scrollTopEle = '#' + validationErrors[0].fieldId + '-wrap';
1531                }
1532
1533                // SCROLL TO FIRST INVALID FIELD
1534                jQuery('html, body').animate({
1535                    scrollTop: jQuery(scrollTopEle).offset().top
1536                }, 500, 'linear');
1537
1538                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1539                submitButton.removeClass('inactive').addClass('active');
1540            } else if(privacyAgreementEle.prop('checked') !== true) {
1541                // ENSURE THE HIPAA PRIVACY CHECKBOX IS CHECKED
1542                privacyAgreementEle.parent().css('border', '1px solid red');
1543                noticeEle.html('You must agree to the HIPAA Privacy Agreement');
1544
1545                // REMOVE HIDDEN FORM
1546                jQuery('.cm-hipaa-forms-hidden-form').remove();
1547
1548                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1549                submitButton.removeClass('inactive').addClass('active');
1550            } else if(showSignature === 'yes' && !signatureEle.find('.jSignature').hasClass('cm-valid-sig')) {
1551                // ADD RED BORDER TO SIGNATURE FIELD
1552                signatureEle.find('.jSignature').css('border', '1px solid red');
1553
1554                // UPDATE NOTICE ELEMENT
1555                noticeEle.html('You must sign the form');
1556
1557                // REMOVE HIDDEN FORM
1558                jQuery('.cm-hipaa-forms-hidden-form').remove();
1559
1560                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1561                submitButton.removeClass('inactive').addClass('active');
1562            } else {
1563                // VALIDATE ACCOUNT TO GET ENABLED ADD-ONS
1564                jQuery.ajax({
1565                    method: 'POST',
1566                    type: 'POST',
1567                    url: cmHipaaScript.ajax_url,
1568                    data: {
1569                        'action': 'cm_hipaa_validate_account',
1570                        'form_id': formId,
1571                        'form_submission': true,
1572                        'nonce': cmHipaaScript.nonce
1573                    },
1574                    success: function (data) {
1575                        // REMOVE LOADING ICON
1576                        jQuery('.cm-hipaa-forms-loading').remove();
1577                        var resultData;
1578                        try {
1579                            resultData = cmHipaaParseAjaxJson(data);
1580                        } catch (e) {
1581                            console.log(data);
1582                            noticeEle.append(data);
1583                            return false;
1584                        }
1585
1586                        if (resultData.success === 'success') {
1587                            // CHECK IF FILE UPLOAD ENABLED
1588                            var validatedAddOns = resultData.add_ons;
1589                            var validatedAddOnsArray;
1590                            if(validatedAddOns) {
1591                                validatedAddOnsArray = validatedAddOns.split(',');
1592                            }
1593                            var fileUploadEnabled = 'no';
1594                            var sessionId = resultData.session_id || '';
1595
1596                            if(Array.isArray(validatedAddOnsArray) && validatedAddOnsArray.indexOf('fileupload') !== -1) {
1597                                fileUploadEnabled = 'yes';
1598                            } else if(validatedAddOns === 'fileupload') {
1599                                fileUploadEnabled = 'yes';
1600                            }
1601
1602                            // IF FILE INPUTS EXIST & FILE UPLOAD ENABLED
1603                            if (fileInputs.length > 0 && fileUploadEnabled === 'yes') {
1604                                // SHOW LOADING BAR
1605                                noticeEle.html('<div class="cm-hipaa-forms-file-upload-status">Uploading Files...</div><div class="cm-hipaa-forms-progress-wrapper"><div class="cm-hipaa-forms-progress"><div class="cm-hipaa-forms-progress-bar"><!--    <div class="cm-hipaa-forms-progress-label">10%</div>--></div></div></div>');
1606                                cmHipaaFormsProgress();
1607                                var fileInputsLength = fileInputs.length;
1608                                var iterations = 0;
1609                                var fileKeys = [];
1610                                fileInputs.each(function (index) {
1611                                    var fileInputParentId = jQuery(this).parent().parent().attr('id');
1612                                    var fileLabel = jQuery(this).parent().parent().find('label').text();
1613                                    fileLabel = fileLabel.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '-');
1614
1615                                    // GET FILE
1616                                    var theFormFile = jQuery(this).get()[0].files[0];
1617                                    if (theFormFile) {
1618                                        var fileType = theFormFile.type;
1619                                        var fileName = theFormFile.name;
1620                                        var fieldId = jQuery(this).attr('data-field') || jQuery(this).attr('id') || fileInputParentId || '';
1621
1622                                        // GET PRESIGNED FILE UPLOAD URL
1623                                        jQuery.ajax({
1624                                            method: 'POST',
1625                                            type: 'POST',
1626                                            url: cmHipaaScript.ajax_url,
1627                                            data: {
1628                                                'action': 'cm_hipaa_get_file_upload_url',
1629                                                'file_name': fileName,
1630                                                'file_size': theFormFile.size,
1631                                                'mime_type': theFormFile.type,
1632                                                'form_id': formId,
1633                                                'field_id': fieldId,
1634                                                'session_id': sessionId,
1635                                                'nonce': cmHipaaScript.
1635nonce
1636                                            },
1637                                            success: function (data) {
1638                                                //var resultData = JSON.parse(data);
1639                                                var resultData;
1640                                                try {
1641                                                    resultData = cmHipaaParseAjaxJson(data);
1642                                                } catch (e) {
1643                                                    console.log(data);
1644                                                    noticeEle.append(data);
1645                                                    return false;
1646                                                }
1647
1648                                                var fileUploadUrl = resultData.file_upload_url;
1649                                                var fileKey = resultData.file_key;
1650                                                // PUSH FILE KEYS TO ARRAY
1651                                                fileKeys.push(fileKey);
1652                                                // UPLOAD THE FILE
1653                                                jQuery.ajax({
1654                                                    url: fileUploadUrl, // the presigned URL
1655                                                    type: 'PUT',
1656                                                    processData: false,
1657                                                    contentType: fileType,
1658                                                    //headers: {'x-amz-tagging': 'label=' + fileLabel},
1659                                                    data: theFormFile,
1660                                                    success: function () {
1661                                                        var hiddenFileUploadContainer = hiddenForm.find('#' + fileInputParentId);
1662                                                        var existingFiles = hiddenFileUploadContainer.find('.cm_hipaa_file_input'); // GET EXISTING FILES ALREADY UPLOADED IN HIDDEN FORM
1663                                                        hiddenFileUploadContainer.html(''); // CLEAR THE CONTAINER ELEMENT
1664                                                        // PREPEND LABEL TO FILE CONTAINER ELEMENT
1665                                                        hiddenFileUploadContainer.prepend('<label>' + fileLabel + '</label>');
1666                                                        jQuery.each(existingFiles, function () {
1667                                                            // APPEND EXISTING FILES ALREADY UPLOADED BACK INTO CONTAINER ELEMENT
1668                                                            hiddenFileUploadContainer.append(jQuery(this));
1669                                                        });
1670                                                        // APPEND NEW UPLOADED FILE TO CONTAINER ELEMENT
1671                                                        hiddenFileUploadContainer.append('<div class="cm_hipaa_file_input" data-file-key="' + fileKey + '">' + fileKey + '</div>');
1672                                                        iterations = iterations + 1;
1673                                                        if (iterations === fileInputsLength) {
1674                                                            // UPDATE FILE UPLOAD STATUS
1675                                                            jQuery('.cm-hipaa-forms-file-upload-status').html('Submitting Form...');
1676                                                            // SET TIMEOUT TO ENSURE INPUTS OVERWRITTEN
1677                                                            setTimeout(function () {
1678                                                                // SUBMIT FORM
1679                                                                jQuery.ajax({
1680                                                                    method: 'POST',
1681                                                                    type: 'POST',
1682                                                                    url: cmHipaaScript.ajax_url,
1683                                                                    data: {
1684                                                                        'action': 'cm_hipaa_submit_caldera_form',
1685                                                                        'formId': formId,
1686                                                                        'session_id': sessionId,
1687                                                                        'formFields': formFields,
1688                                                                        'formHtml': hiddenForm.html(),
1689                                                                        'signature': signature,
1690                                                                        'nonce': nonce,
1691                                                                        'selectedUserSlug': selectedUserSlug,
1692                                                                        'notification_option': notificationOption,
1693                                                                        'files': fileKeys.join(','),
1694                                                                        'formFound': formFound
1695                                                                    },
1696                                                                    success: function (data) {
1697                                                                        //var resultData = JSON.parse(data);
1698                                                                        var resultData;
1699                                                                        try {
1700                                                                            resultData = cmHipaaParseAjaxJson(data);
1701                                                                        } catch (e) {
1702                                                                            console.log(data);
1703                                                                            noticeEle.append(data);
1704                                                                            return false;
1705                                                                        }
1706
1707                                                                        var formError = '';
1708                                                                        if (resultData.error) {
1709                                                                            formError = resultData.error;
1710                                                                        }
1711
1712                                                                        if (resultData.success === 'success') {
1713                                                                            if (successHandler === 'message') {
1714                                                                                if(successHideForm === 'hide') {
1715                                                                                    // HIDE FORM THEN ADD SUCCESS MESSAGE
1716                                                                                    form.fadeOut().promise().done(function() {
1717                                                                                        form.after('<div class="cm-hipaa-notice cm-hidden-form-message">' + successMessage + ' ' + formError + '</div>');
1718                                                                                        jQuery('.cm
1718-hidden-form-message').fadeIn();
1719                                                                                        // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1720                                                                                        submitButton.removeClass('inactive').addClass('active');
1721                                                                                    });
1722                                                                                } else {
1723                                                                                    // DISPLAY THE SUCCESS NOTICE
1724                                                                                    noticeEle.html(successMessage + ' ' + formError);
1725                                                                                    // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1726                                                                                    submitButton.removeClass('inactive').addClass('active');
1727                                                                                }
1728                                                                            } else if (successHandler === 'redirect') {
1729                                                                                // REDIRECT TO SUCCESS PAGE
1730                                                                                window.location = successRedirect;
1731                                                                            } else if (successHandler === 'callback') {
1732                                                                                // MAKE SURE CALLBACK IS AN EXISTING FUNCTION
1733                                                                                fnExists = typeof window[successCallback] === 'function';
1734                                                                                if (fnExists) {
1735                                                                                    if (successCallbackParams) {
1736                                                                                        window[successCallback].apply(null, successCallbackParams.split(','));
1737                                                                                    } else {
1738                                                                                        window[successCallback]();
1739                                                                                    }
1740                                                                                } else {
1741                                                                                    console.log(successCallback + ' is not an existing function!');
1742                                                                                }
1743                                                                                if (successMessage) {
1744                                                                                    noticeEle.html(successMessage + ' ' + formError);
1745                                                                                } else {
1746                                                                                    // DISPLAY THE SUCCESS NOTICE
1747                                                                                    noticeEle.html('Thank y
1747ou, your form has been encrypted to protect your privacy and submitted successfully!');
1748                                                                                }
1749                                                                                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1750                                                                                submitButton.removeClass('inactive').addClass('active');
1751                                                                            } else {
1752                                                                                // DISPLAY THE SUCCESS NOTICE
1753                                                                                noticeEle.html('Thank you, your form has been encrypted to protect your privacy and submitted successfully!');
1754                                                                                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1755                                                                                submitButton.removeClass('inactive').addClass('active');
1756                                                                            }
1757                                                                            // RESET THE FORM
1758                                                                            form[0].reset();
1759                                                                            if (signature) {
1760                                                                                signatureEle.jSignature("reset");
1761                                                                            }
1762                                                                        } else {
1763                                                                            // JUST A FAIL-SAFE JUST IN CASE WE DON'T ACTUALLY GET A SUCCESS MESSAGE
1764                                                                            noticeEle.html(formError);
1765                                                                        }
1766                                                                        hiddenForm.remove();
1767                                                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
1768                                                                    },
1769                                                                    error: function (errorThrown) {
1770                                                                        console.log(errorThrown);
1771                                                                        noticeEle.html(errorThrown);
1772                                                                        hiddenForm.remove();
1773                                                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
1774                                                                    }
1775                                                                });
1776                                                            }, 1000);
1777                                                        }
1778                                                    }
1779                                                });
1780                                            },
1781                                            error: function (errorThrown) {
1782                                                console.log(errorThrown);
1783                                            }
1784                                        });
1785                                    } else {
1786                                        hiddenForm.find('#' + fileInputParentId).find('.file-prevent-overflow').html('<div class="cm_hipaa_file_input" data-file-key="">No File Attached</div>');
1787                                        iterations = iterations + 1;
1788                                        if (iterations === fileInputsLength) {
1789                                            // UPDATE FILE UPLOAD STATUS
1790                                            jQuery('.cm-hipaa-forms-file-upload-status').html('Submitting Form...');
1791                                            // SET TIMEOUT TO ENSURE INPUTS OVERWRITTEN
1792                                            setTimeout(function () {
1793                                                // SUBMIT FORM
1794                                                jQuery.ajax({
1795                                                    method: 'POST',
1796                                                    type: 'POST',
1797                                                    url: cmHipaaScript.ajax_url,
1798                                                    data: {
1799                                                        'action': 'cm_hipaa_submit_caldera_form',
1800                                                        'formId': formId,
1801                                                        'session_id': sessionId,
1802                                                        'formFields': formFields,
1803                                                        'formHtml': hiddenForm.html(),
1804                                                        'signature': signature,
1805                                                        'nonce': nonce,
1806                                                        'selectedUserSlug': selectedUserSlug,
1807                                                        'notification_option': notificationOption,
1808                                                        'files': fileKeys.join(','),
1809                                                        'formFound': formFound
1810                                                    },
1811                                                    success: function (data) {
1812                                                        //var resultData = JSON.parse(data);
1813                                                        var resultData;
1814                                                        try {
1815                                                            resultData = cmHipaaParseAjaxJson(data);
1816                                                        } catch (e) {
1817                                                            console.log(data);
1818                                                            noticeEle.append(data);
1819                                                            return false;
1820                                                        }
1821
1822                                                        var formError = '';
1823                                                        if (resultData.error) {
1824                                                            formError = resultData.error;
1825                                                        }
1826                                                        if (resultData.success === 'success') {
1827                                                            if (successHandler === 'message') {
1828                                                                if(successHideForm === 'hide') {
1829                                                                    // HIDE FORM THEN ADD SUCCESS MESSAGE
1830                                                                    form.fadeOut().promise().done(function() {
1831                                                                        form.after('<div class="cm-hipaa-notice cm-hidden-form-message">' + successMessage + ' ' + formError + '</div>');
1832                                                                        jQuery('.cm
1832-hidden-form-message').fadeIn();
1833                                                                    });
1834                                                                    // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1835                                                                    submitButton.removeClass('inactive').addClass('active');
1836                                                                } else {
1837                                                                    // DISPLAY THE SUCCESS NOTICE
1838                                                                    noticeEle.html(successMessage + ' ' + formError);
1839                                                                    // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1840                                                                    submitButton.removeClass('inactive').addClass('active');
1841                                                                }
1842                                                            } else if (successHandler === 'redirect') {
1843                                                                // REDIRECT TO SUCCESS PAGE
1844                                                                window.location = successRedirect;
1845                                                            } else if (successHandler === 'callback') {
1846                                                                // MAKE SURE CALLBACK IS AN EXISTING FUNCTION
1847                                                                fnExists = typeof window[successCallback] === 'function';
1848                                                                if (fnExists) {
1849                                                                    if (successCallbackParams) {
1850                                                                        window[successCallback].apply(null, successCallbackParams.split(','));
1851                                                                    } else {
1852                                                                        window[successCallback]();
1853                                                                    }
1854                                                                } else {
1855                                                                    console.log(successCallback + ' is not an existing function!');
1856                                                                }
1857                                                                if (successMessage) {
1858                                                                    noticeEle.html(successMessage + ' ' + formError);
1859                                                                } else {
1860                                                                    // DISPLAY THE SUCCESS NOTICE
1861                                                                    noticeEle.html('Thank y
1861ou, your form has been encrypted to protect your privacy and submitted successfully!');
1862                                                                }
1863                                                                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1864                                                                submitButton.removeClass('inactive').addClass('active');
1865                                                            } else {
1866                                                                // DISPLAY THE SUCCESS NOTICE
1867                                                                noticeEle.html('Thank you, your form has been encrypted to protect your privacy and submitted successfully!');
1868                                                                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1869                                                                submitButton.removeClass('inactive').addClass('active');
1870                                                            }
1871                                                            // RESET THE FORM
1872                                                            form[0].reset();
1873                                                            if (signature) {
1874                                                                signatureEle.jSignature("reset");
1875                                                            }
1876                                                        } else {
1877                                                            // JUST A FAIL-SAFE JUST IN CASE WE DON'T ACTUALLY GET A SUCCESS MESSAGE
1878                                                            noticeEle.html(formError);
1879                                                        }
1880                                                        hiddenForm.remove();
1881                                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
1882                                                        // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1883                                                        submitButton.removeClass('inactive').addClass('active');
1884                                                    },
1885                                                    error: function (errorThrown) {
1886                                                        console.log(errorThrown);
1887                                                        noticeEle.html(errorThrown);
1888                                                        hiddenForm.remove();
1889                                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
1890                                                        // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1891                                                        submitButton.removeClass('inactive').addClass('active');
1892                                                    }
1893                                                });
1894                                            }, 1000);
1895                                        }
1896                                    }
1897                                });
1898                            } else {
1899                                // SHOW LOADING BAR
1900                                noticeEle.html('<div class="cm-hipaa-forms-progress-wrapper"><div class="cm-hipaa-forms-progress"><div class="cm-hipaa-forms-progress-bar"><!--    <div class="cm-hipaa-forms-progress-label">10%</div>--></div></div></div>');
1901                                cmHipaaFormsProgress();
1902                                // SUBMIT FORM
1903                                jQuery.ajax({
1904                                    method: 'POST',
1905                                    type: 'POST',
1906                                    url: cmHipaaScript.ajax_url,
1907                                    data: {
1908                                        'action': 'cm_hipaa_submit_caldera_form',
1909                                        'formId': formId,
1910                                        'session_id': sessionId,
1911                                        'formFields': formFields,
1912                                        'formHtml': hiddenForm.html(),
1913                                        'signature': signature,
1914                                        'nonce': nonce,
1915                                        'selectedUserSlug': selectedUserSlug,
1916                                        'notification_option': notificationOption,
1917                                        'formFound': formFound
1918                                    },
1919                                    success: function (data) {
1920                                        var resultData;
1921                                        try {
1922                                            resultData = cmHipaaParseAjaxJson(data);
1923                                        } catch (e) {
1924                                            console.log(data);
1925                                            noticeEle.append(data);
1926                                            return false;
1927                                        }
1928
1929                                        var formError = '';
1930                                        if (resultData.error) {
1931                                            formError = resultData.error;
1932                                        }
1933                                        if (resultData.success === 'success') {
1934                                            if (successHandler === 'message') {
1935                                                if(successHideForm === 'hide') {
1936                                                    // HIDE FORM THEN ADD SUCCESS MESSAGE
1937                                                    form.fadeOut().promise().done(function() {
1938                                                        form.after('<div class="cm-hipaa-notice cm-hidden-form-message">' + successMessage + ' ' + formError + '</div>');
1939                                                        jQuery('.cm
1939-hidden-form-message').fadeIn();
1940                                                    });
1941                                                } else {
1942                                                    // DISPLAY THE SUCCESS NOTICE
1943                                                    noticeEle.html(successMessage + ' ' + formError);
1944                                                }
1945                                            } else if (successHandler === 'redirect') {
1946                                                // REDIRECT TO SUCCESS PAGE
1947                                                window.location = successRedirect;
1948                                            } else if (successHandler === 'callback') {
1949                                                // MAKE SURE CALLBACK IS AN EXISTING FUNCTION
1950                                                fnExists = typeof window[successCallback] === 'function';
1951                                                if (fnExists) {
1952                                                    if (successCallbackParams) {
1953                                                        window[successCallback].apply(null, successCallbackParams.split(','));
1954                                                    } else {
1955                                                        window[successCallback]();
1956                                                    }
1957                                                } else {
1958                                                    console.log(successCallback + ' is not an existing function!');
1959                                                }
1960                                                if (successMessage) {
1961                                                    noticeEle.html(successMessage + ' ' + formError);
1962                                                } else {
1963                                                    // DISPLAY THE SUCCESS NOTICE
1964                                                    noticeEle.html('Thank y
1964ou, your form has been encrypted to protect your privacy and submitted successfully!');
1965                                                }
1966                                                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1967                                                submitButton.removeClass('inactive').addClass('active');
1968                                            } else {
1969                                                // DISPLAY THE SUCCESS NOTICE
1970                                                noticeEle.html('Thank you, your form has been encrypted to protect your privacy and submitted successfully!');
1971                                                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1972                                                submitButton.removeClass('inactive').addClass('active');
1973                                            }
1974                                            // RESET THE FORM
1975                                            form[0].reset();
1976                                            if (signature) {
1977                                                signatureEle.jSignature("reset");
1978                                            }
1979                                        } else {
1980                                            // JUST A FAIL-SAFE JUST IN CASE WE DON'T ACTUALLY GET A SUCCESS MESSAGE
1981                                            noticeEle.html(formError);
1982                                            // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1983                                            submitButton.removeClass('inactive').addClass('active');
1984                                        }
1985                                        hiddenForm.remove();
1986                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
1987                                    },
1988                                    error: function (errorThrown) {
1989                                        console.log(errorThrown);
1990                                        noticeEle.html(errorThrown);
1991                                        hiddenForm.remove();
1992                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
1993                                        // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
1994                                        submitButton.removeClass('inactive').addClass('active');
1995                                    }
1996                                });
1997                            }
1998                        } else {
1999                            console.log('Error validating Account...');
2000                        }
2001                    },
2002                    error: function (errorThrown) {
2003                        console.log(errorThrown);
2004                    }
2005                });
2006            }
2007        }
2008    });
2009
2010    /*** SUBMIT HIPAA ENABLED GRAVITY FORM ***/
2011    jQuery(document).on('click', 'form .cm-hipaa-forms-submit.gravity.active', function(e){
2012        var gravityVersion = cmHipaaScript.gravityVersion;
2013        var submitButton = jQuery(this);
2014        var form = jQuery(this).parents('form:first');
2015        var noticeEle = form.find('.cm-hipaa-notice');
2016        var formMainId = form.attr('id');
2017        var formId = form.attr('data-form-id');
2018        var newFormat = false;
2019        var legacyMarkup = false;
2020        if(!formId) {
2021            formId = formMainId;
2022        }
2023
2024        // REMOVE ALL TAGS BEFORE CLONING FORM
2025        var rawInputs = form.find('textarea, ' +
2026            'input[type=text], ' +
2027            'input[type=textarea], ' +
2028            'input[type=email], ' +
2029            'input[type=hidden], ' +
2030            'input[type=password], ' +
2031            'input[type=search], ' +
2032            'input[type=url], ' +
2033            'input[type=month], ' +
2034            'input[type=day], ' +
2035            'input[type=year]');
2036        jQuery.each(rawInputs, function(index) {
2037            var rawValue = jQuery(this).val();
2038            if (rawValue) {
2039                var newValue = rawValue
2040                    .replaceAll('onerror', '')
2041                    .replaceAll('img', '')
2042                    .replaceAll('onload','')
2043                    .replaceAll('<','&lt;')
2044                    .replaceAll('>', '&gt;');
2045                //var sanitizedValue = removeTags(newValue);
2046                jQuery(this).val(newValue);
2047            }
2048        });
2049
2050        // CHECK IF NEW FORMAT VERSION (2.5 OR HIGHER - UPDATED 4/30/2026)
2051        var gvParts = String(gravityVersion).split('.');
2052        var gvMajor = parseInt(gvParts[0], 10) || 0;
2053        var gvMinor = parseInt(gvParts[1], 10) || 0;
2054        if (gvMajor > 2 || (gvMajor === 2 && gvMinor >= 5)) {
2055            // SET NEW FORMAT TO TRUE
2056            newFormat = true;
2057
2058            // CHECK IF LEGACY MARKUP FORM
2059            if(form.parent().hasClass('gform_legacy_markup_wrapper')) {
2060                legacyMarkup = true;
2061            }
2062        }
2063
2064        // REMOVE ACTIVE CLASS TO PREVENT RE-SUBMITTING
2065        submitButton.removeClass('active').addClass('inactive');
2066
2067        // REMOVE REQUIRED FIELD NOTIFICATION ERROR IF EXISTS
2068        jQuery('.validation_error').remove();
2069
2070        var gravityEnabledForms = JSON.parse(cmHipaaScript.gravityEnabledForms); // DEPRECATED
2071        formIds = [];
2072
2073        // LOOP GRAVITY FORMS AND PUSH IDS TO ARRAY - DEPRECATED
2074        for(var i = 0; i < gravityEnabledForms.length; i++){
2075            if(gravityEnabledForms[i]) {
2076                formIds.push('gform_' + gravityEnabledForms[i]);
2077            }
2078        }
2079
2080        var enabledFormsSettings;
2081        if(cmHipaaScript.enabledFormsSettings) {
2082            enabledFormsSettings = JSON.parse(cmHipaaScript.enabledFormsSettings); // NEW JSON OBJECT ARRAY
2083        }
2084
2085        // CHECK IF FORM OBJECT EXISTS IN ARRAY - NEW FORMS SETTINGS JSON OBJECT ARRAY METHOD
2086        var formFound;
2087        var successHandler;
2088        var successMessage;
2089        var successHideForm;
2090        var successRedirect;
2091        var successCallback;
2092        var successCallbackParams;
2093        var selectedUserSlug = '';
2094        var showSignature;
2095        var notificationOption = '';
2096
2097        if(cmHipaaScript.enabledFormsSettings) {
2098            enabledFormsSettings.some(function (el) {
2099                if (el.form_builder === 'gravity' && 'gform_' + el.id === formId && el.enabled === 'yes') {
2100                    formFound = true;
2101                    successHandler = el.success_handler;
2102                    successMessage = el.success_message;
2103                    successHideForm = el.success_hide_form;
2104                    successRedirect = el.success_redirect;
2105                    successCallback = el.success_callback;
2106                    successCallbackParams = el.success_callback_params;
2107                    selectedUserSlug = el.selected_user_slug;
2108                    showSignature = el.show_signature;
2109                    notificationOption = el.notification_option;
2110                }
2111            });
2112        }
2113
2114        // SET SUCCESS MESSAGE IF NOT SET
2115        if(!successMessage) {
2116            successMessage = 'Thank you, your form has been encrypted to protect your privacy and submitted successfully!';
2117        }
2118
2119        // IF FORM ID IS IN ENABLED FORMS PREVENT DEFAULT SUBMIT AND SEND TO CODE MONKEYS
2120        if(jQuery.inArray(formId, formIds) !== -1 || formFound) {
2121            e.preventDefault(); //Prevent the normal submission action
2122
2123            var location;
2124            var locationEmail;
2125            var firstName;
2126            var lastName;
2127            var email;
2128            var phone;
2129            var selectedUser;
2130            var defaultBorder;
2131
2132            // CHECK IF PAGINATED
2133            let isPaginated = false;
2134            if(jQuery('.gform_page')[0]) {
2135                isPaginated = true;
2136            }
2137
2138            // GET FILE INPUTS
2139            var fileInputs = form.find('input[type=file]');
2140
2141            // CLONE THE FORM AS A HIDDEN VERSION IN ORDER TO REPLACE INPUTS WITH VALUES AND FORMAT TO SAVE
2142            form.after('<div class="cm-hipaa-forms-hidden-form" style="display:none;"></div>'); // ADD HIDDEN EMPTY DIV ELEMENT TO CLONE FORM TO
2143            var hiddenFormClone = cmHipaaStripHiddenFormScripts(form.clone()); // REMOVE SCRIPT NODES BEFORE THE CLONE IS ATTACHED OR STORED
2144            hiddenFormClone.appendTo('.cm-hipaa-forms-hidden-form'); // CLONE FORM TO APPENDED HIDDEN EMPTY DIV ELEMENT
2145            var hiddenForm = jQuery('.cm-hipaa-forms-hidden-form form'); // SET HIDDEN FORM VARIABLE
2146            var hiddenFormInputs = jQuery('.cm-hipaa-forms-hidden-form form :input'); // SET INPUTS VARIABLE FROM HIDDEN FORM
2147
2148            // IF GRAVITY 2.5+ ADD GFORM_WRAPPER GRAVITY-THEME CLASS ELEMENT FOR COLUMN STYLES TO WORK
2149            if(newFormat === true && legacyMarkup === false) {
2150                hiddenForm.find('.gform_body').addClass('gform_wrapper gravity-theme');
2151            }
2152
2153            // REMOVE THE UNWANTED APPENDED ITEMS AT BOTTOM OF FORM
2154            hiddenForm.find('.cm-hipaa-forms-prepend-bottom, .cmprivacy-modal, .cmprivacy-modal-overlay').remove();
2155            hiddenForm.find('.gform_footer .gform_hidden').remove();
2156
2157            //add css class by dividing by number of header items
2158            hiddenForm.find('.gfield_list_container').each(function () {
2159                var headerItems = jQuery(this).find('.gfield_header_item');
2160                var headerCount = headerItems.length;
2161                //console.log(headerCount)
2162                if(headerItems.last().hasClass('gfield_header_item--icons')){
2163                    headerCount = headerCount - 1;
2164                }
2165
2166                var widthClass;
2167                switch (headerCount) {
2168                    case 1 :
2169                        widthClass = 'cm-hipaa-gfield--width-1-col';
2170                        break;
2171                    case 2 :
2172                        widthClass = 'cm-hipaa-gfield--width-2-col';
2173                        break;
2174                    case 3 :
2175                        widthClass = 'cm-hipaa-gfield--width-3-col';
2176                        break;
2177                    case 4 :
2178                        widthClass = 'cm-hipaa-gfield--width-4-col';
2179                        break;
2180                    case 5 :
2181                        widthClass = 'cm-hipaa-gfield--width-5-col';
2182                        break;
2183                    case 6 :
2184                        widthClass = 'cm-hipaa-gfield--width-6-col';
2185                        break;
2186                    case 7 :
2187                        widthClass = 'cm-hipaa-gfield--width-7-col';
2188                        break;
2189                    case 8 :
2190                        widthClass = 'cm-hipaa-gfield--width-8-col';
2191                        break;
2192                    case 9 :
2193                        widthClass = 'cm-hipaa-gfield--width-9-col'
2194                        break;
2195                    case 10 :
2196                        widthClass = 'cm-hipaa-gfield--width-10-col'
2197                        break;
2198                    default:
2199                        widthClass = '';
2200                }
2201                headerItems.each(function () {
2202                    jQuery(this).addClass(widthClass);
2203                });
2204                jQuery(this).find('.gfield_list_group_item').each(function () {
2205                    jQuery(this).removeAttr('data-label');
2206                    jQuery(this).addClass(widthClass);
2207                })
2208            })
2209
2210            // FIND DATE FIELDS
2211            var dateContainers = hiddenForm.find('.ginput_container_date');
2212
2213            // LOOP DATE FIELDS
2214            var dateInputId = '';
2215            dateContainers.each(function() {
2216                // SET MAIN INPUT ID
2217                dateInputId = jQuery(this).find('.datepicker').attr('id');
2218
2219                // REMOVE ICON
2220                jQuery(this).find('.ui-datepicker-trigger').remove();
2221
2222                // REMOVE HIDDEN INPUT WITH ICON PATH
2223                jQuery(this).find('.gform_hidden').remove();
2224            });
2225
2226            // FIND AND REMOVE HIDDEN DATEPICKER ICON INPUT IF EXISTS
2227            hiddenForm.find('.ginput_container_date').next('.gform_hidden').remove();
2228
2229            // REMOVE STEPS LINKS AT TOP OF FORM IF EXIST
2230            hiddenForm.find('.gf_page_steps').remove();
2231
2232            // REMOVE HIDDEN PAGE PROGRESSION INPUT IF EXISTS
2233            hiddenForm.find( "input[name^='gpps_page_progression_']" ).remove();
2234
2235            // REMOVE ADD/DELETE ROW ICONS IF EXIST
2236            hiddenForm.find('.add_list_item').remove();
2237            hiddenForm.find('.delete_list_item').remove();
2238
2239            // REMOVE MULTI-SELECT SELECT OPTIONS ELEMENT
2240            hiddenForm.find('.chosen-drop').remove();
2241
2242            // LOOP CLONED HIDDEN FORM INPUTS AND GET LABELS => VALUES & FULL HTML VERSION OF FORM
2243            var formFields = [];
2244            var validationErrors = [];
2245
2246            var inputs = jQuery('#' + formMainId + ' :input');
2247            hiddenFormInputs.each(function() {
2248                var fieldId = jQuery(this).attr('id');
2249                var label = form.find('label[for="' + fieldId + '"]').text().trim();
2250                var value = jQuery(this).val();
2251                var fieldSetId;
2252                var fieldName = jQuery(this).attr('name');
2253                var fieldType = jQuery(this).attr('type');
2254                var gravityClassEle = jQuery(this).closest('.gfield');
2255                var gravityClass = gravityClassEle.attr('class');
2256                defaultBorder = jQuery(this).css('border');
2257
2258                var locationSelect;
2259                var selectedUserSelect;
2260                var visibleSelect;
2261                var optionText = '';
2262                var checkboxParentLabel = '';
2263                var checkboxLabel;
2264                var radioValue = '';
2265                var checkboxValue = '';
2266                var fieldValue = '';
2267                var optionLabel = '';
2268                var optionValue = '';
2269                var checkRadioEmpty = false;
2270                var required = false;
2271
2272                // ENSURE FIELD ID IS SET, SEEMS TO BE AN ISSUE FOR LIST FIELDS - ADDED 9/15/25
2273                if(!fieldId || fieldId === '') {
2274                    const fieldIdFound = jQuery(this).closest('.gfield').attr('id');
2275
2276                    if(fieldIdFound) {
2277                        fieldId = fieldIdFound;
2278                    }
2279                }
2280
2281                // SET IF FIELD IS VISIBLE (TRUE/FALSE)
2282                var visibleFormField = form.find('#' + fieldId);
2283                var isVisible = visibleFormField.is(':visible');
2284                // FOLLOWING IS NEEDED FOR NEW GRAVITY ORBITAL THEME USING CONDITIONAL LOGIC ATTRIBUTE
2285                if(visibleFormField.attr('data-conditional-logic') === 'hidden') {
2286                    console.log('Original = ' + isVisible);
2287                    isVisible = false;
2288                    console.log('Conditional Logic = ' + isVisible);
2289                }
2290
2291                var isDisabled = jQuery(this).prop('disabled');
2292                var message = '';
2293
2294                // SET IF ADVANCED FIELD
2295                var isAdvancedField = false;
2296                var isAdvancedList = false;
2297                if(jQuery(this).closest('.ginput_container').hasClass('ginput_complex') || jQuery(this).closest('.ginput_container').hasClass('ginput_container_list')) {
2298                    isAdvancedField = true;
2299                    // SET FIELDSET ID IF NEW FORMAT & NOT LEGACY MARKUP
2300                    if(newFormat === true && legacyMarkup === false) {
2301                        fieldSetId = jQuery(this).closest('fieldset').attr('id');
2302
2303                        // SET FIELD ID OF EACH INPUT ELEMENT
2304                        let currentItem = jQuery(this);
2305                        jQuery('.gfield_list input').each(function(index) {
2306                            if(jQuery(this).attr('aria-label') === currentItem.attr('aria-label')) {
2307                                fieldId = fieldSetId + '_' + index;
2308                                return false;
2309                            }
2310                        });
2311
2312                        // SET IF ADVANCED FIELD IS VISIBLE
2313                        let visibleFormFieldSet = form.find('#' + fieldSetId);
2314                        isVisible = visibleFormFieldSet.is(':visible');
2315                        // FOLLOWING IS NEEDED FOR NEW GRAVITY ORBITAL THEME USING CONDITIONAL LOGIC ATTRIBUTE
2316                        if(visibleFormFieldSet.attr('data-conditional-logic') === 'hidden') {
2317                            isVisible = false;
2318                        }
2319                    }
2320
2321                    // IF ADVANCED LIST ITEM
2322                    if(jQuery(this).closest('.ginput_container').hasClass('ginput_container_list')) {
2323                        isAdvancedList = true;
2324
2325                        // TODO: SET FIELD ID OF EACH INPUT ELEMENT ON LEGACY MARKUP (MAYBE IMPOSSIBLE)
2326                    }
2327                }
2328
2329                // IGNORE GRAVITY SPECIFIC HIDDEN FIELDS NOT NEEDED TO SHOW ON FORM
2330                if(fieldName !== 'is_submit_10' && fieldName !== 'gform_submit' && fieldName !== 'gform_unique_id' && fieldName !== 'state_10' && fieldName !== 'gform_target_page_number_10' && fieldName !== 'gform_source_page_number_10' && fieldName !== 'gform_field_values' && !jQuery(this).hasClass('gforms-pum') && !(jQuery(this).hasClass('gform_hidden') && jQuery(this).parent().hasClass('ginput_container_
2330consent'))) {
2331                    // TODO: ADDING THIS TO THE END OF THE ABOVE IF STATEMENT BREAKS ADVANCED ADDRESS FIELDS ON >2.5  && !jQuery(this).hasClass('gform_hidden')
2332                    // TODO: ABOVE WAS ADDED TO TRY AND REMOVE REDUNDANT LABEL/VALUE FOR "I AGREE" CHECKBOX FIELD, NEED TO TRY AND CHECK PARENT ELE FOR CLASS GINPUT_CONTAINER_CONSENT FIRST
2333
2334                    // GET REQUIRED GRAVITY FIELDS
2335                    if (gravityClassEle.hasClass('hipaa_forms_office_location')) {
2336                        // SET LOCATION VALUES
2337                        locationSelect = form.find('#' + fieldId);
2338                        location = locationSelect.find('option:selected').text();
2339                        locationEmail = locationSelect.val();
2340                    } else if (gravityClassEle.hasClass('hipaa_forms_first_name') && jQuery(this).val()) {
2341                        firstName = jQuery(this).val();
2342                    } else if (gravityClassEle.hasClass('hipaa_forms_last_name') && jQuery(this).val()) {
2343                        lastName = jQuery(this).val();
2344                    } else if (gravityClassEle.hasClass('hipaa_forms_name')) {
2345                        if (jQuery(this).parent().hasClass('name_first') && jQuery(this).val()) {
2346                            firstName = jQuery(this).val();
2347                        } else if (jQuery(this).parent().hasClass('name_last') && jQuery(this).val()) {
2348                            lastName = jQuery(this).val();
2349                        }
2350                    } else if (gravityClassEle.hasClass('hipaa_forms_email')) {
2351                        email = jQuery(this).val();
2352                    } else if (gravityClassEle.hasClass('hipaa_forms_phone')) {
2353                        phone = jQuery(this).val();
2354                    } else if (selectedUserSlug && gravityClassEle.hasClass(selectedUserSlug)) {
2355                        selectedUserSelect = form.find('#' + fieldId);
2356                        selectedUser = selectedUserSelect.val();
2357                    }
2358
2359                    if (!fieldType) {
2360                        if (jQuery(this).is('select')) {
2361                            fieldType = 'select';
2362                            visibleSelect = form.find('#' + fieldId);
2363                            optionText = visibleSelect.find('option:selected').text();
2364                            value = visibleSelect.val();
2365                            fieldValue = value;
2366                        } else if (jQuery(this).is('textarea')) {
2367                            fieldType = 'textarea';
2368                            var visibleTextArea = form.find('#' + fieldId);
2369                            value = visibleTextArea.attr('value');
2370                            fieldValue = value;
2371                            // TRY THE VALUE ATTR FIRST AND IF NO VALUE TRY NORMAL JQUERY VAL(), NOT SURE WHY ONE WORKS OVER THE OTHER SOMETIMES
2372                            if (!value || value === 'undefined') {
2373                                value = visibleTextArea.val();
2374                                fieldValue = value;
2375                            }
2376                        }
2377                    }
2378                    // IF CHECKBOX OR RADIO SET OPTIONS
2379                    var cbOptionsWrapper;
2380                    var checkOrRadio = false;
2381                    var cbOptionChecked;
2382                    if (fieldType === 'checkbox' || fieldType === 'radio') {
2383                        checkOrRadio = true;
2384                        cbOptionsWrapperId = gravityClassEle.attr('id');
2385                        cbOptionsWrapper = form.find('#' + cbOptionsWrapperId);
2386                        cbOptionChecked = form.find('#' + fieldId).prop('checked');
2387                    }
2388
2389                    // CHECK IF FIELD IS FILE UPLOAD & SET AS HIDDEN INPUT VALUE (SAFARI REQUIRED FIELD FIX)
2390                    if (fieldType === 'file') {
2391                        value = form.find('#' + fieldId).val().replace(/C:\\fakepath\\/i, '');
2392                        if (!label) {
2393                            label = 'File Upload';
2394                        }
2395                    }
2396
2397                    // CHECK IF FIELD IS A NUMBER FIELD WITH MIN AND/OR MAX
2398                    if (fieldType === 'number') {
2399                        var val = jQuery(this).val();
2400                        var num = parseFloat(val);
2401
2402                        if (val !== '') {
2403                            if (jQuery.isNumeric(num)) {
2404                                var min = parseFloat(jQuery(this).attr('min'));
2405                                var max = parseFloat(jQuery(this).attr('max'));
2406
2407                                if (jQuery.isNumeric(min) && jQuery.isNumeric(max)) {
2408                                    if ((Math.round(num * 100000) < Math.round(min * 100000)) || (Math.round(max * 100000) < Math.round(num * 100000))) {
2409                                        validationErrors.push({
2410                                            'fieldId': fieldId,
2411                                            'label': label,
2412                                            'name': fieldName,
2413                                            'visible': isVisible,
2414                                            'message': 'The number must be between ' + min + ' and ' + max
2415                                        });
2416                                    }
2417                                } else if (jQuery.isNumeric(max)) {
2418                                    if (Math.round(max * 100000) < Math.round(num * 100000)) {
2419                                        validationErrors.push({
2420                                            'fieldId': fieldId,
2421                                            'label': label,
2422                                            'name': fieldName,
2423                                            'visible': isVisible,
2424                                            'message': 'The number must be less than or equal to ' + max
2425                                        });
2426                                    }
2427                                } else if (jQuery.isNumeric(min)) {
2428                                    if (Math.round(num * 100000) < Math.round(min * 100000)) {
2429                                        validationErrors.push({
2430                                            'fieldId': fieldId,
2431                                            'label': label,
2432                                            'name': fieldName,
2433                                            'visible': isVisible,
2434                                            'message': 'The number must be greater than or equal to ' + min
2435                                        });
2436                                    }
2437                                }
2438                            } else {
2439                                validationErrors.push({
2440                                    'fieldId': fieldId,
2441                                    'label': label,
2442                                    'name': fieldName,
2443                                    'visible': isVisible,
2444                                    'message': 'You must enter a number'
2445                                });
2446                            }
2447                        }
2448                    }
2449
2450                    // CHECK IF FIELD IS AN EMAIL AND FORMATTED CORRECTLY
2451                    if (fieldType === 'email'){
2452                        var emailVal = jQuery(this).val();
2453                        // pattern taken form https://emailregex.com/
2454                        var emailReg = /^(([^<>()\[\]\\.,;:\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,}))$/;
2455                        if ( emailVal !== '' ) {
2456                            if(!emailReg.test( emailVal ) ){
2457                                validationErrors.push({
2458                                    'fieldId': fieldId,
2459                                    'label': label,
2460                                    'name': fieldName,
2461                                    'visible': isVisible,
2462                                    'message': 'The email address entered is invali
2462d, please check the formatting (e.g. [email protected])',
2463                                });
2464                            }
2465                        }
2466                    }
2467
2468                    // SET IF FIELD IS REQUIRED
2469                    if (isDisabled !== true && isVisible === true && (jQuery(this).attr('required') === 'true' || jQuery(this).attr('aria-required') === 'true' || gravityClassEle.hasClass('gfield_contains_required') === 'true' && checkOrRadio !== true && !jQuery(this).parent().hasClass('address_line_2'))) {
2470                        required = true;
2471                        jQuery(this).attr('required');
2472                    } else if (isAdvancedField) {
2473                        if (isAdvancedList && jQuery(this).attr('aria-required') === 'true' && isVisible === true) {
2474                            required = true;
2475                            jQuery(this).attr('required');
2476                            fieldId = (jQuery(this).closest('fieldset.gfield_contains_required').attr('id'));
2477                            jQuery(this).attr('id', fieldId + '_' + jQuery(this).attr('aria-label'));
2478                        }
2479                    }
2480
2481                    // GET REQUIRED FIELDS THAT DO NOT HAVE A VALUE
2482                    if (required && (!value || value == "") || isDisabled !== true && isVisible === true && checkOrRadio === true && cbOptionsWrapper.hasClass('gfield_contains_required') && cbOptionChecked === false) {
2483                        // MAKE SURE OBJECT DOES NOT ALREADY EXIST, CLEARING ARRAY ABOVE DOESN'T SEEM TO WORK HERE
2484                        var errorFound;
2485                        var cbIgnore;
2486
2487                        // IF CHECKBOX SPLIT NAME AT PERIOD FOR CONSISTENCY
2488                        if (fieldType === 'checkbox' && !jQuery(this).parent().hasClass('gchoice_select_all')) {
2489                            fieldName = fieldName.split('.')[0];
2490                        }
2491
2492                        // IF CHECKBOX OR RADIO, GROUP OPTIONS & ENSURE ONE IS CHECKED
2493                        if (cbOptionsWrapper) {
2494                            var cbOptions = cbOptionsWrapper.find('input');
2495                            cbOptions.each(function () {
2496                                if (jQuery(this).prop('checked')) {
2497                                    cbIgnore = true;
2498
2499                                    return false;
2500                                }
2501                            });
2502                        }
2503
2504                        if (validationErrors.length > 0) {
2505                            validationErrors.some(function (el) {
2506                                // CHECK IF ERROR ALREADY EXISTS IN VALIDATION ERRORS ARRAY
2507                                if (el.fieldId === fieldId || el.name === fieldName) {
2508                                    errorFound = true;
2509                                }
2510                            });
2511                        }
2512
2513                        if (!errorFound && !cbIgnore && !jQuery(this).parent().hasClass('name_prefix_select') && !jQuery(this).parent().hasClass('name_suffix') && !jQuery(this).parent().hasClass('ginput_address_line_2')) {
2514                            validationErrors.push({
2515                                'fieldId': fieldId,
2516                                'label': label,
2517                                'name': fieldName,
2518                                'visible': isVisible,
2519                                'message': message
2520                            });
2521                        }
2522                    }
2523
2524                    // SET CHECKBOX OR RADIO FIELD LABEL AND INPUT LABEL
2525                    if (fieldType === 'checkbox' || fieldType === 'radio') {
2526                        if (jQuery(this).prop('checked') === true) {
2527                            checkboxLabel = jQuery(this).parent().find('label').text().trim();
2528
2529                            if (jQuery(this).hasClass('cm-hipaa-forms-privacy-agree')) {
2530                                label = 'Privacy Agreement';
2531                            } else {
2532                                label = cbOptionsWrapper.find('.gfield_label').text().trim();
2533                            }
2534
2535                            checkboxParentLabel = label;
2536                            optionLabel = checkboxLabel;
2537                            optionValue = value;
2538                        }
2539
2540                        // GET CHECKBOXES OR RADIOS WITHIN GROUP
2541                        //var advancedFields = gravityClassEle.find('input, select');
2542                        //var lastAdvancedFieldId = gravityClassEle.find('input
2542:last', 'select:last').attr('id');
2543                    }
2544
2545                    // REPLACE HIDDEN HTML VERSION INPUTS WITH VALUES
2546                    if (isAdvancedField === true) {
2547                        if (newFormat === true && legacyMarkup === false) {
2548                            // NEW 2.5+ FORMAT STUFF HERE
2549                            // GET INPUT AND SELECT ELEMENTS IN FIELD
2550                            var advancedFields = gravityClassEle.find('input, select');
2551                            var lastAdvancedFieldId = '';
2552                            var lastAdvancedListField = '';
2553                            if (isAdvancedList === true) {
2554                                lastAdvancedListField = advancedFields.filter(':last');
2555                            } else {
2556                                lastAdvancedFieldId = advancedFields.filter(':last').attr('id');
2557                            }
2558                            // LOOP FIELDS IF THIS IS THE LAST ADVANCED FIELD
2559                            if (fieldId === lastAdvancedFieldId || isAdvancedList === true && jQuery(this).is(lastAdvancedListField)) {
2560                                // LOOP FIELDS
2561                                var advancedFieldValues = [];
2562                                var advancedFieldHTML = [];
2563                                advancedFields.each(function (index) {
2564                                    var advancedFieldClass = jQuery(this).parent().attr('class');
2565                                    var listGroupsWrapper;
2566                                    var listRows;
2567                                    var listRow;
2568                                    var firstListRow;
2569                                    var lastListRow;
2570                                    var listRowFields;
2571                                    var listCell;
2572                                    var firstListCell;
2573                                    var lastListCell;
2574                                    var listCellLabel;
2575
2576                                    if (isAdvancedList === true) {
2577                                        listGroupsWrapper = jQuery(this).closest('.gfield_list_groups');
2578                                        listRows = listGroupsWrapper.find('.gfield_list_group');
2579                                        listRow = jQuery(this).closest('.gfield_list_group');
2580                                        firstListRow = listRows.filter(':first');
2581                                        lastListRow = listRows.filter(':last');
2582                                        listRowFields = listRow.find('input, select');
2583                                        listCell = jQuery(this).closest('.gfield_list_group_item');
2584                                        firstListCell = listRowFields.filter(':first');
2585                                        lastListCell = listRowFields.filter(':last');
2586                                        //listCellLabel = jQuery(this).parent().attr('data-label');
2587                                        listCellLabel = jQuery(this).attr('aria-label');
2588                                    }
2589
2590                                    if (jQuery(this).is('select') && isAdvancedList !== true) {
2591                                        visibleSelect = form.find('#' + jQuery(this).attr('id'));
2592                                        optionText = visibleSelect.find('option:selected').text();
2593
2594                                        advancedFieldHTML.push('<span class="' + advancedFieldClass + '">' + optionText + '</span> ');
2595                                        advancedFieldValues.push(optionText);
2596                                    } else {
2597                                        if (isAdvancedList === true && jQuery(this).is(firstListCell)) {
2598                                            // if (listRow.is(firstListRow)) {
2599                                            //     //advancedFieldHTML.push('<table class="' + listTable.attr('class') + '">' + listTableHead.html());
2600                                            // }
2601                                            advancedFieldHTML.push('<div class="' + listRow.attr('class') + '"><div class="' + listCell.attr('class') + '">');
2602                                        }
2603
2604                                        if (isAdvancedList === true) {
2605                                            var listVal;
2606                                            if (jQuery(this).is('select')) {
2607                                                var thisListField = jQuery(this);
2608                                                var thisFieldName = thisListField.attr('name');
2609                                                var thisFieldSelects = hiddenForm.find('select[name="' + thisFieldName + '"]');
2610                                                var visibleFieldSelects = form.find('select[name="' + thisFieldName + '"]');
2611                                                var listOptionValue;
2612                                                thisFieldSelects.each(function (index) {
2613                                                    if (jQuery(this).is(thisListField)) {
2614                                                        listOptionValue = visibleFieldSelects.eq(index).val();
2615                                                    }
2616                                                });
2617
2618                                                if (listCell.attr('data-label')) {
2619                                                    listCellLabel = listCell.attr('data-label');
2620                                                }
2621
2622                                                listVal = listOptionValue;
2623                                            } else {
2624                                                listVal = jQuery(this).val();
2625                                            }
2626                                            var inputAttributes = [];
2627                                            jQuery(this).each(function () {
2628                                                jQuery.each(this.attributes, function () {
2629                                                    // this.attributes is not a plain object, but an array
2630                                                    // of attribute nodes, which contain both the name and value
2631                                                    if (this.specified) {
2632                                                        inputAttributes.push(this.name + '="' + this.value + '"');
2633                                                    }
2634                                                });
2635                                            });
2636                                            jQuery(this).replaceWith('<span ' + inputAttributes.join(' ') + '>
2636' + listVal + '</span>');
2637                                            advancedFieldValues.push(listCellLabel +': ' + listVal);
2638                                        } else {
2639                                            advancedFieldHTML.push('<span class="' + advancedFieldClass + '">' + jQuery(this).val() + '</span> ');
2640                                            advancedFieldValues.push(jQuery(this).val());
2641                                        }
2642
2643                                        if (isAdvancedList === true && jQuery(this).is(lastListCell)) {
2644                                            advancedFieldHTML.push('</div>');
2645                                            if (index !== advancedFields.length - 1) {
2646                                                advancedFieldValues.push('|');
2647                                            }
2648                                        } else if (isAdvancedList === true) {
2649                                            advancedFieldValues.push(' - ');
2650                                        }
2651                                    }
2652
2653                                    if (isAdvancedList === true) {
2654                                        value = advancedFieldHTML.join('');
2655                                    } else {
2656                                        value = '<div class="' + jQuery(this).closest('div.ginput_complex').attr('class') + '" id="' + jQuery(this).closest('div.ginput_complex').attr('id') + '">' + advancedFieldHTML.join('') + '</div>';
2657                                    }
2658
2659                                    fieldValue = advancedFieldValues.join(' ');
2660                                    label = gravityClassEle.find('.gfield_label_before_complex').text();
2661                                    // ADD FIX FOR ADVANCED LIST NOT GETTING LABEL
2662                                    if (!label) {
2663                                        label = gravityClassEle.find('.label').text();
2664                                    }
2665                                    if (!label){
2666                                        label = gravityClassEle.find('.gfield_label').text();
2667                                    }
2668                                });
2669                            } else {
2670                                value = '';
2671                                fieldValue = '';
2672                                label = '';
2673                            }
2674
2675                            if (value && isAdvancedList !== true) {
2676                                gravityClassEle.html('<label class="gfield_label gfield_label_before_complex">' + label + '</label>' + value);
2677                                fieldId = gravityClassEle.attr('id');
2678                                fieldType = 'advanced';
2679                            }
2680                        } else {
2681                            // PRE-2.5 & LEGACY FORMS ADVANCED FIELDS
2682                            // GET INPUT AND SELECT ELEMENTS IN FIELD
2683                            var advancedFields = gravityClassEle.find('input, select');
2684                            var lastAdvancedFieldId = '';
2685                            var lastAdvancedListField = '';
2686
2687                            if (isAdvancedList === true) {
2688                                lastAdvancedListField = advancedFields.filter(':last');
2689                            } else {
2690                                lastAdvancedFieldId = advancedFields.filter(':last').attr('id');
2691                            }
2692
2693                            // LOOP FIELDS IF THIS IS THE LAST ADVANCED FIELD
2694                            if (fieldId === lastAdvancedFieldId || isAdvancedList === true && jQuery(this).is(lastAdvancedListField)) {
2695                                var listTable;
2696                                var listTableHead;
2697                                if (isAdvancedList === true) {
2698                                    listTable = jQuery(this).closest('table');
2699                                    listTableHead = listTable.find('thead');
2700                                }
2701
2702                                // LOOP FIELDS
2703                                var advancedFieldValues = [];
2704                                var advancedFieldHTML = [];
2705                                advancedFields.each(function (index) {
2706                                    var advancedFieldClass = jQuery(this).parent().attr('class');
2707                                    var listRow;
2708                                    var firstListRow;
2709                                    var lastListRow;
2710                                    var listRowFields;
2711                                    var listCell;
2712                                    var firstListCell;
2713                                    var lastListCell;
2714                                    var listCellLabel;
2715
2716                                    if (isAdvancedList === true) {
2717                                        listRow = jQuery(this).closest('tr');
2718                                        firstListRow = jQuery(this).closest('table').find('tr').filter(':first');
2719                                        lastListRow = jQuery(this).closest('table').find('tr').filter(':last');
2720                                        listRowFields = listRow.find('input, select');
2721                                        listCell = jQuery(this).closest('td');
2722                                        firstListCell = listRowFields.filter(':first');
2723                                        lastListCell = listRowFields.filter(':last');
2724                                        listCellLabel = jQuery(this).attr('aria-label');
2725                                    }
2726
2727                                    if (jQuery(this).is('select') && isAdvancedList !== true) {
2728                                        visibleSelect = form.find('#' + jQuery(this).attr('id'));
2729                                        optionText = visibleSelect.find('option:selected').text();
2730
2731                                        advancedFieldHTML.push('<span class="' + advancedFieldClass + '">
2731' + optionText + '</span> ');
2732                                        advancedFieldValues.push(optionText);
2733                                    } else {
2734                                        if (isAdvancedList === true && jQuery(this).is(firstListCell)) {
2735                                            if (listRow.is(firstListRow)) {
2736                                                //advancedFieldHTML.push('<table class="' + listTable.attr('class') + '">' + listTableHead.html());
2737                                            }
2738
2739                                            advancedFieldHTML.push('<tr class="' + listRow.attr('class') + '">');
2740                                        }
2741
2742                                        if (isAdvancedList === true) {
2743                                            var listVal;
2744                                            if (jQuery(this).is('select')) {
2745                                                var thisListField = jQuery(this);
2746                                                var thisFieldName = thisListField.attr('name');
2747                                                var thisFieldSelects = hiddenForm.find('select[name="' + thisFieldName + '"]');
2748                                                var visibleFieldSelects = form.find('select[name="' + thisFieldName + '"]');
2749                                                var listOptionValue;
2750                                                thisFieldSelects.each(function (index) {
2751                                                    if (jQuery(this).is(thisListField)) {
2752                                                        listOptionValue = visibleFieldSelects.eq(index).val();
2753                                                    }
2754                                                });
2755
2756                                                if (jQuery(this).closest('td').attr('data-label')) {
2757                                                    listCellLabel = jQuery(this).closest('td').attr('data-label');
2758                                                }
2759
2760                                                listVal = listOptionValue;
2761                                            } else {
2762                                                listVal = jQuery(this).val();
2763                                            }
2764
2765                                            advancedFieldHTML.push('<td class="' + listCell.attr('class') + '">' + listVal + '</td>');
2766                                            advancedFieldValues.push(listCellLabel + ': ' + listVal);
2767                                        } else {
2768                                            advancedFieldHTML.push('<span class="' + advancedFieldClass + '">' + jQuery(this).val() + '</span> ');
2769                                            advancedFieldValues.push(jQuery(this).val());
2770                                        }
2771
2772                                        if (isAdvancedList === true && jQuery(this).is(lastListCell)) {
2773                                            advancedFieldHTML.push('</tr>');
2774
2775                                            if (listRow.is(lastListRow)) {
2776                                                //advancedFieldHTML.push('</table>');
2777                                            }
2778
2779                                            if (index !== advancedFields.length - 1) {
2780                                                advancedFieldValues.push('|');
2781                                            }
2782                                        } else if (isAdvancedList === true) {
2783                                            advancedFieldValues.push(' - ');
2784                                        }
2785                                    }
2786
2787                                    if (isAdvancedList === true) {
2788                                        var listTableHeadHtml = '';
2789                                        if (listTableHead.html()) {
2790                                            listTableHeadHtml = listTableHead.html();
2791                                        }
2792
2793                                        value = '<table class="' + jQuery(this).closest('table').attr('class') + '"><thead>' + listTableHeadHtml + '</thead>' + advancedFieldHTML.join('') + '</table>';
2794                                    } else {
2795                                        value = '<div class="' + jQuery(this).closest('div.ginput_complex').attr('class') + '" id="' + jQuery(this).closest('div.ginput_complex').attr('id') + '">' + advancedFieldHTML.join('') + '</div>';
2796                                    }
2797
2798                                    fieldValue = advancedFieldValues.join(' ');
2799                                    label = gravityClassEle.find('.gfield_label_before_complex').text();
2800
2801                                    // ADD FIX FOR ADVANCED LIST NOT GETTING LABEL
2802                                    if (!label) {
2803                                        label = gravityClassEle.find('label').text();
2804                                    }
2805                                    if (!label){
2806                                        label = gravityClassEle.find('.gfield_label').text();
2807                                    }
2808                                });
2809                            } else {
2810                                value = '';
2811                                fieldValue = '';
2812                                label = '';
2813                            }
2814
2815                            if (value) {
2816                                gravityClassEle.html('<label class="gfield_label gfield_label_before_complex">' + label + '</label>' + value);
2817                                fieldId = gravityClassEle.attr('id');
2818                                fieldType = 'advanced';
2819                            }
2820                        }
2821                    } else if (fieldType === 'select') {
2822                        // IF VALUE IS OBJECT ARRAY LIKE FROM MULTISELECT, JOIN VALUES TO STRING
2823                        if (Array.isArray(value)) {
2824                            fieldValue = value.join(';');
2825                            value = value.join('<br />');
2826                            jQuery(this).replaceWith(value);
2827                        } else if (jQuery(this).closest('.ginput_container_date').is('[class*="gfield_date_dropdown"]')){
2828                            var fieldsetElm;
2829                            var parentElm;
2830                            if (newFormat === true && legacyMarkup === false){
2831                                fieldsetElm = jQuery(this).closest('fieldset');
2832                                fieldSetId = fieldsetElm.attr('id');
2833                                parentElm =  jQuery(this).parent();
2834                            }else{
2835                                fieldsetElm = jQuery(this).closest('li.gf
2835ield');
2836                                fieldSetId = fieldsetElm.attr('id');
2837                                parentElm = jQuery(this).parent().parent();
2838                            }
2839
2840                            var dateSelect1 = form.find('#' + fieldSetId).find('select:eq(0)').attr('id');
2841                            var dateSelect2 = form.find('#' + fieldSetId).find('select:eq(1)').attr('id');
2842                            var dateSelect3 = form.find('#' + fieldSetId).find('select:eq(2)').attr('id');
2843                            var dateValue1 = form.find('#'+dateSelect1+' option:selected').text();
2844                            var dateValue2 = form.find('#'+dateSelect2+' option:selected').text();
2845                            var dateValue3 = form.find('#'+dateSelect3+' option:selected').text();
2846
2847                            if (jQuery(this).attr('id') === dateSelect1){
2848                                if (dateValue1 && dateValue1 !== '' && dateValue1 !== 'Month' && dateValue1 !== 'Day' && dateValue1 !== 'Year') {
2849                                    value = dateValue1 + '<span class="dateseparator">\/</span>' + dateValue2 + '<span class="dateseparator">\/</span>' + dateValue3;
2850                                    parentElm.replaceWith(value);
2851                                    fieldId = fieldSetId;
2852                                    fieldValue = dateValue1 + '/' + dateValue2 + '/' + dateValue3;
2853                                    optionText = '';
2854                                    label = fieldsetElm.find('.gfield_label').text();
2855                                }else{
2856                                    label = fieldsetElm.find('.gfield_label').text();
2857                                    jQuery(this).replaceWith('');
2858                                }
2859                            }else{
2860                                label = '';
2861                                jQuery(this).replaceWith('');
2862                            }
2863                        } else {
2864                            jQuery(this).replaceWith(optionText);
2865                        }
2866                    } else if (fieldType === 'checkbox') {
2867                        // SET CHECKBOX VALUE IF DIFFERENT THAN LABEL
2868                        if (value !== checkboxLabel && !jQuery(this).parent().hasClass('ginput_container_consent')) {
2869                            checkboxValue = value;
2870                        }
2871
2872                        if (jQuery(this).prop('checked') === true) {
2873                            // SET CHECKED CHECKBOX IMAGE AND VALUE
2874                            value = '<span class="cm-hipaa-forms-checkbox-value cm-hipaa-forms-checkbox-checked" style="background: #f7f5a091;"><img src="https://www.hipaaforms.online/api-assets/checkbox.png" alt="Checked" style="height: 16px; padding-right: 5px; vertical-align: middle;" />' + checkboxValue + '</span>';
2875                            // ADD CHECKED WRAPPER CLASS TO PARENT ELEMENT
2876                            jQuery(this).parent().addClass('cm-hipaa-forms-checkbox-checked-wrapper');
2877                            if (checkboxParentLabel) {
2878                                fieldValue = 'checked';
2879                            }
2880                        } else {
2881                            // SET UNCHECKED CHECKBOX IMAGE AND VALUE
2882                            value = '<span class="cm-hipaa-forms-checkbox-value  cm-hipaa-forms-checkbox-not-checked"><img src="https://www.hipaaforms.online/api-assets/checkbox-unchecked.png" alt="Not Checked" style="height: 16px; padding-right: 5px; vertical-align: middle;" /></span>';
2883                            jQuery(this).parent().addClass('cm-hipaa-forms-checkbox-not-checked-wrapper');
2884                        }
2885
2886                        // ADD VALUE
2887                        jQuery(this).replaceWith(value);
2888                    } else if (fieldType === 'radio') {
2889                        // SET RADIO VALUE IF DIFFERENT THAN LABEL
2890                        if (value !== checkboxLabel) {
2891                            radioValue = value;
2892                        }
2893
2894                        if (jQuery(this).prop('checked') === true) {
2895                            // SET CHECKED RADIO BUTTON IMAGE AND VALUE
2896                            value = '<span class="cm-hipaa-forms-radio-value cm-hipaa-forms-radio-checked" style="background: #f7f5a091;"><img src="https://www.hipaaforms.online/api-assets/radio-checked.png" alt="Selected" style="height: 16px; padding-right: 5px; vertical-align: middle;" />' + radioValue + '</span>';
2897                            jQuery(this).parent().addClass('cm-hipaa-forms-radio-checked-wrapper');
2898
2899                            if (checkboxParentLabel) {
2900                                fieldValue = 'checked';
2901                            }
2902                        } else {
2903                            // SET UNCHECKED RADIO BUTTON IMAGE AND VALUE
2904                            value = '<span class="cm-hipaa-forms-radio-value cm-hipaa-forms-radio-not-checked"><img src="https://www.hipaaforms.online/api-assets/radio-unchecked.png" alt="Not Selected" style="height: 16px; padding-right: 5px; vertical-align: middle;" /></span>';
2905                            jQuery(this).parent().addClass('cm-hipaa-forms-radio-not-checked-wrapper');
2906                        }
2907                        jQuery(this).replaceWith(value);
2908                    } else if (fieldType === 'url') {
2909                        var rawUrl = jQuery(this).val();
2910                        var formatedUrl = '';
2911
2912                        if (rawUrl.indexOf("http://") === 0){
2913                            formatedUrl = rawUrl.replace('http://','https://');
2914                        }else if(rawUrl.indexOf("https://") === 0){
2915                            formatedUrl = rawUrl;
2916                        }else{
2917                            formatedUrl = 'https://'+rawUrl;
2918                        }
2919                        value = '<span class="cm-hipaa-forms-url-value"><a target="_blank" href="' + formatedUrl + '">' + formatedUrl + '</a></span>';
2920                        fieldValue = formatedUrl;
2921                        jQuery(this).replaceWith(value);
2922                    }else if(jQuery(this).parent().hasClass('ginput_container_time')) {
2923                        if (jQuery(this).parent().hasClass('gfield_time_hour')) {
2924                            var name = jQuery(this).attr('name');
2925                            var hours = jQuery(this).val();
2926                            var minutes = jQuery('.gfield_time_minute input[name="' + name + '"]').val();
2927                            var ampm = jQuery('.gfield_time_ampm select[name="' + name + '"]').val();
2928                            if(hours && hours !== '') {
2929                                if (parseInt(minutes) < 10) {
2930                                    minutes = '0' + minutes;
2931                                }
2932                                if (ampm) {
2933                                    fieldValue = hours + ':' + minutes + ' ' + ampm;
2934                                } else {
2935                                    fieldValue = hours + ':' + minutes;
2936                                }
2937                            }else{
2938                                fieldValue = '';
2939                            }
2940                            label = jQuery(this).closest('fieldset').find('.gfield_label').text();
2941                            fieldId = jQuery(this).closest('.gfield_time_hour').attr('id');
2942                            jQuery(this).closest('.ginput_complex').replaceWith('<div class="ginput_container ginput_container_time" id="' + fieldId + '">' + fieldValue + '</div>');
2943                        } else {
2944                            label = false;
2945                        }
2946                    }else if (jQuery(this).closest('.ginput_container_date').is('[class*="gfield_date"]')) {
2947                        var dateFieldsetElm = jQuery(this).closest('fieldset, li.gf
2947ield');
2948                        var dateFieldsetId = dateFieldsetElm.attr('id');
2949                        var parentElm;
2950
2951                        if (dateFieldsetElm.is('fieldset')) {
2952                            parentElm = jQuery(this).parent();
2953                        } else {
2954                            parentElm = jQuery(this).parent().parent();
2955                        }
2956
2957                        var currentInputId = jQuery(this).attr('id') || '';
2958                        var baseInputId = currentInputId.replace(/_\d+$/, '');
2959
2960                        var dateField1 = form.find('#' + baseInputId + '_1');
2961                        var dateField2 = form.find('#' + baseInputId + '_2');
2962                        var dateField3 = form.find('#' + baseInputId + '_3');
2963
2964                        if (!dateField1.length || !dateField2.length || !dateField3.length) {
2965                            dateField1 = form.find('#' + dateFieldsetId).find('.ginput_container_date:eq(0) input');
2966                            dateField2 = form.find('#' + dateFieldsetId).find('.ginput_container_date:eq(1) input');
2967                            dateField3 = form.find('#' + dateFieldsetId).find('.ginput_container_date:eq(2) input');
2968                        }
2969
2970                        var dateFieldValue1 = jQuery(dateField1).val();
2971                        var dateFieldValue2 = jQuery(dateField2).val();
2972                        var dateFieldValue3 = jQuery(dateField3).val();
2973
2974                        if (jQuery(this).attr('id') === jQuery(dateField1).attr('id')) {
2975                            if (dateFieldValue1 && dateFieldValue1 !== '' && dateFieldValue1 !== 'Month' && dateFieldValue1 !== 'Day' && dateFieldValue1 !== 'Year') {
2976                                value = dateFieldValue1 + '<span class="dateseparator">\/</span>' + dateFieldValue2 + '<span class="dateseparator">\/</span>' + dateFieldValue3;
2977                                parentElm.replaceWith(value);
2978                                fieldValue = dateFieldValue1 + '/' + dateFieldValue2 + '/' + dateFieldValue3;
2979                                fieldId = dateFieldsetId;
2980                                fieldType = 'date';
2981                                label = dateFieldsetElm.find('.gfield_label').first().text().trim();
2982                                optionText = '';
2983                            } else {
2984                                label = dateFieldsetElm.find('.gfield_label').first().text().trim();
2985                                jQuery(this).replaceWith('');
2986                            }
2987                        } else {
2988                            label = '';
2989                            jQuery(this).replaceWith('');
2990                        }
2991                    } else {
2992                        jQuery(this).replaceWith(value);
2993                    }
2994                    // MAKE SURE VALUES ARE TRIMMED
2995                    if(typeof value === 'string' || value instanceof String) {
2996                        value = value.trim();
2997                    }
2998                    if(typeof fieldValue === 'string' || fieldValue instanceof String) {
2999                        fieldValue = fieldValue.trim();
3000                    }
3001
3002                    if(!fieldValue && fieldType !== 'checkbox' && fieldType !== 'radio' && fieldType !== 'advanced' && fieldType !== 'url') {
3003                        fieldValue = value;
3004                    }
3005
3006                    // ADD CUSTOM CLASS TO IDENTIFY IF FIELD VALUE IS EMPTY OR NOT
3007                    if(gravityClassEle.hasClass('cm_hipaa_forms_field_not_empty') === false && (!fieldValue || fieldValue.length === 0)) {
3008                        gravityClassEle.addClass('cm_hipaa_forms_field_empty');
3009                    } else {
3010                        gravityClassEle.removeClass('cm_hipaa_forms_field_empty');
3011                        gravityClassEle.addClass('cm_hipaa_forms_field_not_empty');
3012                    }
3013
3014                    // REMOVED "&& fieldValue" TO START STORING FIELDS WITH EMPTY VALUES 4/2/21
3015                    if (label) {
3016                        // IF LABEL EXISTS PUSH TO FIELDS ARRAY
3017                        formFields.push({
3018                            'label': label,
3019                            'option_label': optionLabel,
3020                            'option_value': optionValue,
3021                            'value': fieldValue,
3022                            'field_id': fieldId,
3023                            'field_type': fieldType,
3024                            'option_text': optionText
3025                        });
3026                    }
3027                }
3028            });
3029
3030            // GET SIGNATURE SVG BASE64 DATA
3031            var signature;
3032            var signatureEle;
3033            var datapair;
3034            if(showSignature === 'yes') {
3035                signatureEle = form.find('.cm-hipaa-form-signature');
3036                datapair = signatureEle.jSignature("getData", "svgbase64");
3037                if(datapair) {
3038                    signature = "data:" + datapair[0] + "," + datapair[1];
3039
3040                    formFields.push({
3041                        'label': 'Signature',
3042                        'option_label': 'data',
3043                        'option_value': datapair[0],
3044                        'value': datapair[1],
3045                        'field_id': '',
3046                        'field_type': 'signature',
3047                        'option_text': 'ELECTRONICALLY SIGNED ' + new Date().toLocaleString()
3048                    });
3049                }
3050            }
3051
3052            // SET PRIVACY AGREEMENT ELEMENT
3053            var privacyAgreementEle = form.find('.cm-hipaa-forms-privacy-agree');
3054
3055            // RESET ERRORS
3056            jQuery('.gfield_error').removeClass('gfield_error');
3057            privacyAgreementEle.parent().css('border', '0');
3058            if(signatureEle) {
3059                signatureEle.find('.jSignature').css('border', '0');
3060            }
3061            noticeEle.html('');
3062            // CLEAR ERRORS
3063            form.find('.gfield_error').removeClass('gfield_error');
3064            form.find('.validation_error, .validation_message').remove();
3065
3066            // MULTI-PAGE FORM RENDERING
3067            var gravityFormPages = hiddenForm.find('.gform_page');
3068            if(gravityFormPages && gravityFormPages.length > 0) {
3069                // REMOVE PROGRESS BAR
3070                hiddenForm.find('.gf_progressbar_wrapper').remove();
3071
3072                gravityFormPages.each(function(index) {
3073                    // MAKE PAGE ELEMENT VISIBLE
3074                    jQuery(this).css({
3075                        'display': 'block'
3076                    });
3077
3078                    // REMOVE BUTTONS
3079                    jQuery(this).find('.gform_page_footer').remove();
3080
3081                    // APPEND PAGE BREAK TO END OF PAGE FOR MPDF IF NOT LAST ELEMENT
3082                    if(index !== (gravityFormPages.length - 1)) {
3083                        jQuery(this).append('<pagebreak />');
3084                    }
3085                });
3086            }
3087
3088            var nonce = cmHipaaScript.nonce;
3089            var honeyPotInput = form.find('.cm-hipaa-required-extra');
3090            var honeyPot;
3091
3092            if(honeyPotInput) {
3093                honeyPot = honeyPotInput.val();
3094            }
3095
3096            if(honeyPot) {
3097                //console.log(honeyPot);
3098                // REMOVE HIDDEN FORM
3099                jQuery('.cm-hipaa-forms-hidden-form').remove();
3100
3101                // ADD NOTICE MESSAGE
3102                noticeEle.html('<div><img src="https://media1.tenor.com/images/4945d2cd26ab7d38a6dce346a9c866e7/tenor.gif?itemid=14825791" alt="Angry Robot Upset GIF - AngryRobot Upset Furious GIFs" style="max-width: 250px;"></div><div>Oops, this appears to be an automated bot submission!  Please contact [email protected] if this is an error.</div>');
3103
3104                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3105                submitButton.removeClass('inactive').addClass('active');
3106            } else if(!jQuery.isEmptyObject(validationErrors) && validationErrors.length > 0) {
3107                // ADD ERROR MESSAGE TO TOP OF FORM
3108                form.find('.gform_body').before('<div class="validation_error">There was a problem with your submission. Errors have been highlighted below.</div>');
3109
3110                // VALIDATE FIELDS
3111                jQuery.each(validationErrors, function(key, val) {
3112                    let invalidFieldId = val.fieldId;
3113                    let invalidFieldInputNumber;
3114                    let invalidField = jQuery('#' + invalidFieldId);
3115
3116                    // IF INVALID FIELD NOT FOUND IT'S PROBABLY A FIELD SET SO SLICE IT DOWN
3117                    if(invalidField.length === 0) {
3118                        invalidFieldId = invalidFieldId.slice(0, -2);
3119
3120                        // FIND FIRST EMPTY INPUT IN FIELD SET
3121                        const invalidFieldSetInputs = jQuery('#' + invalidFieldId + ' input');
3122                        jQuery.each(invalidFieldSetInputs, function(inputKey, inputVal) {
3123                            const invalidValue = jQuery('#' + invalidFieldId + ' input').eq(inputKey).val();
3124                            if(!invalidValue || invalidValue === '') {
3125                                invalidFieldInputNumber = inputKey;
3126                                return false; // BREAK LOOP
3127                            }
3128                        });
3129
3130                        // SET INVALID FIELD
3131                        invalidField = jQuery('#' + invalidFieldId + ' input:eq(' + invalidFieldInputNumber + ')');
3132                    }
3133
3134                    var invalidFieldType = invalidField.attr('type');
3135                    var requiredMessage = val.message;
3136
3137                    if(requiredMessage.length < 1){
3138                        if(invalidField.closest('li').hasClass('hipaa_forms_office_location') && !locationEmail) {
3139                            requiredMessage = 'Location select options must have a value!  This should be an email address for the person at the specific location that should receive the form submission notice.';
3140                        } else {
3141                            requiredMessage = 'This field is required.';
3142                        }
3143                    }
3144
3145
3146                    // ADD ERROR CLASS & NOTICE MESSAGE
3147                    let invalidFieldWrapper;
3148                    if(newFormat === true && legacyMarkup === false) {
3149                        /* NEW FORMAT VALIDATION */
3150                        // SET INVALID FIELD WRAPPER
3151                        if(invalidFieldInputNumber) {
3152                            invalidFieldWrapper = invalidField.parent();
3153                        } else {
3154                            invalidFieldWrapper = invalidField.closest('.gfield');
3155                        }
3156
3157                        // CHECK IF VALIDATION ERROR ALREADY EXISTS
3158                        var existingValidationMessage = invalidFieldWrapper.find('.validation_message');
3159
3160                        if(existingValidationMessage.length === 0) {
3161                            // IF NO VALIDATION MESSAGE EXISTS ADD THE MESSAGE
3162                            invalidFieldWrapper.addClass('gfield_error').append('<div class="gfield_description validation_message">' + requiredMessage + '</div>');
3163                        }
3164                    } else {
3165                        /* PRE-2.5 & LEGACY FORMS */
3166                        if(invalidFieldType === 'checkbox' || invalidFieldType === 'radio') {
3167                            invalidFieldWrapper = invalidField.parent().parent().parent().parent();
3168                            invalidFieldWrapper.addClass('gfield_error').append('<div class="gfield_description validation_message">' + requiredMessage + '</div>');
3169                        } else {
3170                            invalidFieldWrapper = invalidField.closest('li');
3171                            invalidFieldWrapper.addClass('gfield_error').append('<div class="gfield_description validation_message">' + requiredMessage + '</div>');
3172                        }
3173                    }
3174                });
3175
3176                // REMOVE HIDDEN FORM
3177                jQuery('.cm-hipaa-forms-hidden-form').remove();
3178                // SCROLL TO FIRST INVALID FIELD
3179                if (jQuery('#' + validationErrors[0].fieldId).length){
3180                    jQuery('html, body').animate({
3181                        scrollTop: jQuery('#' + validationErrors[0].fieldId).offset().top-125
3182                    }, 500, 'linear');
3183                }else{
3184                    jQuery('html, body').animate({
3185                        scrollTop: jQuery('#' + formId).offset().top-125
3186                    }, 500, 'linear');
3187                }
3188
3189
3190                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3191                submitButton.removeClass('inactive').addClass('active');
3192            } else if(privacyAgreementEle.prop('checked') !== true) {
3193                // ADD RED BORDER TO PRIVACY FIELD
3194                privacyAgreementEle.parent().css('border', '1px solid red');
3195
3196                // UPDATE NOTICE ELEMENT
3197                noticeEle.html('You must agree to the HIPAA Privacy Agreement');
3198
3199                // REMOVE HIDDEN FORM
3200                jQuery('.cm-hipaa-forms-hidden-form').remove();
3201
3202                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3203                submitButton.removeClass('inactive').addClass('active');
3204            } else if(showSignature === 'yes' && !signatureEle.find('.jSignature').hasClass('cm-valid-sig')) {
3205                // ADD RED BORDER TO SIGNATURE FIELD
3206                signatureEle.find('.jSignature').css('border', '1px solid red');
3207
3208                // UPDATE NOTICE ELEMENT
3209                noticeEle.html('You must sign the form');
3210
3211                // REMOVE HIDDEN FORM
3212                jQuery('.cm-hipaa-forms-hidden-form').remove();
3213
3214                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3215                submitButton.removeClass('inactive').addClass('active');
3216            } else {
3217                /*** VALIDATE ACCOUNT TO GET ENABLED ADD-ONS ***/
3218                jQuery.ajax({
3219                    method: 'POST',
3220                    type: 'POST',
3221                    url: cmHipaaScript.ajax_url,
3222                    data: {
3223                        'action': 'cm_hipaa_validate_account',
3224                        'form_id': formId,
3225                        'form_submission': true,
3226                        'nonce': cmHipaaScript.nonce
3227                    },
3228                    success: function (data) {
3229                        // REMOVE LOADING ICON
3230                        jQuery('.cm-hipaa-forms-loading').remove();
3231                        //var resultData = JSON.parse(data);
3232                        var resultData;
3233                        try {
3234                            resultData = cmHipaaParseAjaxJson(data);
3235                        } catch (e) {
3236                            console.log(data);
3237                            noticeEle.append(data);
3238                            return false;
3239                        }
3240
3241                        if (resultData.success === 'success') {
3242                            // VALIDATE TRANSIENT SESSION ID
3243                            var sessionId = resultData.session_id || '';
3244
3245                            // CHECK IF FILE UPLOAD ENABLED
3246                            var validatedAddOns = resultData.add_ons;
3247                            var validatedAddOnsArray;
3248                            if(validatedAddOns) {
3249                                validatedAddOnsArray = validatedAddOns.split(',');
3250                            }
3251                            var fileUploadEnabled = 'no';
3252                            if(Array.isArray(validatedAddOnsArray) && validatedAddOnsArray.indexOf('fileupload') !== -1) {
3253                                fileUploadEnabled = 'yes';
3254                            } else if(validatedAddOns === 'fileupload') {
3255                                fileUploadEnabled = 'yes';
3256                            }
3257
3258                            // IF FILE INPUTS EXIST & FILE UPLOAD ENABLED
3259                            if(fileInputs.length > 0 && fileUploadEnabled === 'yes') {
3260                                // SHOW LOADING BAR
3261                                noticeEle.html('<div class="cm-hipaa-forms-file-upload-status">Uploading Files...</div><div class="cm-hipaa-forms-progress-wrapper"><div class="cm-hipaa-forms-progress"><div class="cm-hipaa-forms-progress-bar"><!--    <div class="cm-hipaa-forms-progress-label">10%</div>--></div></div></div>');
3262                                cmHipaaFormsProgress();
3263
3264                                var fileInputsLength = fileInputs.length;
3265                                var iterations = 0;
3266                                var fileKeys = [];
3267
3268                                fileInputs.each(function(index) {
3269                                    var fileInputParentId = jQuery(this).parent().parent().attr('id');
3270                                    var fileLabel = jQuery(this).parent().parent().find('label').text();
3271                                    fileLabel = fileLabel.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '-');
3272
3273                                    var fieldId = '';
3274
3275                                    var inputId = jQuery(this).attr('id') || '';
3276                                    var inputMatches = inputId.match(/^input_(\d+)_(\d+)/);
3277
3278                                    if (inputMatches && inputMatches[2]) {
3279                                        fieldId = inputMatches[2];
3280                                    } else if (fileInputParentId) {
3281                                        var wrapperMatches = fileInputParentId.match(/^field_(\d+)_(\d+)/);
3282
3283                                        if (wrapperMatches && wrapperMatches[2]) {
3284                                            fieldId = wrapperMatches[2];
3285                                        }
3286                                    }
3287
3288                                    // GET FILE
3289                                    var fileInput = jQuery(this).get()[0];
3290                                    var theFormFile = fileInput && fileInput.files ? fileInput.files[0] : null;
3291
3292                                    if(theFormFile) {
3293                                        var fileType = theFormFile.type;
3294                                        var fileName = index+'_'+theFormFile.name;
3295
3296                                        // GET PRESIGNED FILE UPLOAD URL
3297                                        jQuery.ajax({
3298                                            method: 'POST',
3299                                            type: 'POST',
3300                                            url: cmHipaaScript.ajax_url,
3301                                            data: {
3302                                                'action': 'cm_hipaa_get_file_upload_url',
3303                                                'file_name': fileName,
3304                                                'file_size': theFormFile.size,
3305                                                'mime_type': theFormFile.type,
3306                                                'form_id': formId,
3307                                                'field_id': fieldId,
3308                                                'session_id': sessionId,
3309                                                'nonce': cmHipaaScript.
3309nonce
3310                                            },
3311                                            success: function (data) {
3312                                                var resultData;
3313                                                try {
3314                                                    resultData = cmHipaaParseAjaxJson(data);
3315                                                } catch (e) {
3316                                                    console.log(data);
3317                                                    noticeEle.append(data);
3318                                                    return false;
3319                                                }
3320
3321                                                var fileUploadUrl = resultData.file_upload_url;
3322                                                var fileKey = resultData.file_key;
3323
3324                                                // PUSH FILE KEYS TO ARRAY
3325                                                fileKeys.push(fileKey);
3326
3327                                                // UPLOAD THE FILE
3328                                                jQuery.ajax({
3329                                                    url: fileUploadUrl, // the presigned URL
3330                                                    type: 'PUT',
3331                                                    processData: false,
3332                                                    contentType: fileType,
3333                                                    //headers: {'x-amz-tagging': 'label=' + fileLabel}, //breaks on long text
3334                                                    data: theFormFile,
3335                                                    success: function () {
3336                                                        var hiddenFileUploadContainer = hiddenForm.find('#' + fileInputParentId).find('.ginput_container_fileupload');
3337                                                        var existingFiles = hiddenForm.find('#' + fileInputParentId).find('.cm_hipaa_file_input'); // GET EXISTING FILES ALREADY UPLOADED IN HIDDEN FORM
3338                                                        hiddenFileUploadContainer.html(''); // CLEAR THE CONTAINER ELEMENT
3339
3340                                                        jQuery.each(existingFiles, function() {
3341                                                            // APPEND EXISTING FILES ALREADY UPLOADED BACK INTO CONTAINER ELEMENT
3342                                                            hiddenFileUploadContainer.append(jQuery(this));
3343                                                        });
3344
3345                                                        // APPEND NEW UPLOADED FILE TO CONTAINER ELEMENT
3346                                                        hiddenFileUploadContainer.append('<div class="cm_hipaa_file_input" data-file-key="' + fileKey + '">' + fileKey + '</div>');
3347
3348                                                        iterations = iterations + 1;
3349                                                        if (iterations === fileInputsLength) {
3350                                                            // UPDATE FILE UPLOAD STATUS
3351                                                            jQuery('.cm-hipaa-forms-file-upload-status').html('Submitting Form...');
3352                                                            // SET TIMEOUT TO ENSURE INPUTS OVERWRITTEN
3353                                                            setTimeout(function () {
3354                                                                // SUBMIT FORM
3355                                                                jQuery.ajax({
3356                                                                    method: 'POST',
3357                                                                    type: 'POST',
3358                                                                    url: cmHipaaScript.ajax_url,
3359                                                                    data: {
3360                                                                        'action': 'cm_hipaa_submit_gravity_form',
3361                                                                        'formId': formId,
3362                                                                        'formFields': formFields,
3363                                                                        'formHtml': hiddenForm.html(),
3364                                                                        'signature': signature,
3365                                                                        'nonce': nonce,
3366                                                                        'selectedUser': selectedUser,
3367                                                                        'location': location,
3368                                                                        'locationEmail': locationEmail,
3369                                                                        'firstName': firstName,
3370                                                                        'lastName': lastName,
3371                                                                        'email': email,
3372                                                                        'phone': phone,
3373                                                                        'notification_option': notificationOption,
3374                                                                        'files': fileKeys.join(','),
3375                                                                        'formFound': formFound,
3376                                                                        'session_id': sessionId
3377                                                                    },
3378                                                                    success: function (data) {
3379                                                                        var resultData;
3380                                                                        try {
3381                                                                            resultData = cmHipaaParseAjaxJson(data);
3382                                                                        } catch (e) {
3383                                                                            console.log(data);
3384                                                                            noticeEle.append(data);
3385                                                                            hiddenForm.remove();
3386                                                                            jQuery('.cm-hipaa-forms-hidden-form').remove();
3387
3388                                                                            // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3389                                                                            submitButton.removeClass('inactive').addClass('active');
3390                                                                            return false;
3391                                                                        }
3392
3393                                                                        var formError = '';
3394                                                                        if(resultData.error) {
3395                                                                            formError = resultData.error;
3396                                                                        }
3397
3398                                                                        if (resultData.success === 'success') {
3399                                                                            if (successHandler === 'message') {
3400                                                                                if(successHideForm === 'hide') {
3401                                                                                    // HIDE FORM THEN ADD SUCCESS MESSAGE
3402                                                                                    form.fadeOut().promise().done(function() {
3403                                                                                        form.after('<div class="cm-hipaa-notice cm-hidden-form-message">' + successMessage + ' ' + formError + '</div>');
3404                                                                                        jQuery('.cm-hidden-form-message').fadeIn();
3405                                                                                    });
3406                                                                                    // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3407                                                                                    submitButton.removeClass('inactive').addClass('active');
3408                                                                                } else {
3409                                                                                    // DISPLAY THE SUCCESS NOTICE
3410                                                                                    noticeEle.html(successMessage + ' ' + formError);
3411                                                                                    // ADD ACTIVE CLASS BACK TO SUB
3411MIT BUTTON
3412                                                                                    submitButton.removeClass('inactive').addClass('active');
3413                                                                                }
3414                                                                            } else if (successHandler === 'redirect') {
3415                                                                                // REDIRECT TO SUCCESS PAGE
3416                                                                                window.location = successRedirect;
3417                                                                            } else if (successHandler === 'callback') {
3418                                                                                // MAKE SURE CALLBACK IS AN EXISTING FUNCTION
3419                                                                                fnExists = typeof window[successCallback] === 'function';
3420                                                                                if (fnExists) {
3421                                                                                    if (successCallbackParams) {
3422                                                                                        window[successCallback].apply(null, successCallbackParams.split(','));
3423                                                                                    } else {
3424                                                                                        window[successCallback]();
3425                                                                                    }
3426                                                                                } else {
3427                                                                                    console.log(successCallback + ' is not an existing function!');
3428                                                                                }
3429                                                                                if (successMessage) {
3430                                                                                    noticeEle.html(successMessage + ' ' + formError);
3431                                                                                } else {
3432                                                                                    // DISPLAY THE SUCCESS NOTICE
3433                                                                                    noticeEle.html('Thank y
3433ou, your form has been encrypted to protect your privacy and submitted successfully!');
3434                                                                                }
3435                                                                            } else {
3436                                                                                // DISPLAY THE SUCCESS NOTICE
3437                                                                                noticeEle.html('Thank you, your form has been encrypted to protect your privacy and submitted successfully!');
3438                                                                            }
3439                                                                            // RESET THE FORM
3440                                                                            form[0].reset();
3441                                                                            if (signature) {
3442                                                                                signatureEle.jSignature("reset");
3443                                                                            }
3444
3445                                                                            // SHOW PAGE 1 OF FORM IF PAGINATED/STEPPED & NO ERROR
3446                                                                            if(isPaginated === true && !formError) {
3447                                                                                // DEACTIVATE SUBMIT BUTTON AGAIN (DIRTY BUT EASIER)
3448                                                                                submitButton.removeClass('active').addClass('inactive');
3449
3450                                                                                setTimeout(function() {
3451                                                                                    jQuery('.gform_page').fadeOut().promise().done(function() {
3452                                                                                        jQuery('.gform_page:first').fadeIn().promise().done(function() {
3453                                                                                            // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3454                                                                                            submitButton.removeClass('inactive').addClass('active');
3455                                                                                        });
3456                                                                                    });
3457                                                                                }, 5000);
3458                                                                            } else {
3459                                                                                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3460                                                                                submitButton.removeClass('inactive').addClass('active');
3461                                                                            }
3462                                                                        } else {
3463                                                                            // JUST A FAIL-SAFE JUST IN CASE WE DON'T ACTUALLY GET A SUCCESS MESSAGE
3464                                                                            noticeEle.html(formError);
3465
3466                                                                            // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3467                                                                            submitButton.removeClass('inactive').addClass('active');
3468                                                                        }
3469                                                                        hiddenForm.remove();
3470                                                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
3471                                                                    },
3472                                                                    error: function (errorThrown) {
3473                                                                        console.log(errorThrown);
3474                                                                        noticeEle.html(errorThrown);
3475                                                                        hiddenForm.remove();
3476                                                                        jQuery('.cm
3476-hipaa-forms-hidden-form').remove();
3477
3478                                                                        // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3479                                                                        submitButton.removeClass('inactive').addClass('active');
3480                                                                    }
3481                                                                });
3482                                                            }, 500);
3483                                                        }
3484                                                    }
3485                                                });
3486                                            },
3487                                            error: function (errorThrown) {
3488                                                console.log(errorThrown);
3489                                            }
3490                                        });
3491                                    } else {
3492                                        hiddenForm.find('#' + fileInputParentId).find('.ginput_container_fileupload').html('<div class="cm_hipaa_file_input" data-file-key="">No File Attached</div>');
3493
3494                                        iterations = iterations + 1;
3495                                        if (iterations === fileInputsLength) {
3496                                            // UPDATE FILE UPLOAD STATUS
3497                                            jQuery('.cm-hipaa-forms-file-upload-status').html('Submitting Form...');
3498                                            // SET TIMEOUT TO ENSURE INPUTS OVERWRITTEN
3499                                            setTimeout(function () {
3500                                                // SUBMIT FORM
3501                                                jQuery.ajax({
3502                                                    method: 'POST',
3503                                                    type: 'POST',
3504                                                    url: cmHipaaScript.ajax_url,
3505                                                    data: {
3506                                                        'action': 'cm_hipaa_submit_gravity_form',
3507                                                        'formId': formId,
3508                                                        'formFields': formFields,
3509                                                        'formHtml': hiddenForm.html(),
3510                                                        'signature': signature,
3511                                                        'nonce': nonce,
3512                                                        'selectedUser': selectedUser,
3513                                                        'location': location,
3514                                                        'locationEmail': locationEmail,
3515                                                        'firstName': firstName,
3516                                                        'lastName': lastName,
3517                                                        'email': email,
3518                                                        'phone': phone,
3519                                                        'notification_option': notificationOption,
3520                                                        'files': fileKeys.join(','),
3521                                                        'formFound': formFound,
3522                                                        'session_id': sessionId
3523                                                    },
3524                                                    success: function (data) {
3525                                                        //var resultData = JSON.parse(data);
3526                                                        var resultData;
3527                                                        try {
3528                                                            resultData = cmHipaaParseAjaxJson(data);
3529                                                        } catch (e) {
3530                                                            console.log(data);
3531                                                            noticeEle.append(data);
3532                                                            return false;
3533                                                        }
3534
3535                                                        var formError = '';
3536                                                        if(resultData.error) {
3537                                                            formError = resultData.error;
3538                                                        }
3539
3540                                                        if (resultData.success === 'success') {
3541                                                            if (successHandler === 'message') {
3542                                                                if(successHideForm === 'hide') {
3543                                                                    // HIDE FORM THEN ADD SUCCESS MESSAGE
3544                                                                    form.fadeOut().promise().done(function() {
3545                                                                        form.after('<div class="cm-hipaa-notice cm-hidden-form-message">' + successMessage + ' ' + formError + '</div>');
3546                                                                        jQuery('.cm
3546-hidden-form-message').fadeIn();
3547                                                                    });
3548
3549                                                                    // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3550                                                                    submitButton.removeClass('inactive').addClass('active');
3551                                                                } else {
3552                                                                    // DISPLAY THE SUCCESS NOTICE
3553                                                                    noticeEle.html(successMessage + ' ' + formError);
3554                                                                    // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3555                                                                    submitButton.removeClass('inactive').addClass('active');
3556                                                                }
3557                                                            } else if (successHandler === 'redirect') {
3558                                                                // REDIRECT TO SUCCESS PAGE
3559                                                                window.location = successRedirect;
3560                                                            } else if (successHandler === 'callback') {
3561                                                                // MAKE SURE CALLBACK IS AN EXISTING FUNCTION
3562                                                                fnExists = typeof window[successCallback] === 'function';
3563                                                                if (fnExists) {
3564                                                                    if (successCallbackParams) {
3565                                                                        window[successCallback].apply(null, successCallbackParams.split(','));
3566                                                                    } else {
3567                                                                        window[successCallback]();
3568                                                                    }
3569                                                                } else {
3570                                                                    console.log(successCallback + ' is not an existing function!');
3571                                                                }
3572                                                                if (successMessage) {
3573                                                                    noticeEle.html(successMessage + ' ' + formError);
3574                                                                } else {
3575                                                                    // DISPLAY THE SUCCESS NOTICE
3576                                                                    noticeEle.html('Thank y
3576ou, your form has been encrypted to protect your privacy and submitted successfully!');
3577                                                                }
3578                                                            } else {
3579                                                                // DISPLAY THE SUCCESS NOTICE
3580                                                                noticeEle.html('Thank you, your form has been encrypted to protect your privacy and submitted successfully!');
3581                                                            }
3582                                                            // RESET THE FORM
3583                                                            form[0].reset();
3584                                                            if (signature) {
3585                                                                signatureEle.jSignature("reset");
3586                                                            }
3587
3588                                                            // SHOW PAGE 1 OF FORM IF PAGINATED/STEPPED & NO ERROR
3589                                                            if(isPaginated === true && !formError) {
3590                                                                // DEACTIVATE SUBMIT BUTTON AGAIN (DIRTY BUT EASIER)
3591                                                                submitButton.removeClass('active').addClass('inactive');
3592
3593                                                                setTimeout(function() {
3594                                                                    jQuery('.gform_page').fadeOut().promise().done(function() {
3595                                                                        jQuery('.gform_page:first').fadeIn().promise().done(function() {
3596                                                                            // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3597                                                                            submitButton.removeClass('inactive').addClass('active');
3598                                                                        });
3599                                                                    });
3600                                                                }, 5000);
3601                                                            } else {
3602                                                                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3603                                                                submitButton.removeClass('inactive').addClass('active');
3604                                                            }
3605                                                        } else {
3606                                                            // JUST A FAIL-SAFE JUST IN CASE WE DON'T ACTUALLY GET A SUCCESS MESSAGE
3607                                                            noticeEle.html(formError);
3608                                                            // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3609                                                            submitButton.removeClass('inactive').addClass('active');
3610                                                        }
3611                                                        hiddenForm.remove();
3612                                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
3613                                                    },
3614                                                    error: function (errorThrown) {
3615                                                        console.log(errorThrown);
3616                                                        noticeEle.html(errorThrown);
3617                                                        hiddenForm.remove();
3618                                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
3619
3620                                                        // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3621                                                        submitButton.removeClass('inactive').addClass('active');
3622                                                    }
3623                                                });
3624                                            }, 500);
3625                                        }
3626                                    }
3627                                });
3628                            } else {
3629                                // SHOW LOADING BAR
3630                                noticeEle.html('<div class="cm-hipaa-forms-progress-wrapper"><div class="cm-hipaa-forms-progress"><div class="cm-hipaa-forms-progress-bar"><!--    <div class="cm-hipaa-forms-progress-label">10%</div>--></div></div></div>');
3631                                cmHipaaFormsProgress();
3632                                // SUBMIT FORM
3633                                jQuery.ajax({
3634                                    method: 'POST',
3635                                    type: 'POST',
3636                                    url: cmHipaaScript.ajax_url,
3637                                    data: {
3638                                        'action': 'cm_hipaa_submit_gravity_form',
3639                                        'formId': formId,
3640                                        'formFields': formFields,
3641                                        'formHtml': hiddenForm.html(),
3642                                        'signature': signature,
3643                                        'nonce': nonce,
3644                                        'selectedUser': selectedUser,
3645                                        'location': location,
3646                                        'locationEmail': locationEmail,
3647                                        'firstName': firstName,
3648                                        'lastName': lastName,
3649                                        'email': email,
3650                                        'phone': phone,
3651                                        'notification_option': notificationOption,
3652                                        'formFound': formFound,
3653                                        'session_id': sessionId
3654                                    },
3655                                    success: function (data) {
3656                                        // var resultData = JSON.parse(data);
3657                                        var resultData;
3658                                        try {
3659                                            resultData = cmHipaaParseAjaxJson(data);
3660                                        } catch (e) {
3661                                            console.log(data);
3662                                            noticeEle.append(data);
3663                                            return false;
3664                                        }
3665
3666                                        var formError = '';
3667                                        if (resultData.error) {
3668                                            formError = resultData.error;
3669                                        }
3670
3671                                        if (resultData.success === 'success') {
3672                                            if(successHandler === 'message') {
3673                                                if(successHideForm === 'hide') {
3674                                                    // HIDE FORM THEN ADD SUCCESS MESSAGE
3675                                                    form.fadeOut().promise().done(function() {
3676                                                        form.after('<div class="cm-hipaa-notice cm-hidden-form-message">' + successMessage + ' ' + formError + '</div>');
3677                                                        jQuery('.cm-hidden-form-message').fadeIn();
3678                                                    });
3679                                                } else {
3680                                                    // DISPLAY THE SUCCESS NOTICE
3681                                                    noticeEle.html(successMessage + ' ' + formError);
3682                                                }
3683                                            } else if(successHandler === 'redirect') {
3684                                                // REDIRECT TO SUCCESS PAGE
3685                                                window.location = successRedirect;
3686                                            } else if(successHandler === 'callback') {
3687                                                // MAKE SURE CALLBACK IS AN EXISTING FUNCTION
3688                                                fnExists = typeof window[successCallback] === 'function';
3689                                                if(fnExists) {
3690                                                    if(successCallbackParams) {
3691                                                        window[successCallback].apply(null, successCallbackParams.split(','));
3692                                                    } else {
3693                                                        window[successCallback]();
3694                                                    }
3695                                                } else {
3696                                                    console.log(successCallback + ' is not an existing function!');
3697                                                }
3698
3699                                                if(successMessage) {
3700                                                    noticeEle.html(successMessage + ' ' + formError);
3701                                                } else {
3702                                                    // DISPLAY THE SUCCESS NOTICE
3703                                                    noticeEle.html('Thank y
3703ou, your form has been encrypted to protect your privacy and submitted successfully!');
3704                                                }
3705                                            } else {
3706                                                // DISPLAY THE SUCCESS NOTICE
3707                                                noticeEle.html('Thank you, your form has been encrypted to protect your privacy and submitted successfully!');
3708                                            }
3709
3710                                            // RESET THE FORM
3711                                            form[0].reset();
3712
3713                                            if(signature) {
3714                                                signatureEle.jSignature("reset");
3715                                            }
3716
3717                                            // SHOW PAGE 1 OF FORM IF PAGINATED/STEPPED & NO ERROR
3718                                            if(isPaginated === true && !formError) {
3719                                                // DEACTIVATE SUBMIT BUTTON AGAIN (DIRTY BUT EASIER)
3720                                                submitButton.removeClass('active').addClass('inactive');
3721
3722                                                setTimeout(function() {
3723                                                    jQuery('.gform_page').fadeOut().promise().done(function() {
3724                                                        jQuery('.gform_page:first').fadeIn().promise().done(function() {
3725                                                            // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3726                                                            submitButton.removeClass('inactive').addClass('active');
3727                                                        });
3728                                                    });
3729                                                }, 5000);
3730                                            } else {
3731                                                // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3732                                                submitButton.removeClass('inactive').addClass('active');
3733                                            }
3734                                        } else {
3735                                            // JUST A FAIL-SAFE JUST IN CASE WE DON'T ACTUALLY GET A SUCCESS MESSAGE
3736                                            noticeEle.html(formError);
3737                                            // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3738                                            submitButton.removeClass('inactive').addClass('active');
3739                                        }
3740
3741                                        hiddenForm.remove();
3742                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
3743
3744                                    },
3745                                    error: function (errorThrown) {
3746                                        console.log(errorThrown);
3747                                        noticeEle.html(errorThrown);
3748                                        hiddenForm.remove();
3749                                        jQuery('.cm-hipaa-forms-hidden-form').remove();
3750
3751                                        // ADD ACTIVE CLASS BACK TO SUBMIT BUTTON
3752                                        submitButton.removeClass('inactive').addClass('active');
3753                                    }
3754                                });
3755                            }
3756                        } else {
3757                            console.log('Error validating Account...');
3758                        }
3759                    },
3760                    error: function (errorThrown) {
3761                        console.log(errorThrown);
3762                    }
3763                });
3764
3765            }
3766        }
3767    });
3768
3769    /*** RESET SIGNATURE ***/
3770    jQuery(document).on('click', '.cm-hipaa-form-signature-reset', function() {
3771        jQuery(this).parent().parent().find('.cm-hipaa-form-signature').jSignature("reset");
3772    });
3773
3774    /*** PRIVACY MODAL WINDOW ***/
3775    jQuery(document).on('click', '.cmprivacy-modal .cmprivacy-close-btn', function() {
3776        jQuery('.cmprivacy-modal').toggle('closed');
3777        jQuery('.cmprivacy-modal-overlay').toggle('closed');
3778    });
3779    jQuery(document).on('click', '.cm-hipaa-privacy-statement a', function(e) {
3780        e.preventDefault();
3781        jQuery('.cmprivacy-modal').toggle('closed');
3782        jQuery('.cmprivacy-modal-overlay').toggle('closed');
3783    });
3784});
3785
3786//Custom progress bar
3787function cmHipaaFormsProgress() {
3788    var elem = jQuery(".cm-hipaa-forms-progress-bar");
3789    var width = 10;
3790    var id = setInterval(frame, 25);
3791    function frame() {
3792        if (width >= 100) {
3793            width = 10;
3794        } else {
3795            width++;
3796            elem.css('width', width + '%');
3797            jQuery(".cm-hipaa-forms-progress-label").html( width + '%');
3798        }
3799    }
3800}
3801
3802//Custom Sanatize inputs
3803function removeTags(str) {
3804    if ((str===null) || (str===''))
3805        return false;
3806    else
3807        str = str.toString();
3808
3809    // Regular expression to identify HTML tags in
3810    // the input string. Replacing the identified
3811    // HTML tag with a null string.
3812    var sanitizedString = str.replace( /(<([^>]+)>)/ig, '');
3813    var sanitizedString2 = sanitizedString.replace(/<img[^>]*?>/g,'');
3814    //console.log(sanitizedString2);
3815
3816    return sanitizedString2;
3817}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.