PageSourceSearch

https://www.strongbytamko.com/wp-content/plugins/rsra-contractors-…a-contractors-form-public.js?ver=1791585585

js strongbytamko.com collected 2026-10-09 22:40:17 UTC 22,604 bytes, 502 lines download raw bytes

1(function($) {
2    'use strict';
3
4    // DISABLED FOR TESTING
5    // let turnstileWidgetId = null;
6    // window.onloadTurnstileCallback = function() {
7    //     if ($('.rsra-modal-overlay').hasClass('is-visible')) { renderTurnstile(); }
8    // };
9    // function renderTurnstile() {
10    //     if (typeof turnstile !== 'undefined' && typeof rsra_form_ajax !== 'undefined' && rsra_form_ajax.turnstile_site_key && $('.cf-turnstile-widget').length && !turnstileWidgetId) {
11    //         turnstileWidgetId = turnstile.render('.cf-turnstile-widget', { sitekey: rsra_form_ajax.turnstile_site_key, callback: function(token) {} });
12    //     }
13    // }
14    let turnstileWidgetId = null; // kept so resetUI references don't break
15
16    // Domains allowed to embed this form in an iframe and receive postMessage.
17    const allowedParentDomains = ['codesignery.com', 'tamko.com', 'rsa.pro'];
18
19    /**
20     * Redirect after successful submission.
21     * If running inside an iframe from an allowed domain, sends a postMessage
22     * to the parent instead of redirecting the iframe itself.
23     * Falls back to normal redirect in all other cases.
24     */
25    function handleRedirect(url, meta) {
26        meta = meta || {};
27        if (window !== window.top) {
28            try {
29                const ref = document.referrer;
30                const isAllowed = allowedParentDomains.some(d => ref.indexOf(d) !== -1);
31                if (isAllowed) {
32                    let parentOrigin = '*';
33                    try { parentOrigin = new URL(ref).origin; } catch (e) {}
34                    window.parent.postMessage({
35                        type: 'rsra_form_success',
36                        redirect: url,
37                        role: meta.role || ''
38                    }, parentOrigin);
39                    return;
40                }
41            } catch (e) {}
42        }
43        window.location.href = url;
44    }
45
46    $(function() { 
47        
48        // --- Custom Popup Logic ---
49		function showPopup(title, message, type = 'error') {
50			const overlay = $('#rsra-message-overlay');
51			const box = overlay.find('.rsra-message-box');
52			const iconContainer = $('#rsra-message-icon');
53
54			$('#rsra-message-title').text(title);
55			$('#rsra-message-text').text(message);
56
57			box.removeClass('rsra-msg-error rsra-msg-success');
58
59			if (type === 'success') {
60				box.addClass('rsra-msg-success');
61				iconContainer.html('✔'); 
62			} else {
63				box.addClass('rsra-msg-error');
64				iconContainer.html('⚠'); 
65			}
66
67			overlay.addClass('is-active');
68		}
69
70		$('#rsra-message-close').on('click', function() {
71			$('#rsra-message-overlay').removeClass('is-active');
72		});
73
74        // --- Time Trap ---
75		const formLoadTime = Math.floor(Date.now() / 1000);
76        
77        const modalOverlay = $('.rsra-modal-overlay');
78        const form = $('#rsra-contractor-form');
79        const submitButton = form.find('.rsra-submit-button');
80        let phoneInputInstance = null;
81        let debounceTimer;
82
83        const roleDisplayMap = {
84            'sole-owner': 'Sole Owner',
85            'co-owner': 'Co-Owner',
86            'manager': 'Manager',
87            'sales-rep': 'Sales Rep'
88        };
89
90        const formNameMap = {
91            'cf5': 'Contractors Join Data v5',
92            'ftc5': 'Contractors Join FTC Data v5',
93            'rmr2': 'Contractors Join RMR v2',
94            'rmsp': 'Contractors Join RMSP'
95        };
96
97        function setCookie(name, value, days) {
98            let expires = "";
99            if (days) {
100                const date = new Date();
101                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
102                expires = "; expires=" + date.toUTCString();
103            }
104            document.cookie = name + "=" + (value || "") + expires + "; path=/";
105        }
106
107        function getCookie(name) {
108            const nameEQ = name + "=";
109            const ca = document.cookie.split(';');
110            for (let i = 0; i < ca.length; i++) {
111                let c = ca[i];
112                while (c.charAt(0) === ' ') c = c.substring(1, c.length);
113                if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
114            }
115            return null;
116        }
117
118        function eraseCookie(name) {
119            document.cookie = name + '=; Path=/; Expires=Thu, 01 Jan 1900 00:00:01 GMT;';
120        }
121
122        function generateUniqueId() {
123            return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
124        }
125
126        function getDynamicLocalStorageKey() {
127            const formId = $('#rsra-form-id').val();
128            return formId ? 'rsra_form_progress_' + formId : null;
129        }
130
131        function initializePhoneInput(selector) {
132             if (!$(selector).length) return null;
133             return window.intlTelInput(document.querySelector(selector), {
134                initialCountry: "auto",
135                separateDialCode: true,
136                dropdownContainer: document.body,
137                showSearchInput: true,
138                geoIpLookup: function(callback) {
139                    $.get("https://ipapi.co/json", function() {}, "jsonp").always(function(resp) {
140                        var countryCode = (resp && resp.country_code) ? resp.country_code : "us";
141                        callback(countryCode);
142                    });
143                },
144                utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.13/js/utils.js",
145            });
146        }
147
148        function openModal() {
149            $('body').addClass('rsra-modal-open');
150            modalOverlay.addClass('is-visible');
151            if (!phoneInputInstance) {
152                phoneInputInstance = initializePhoneInput("#rsra-phone");
153            }
154            loadProgress();
155             renderTurnstile();
156        }
157
158        function closeModal() {
159            $('body').removeClass('rsra-modal-open');
160            modalOverlay.removeClass('is-visible');
161        }
162
163        function validateForm() {
164            const inputs = form.find('input:visible[required], select:visible[required]');
165            let isValid = true;
166            inputs.each(function() {
167                if ($(this).attr('name') === 'rsra_honeypot') { return true; }
168                if (!this.checkValidity()) { isValid = false; return false; }
169            });
170
171            // DISABLED FOR TESTING
172            // const turnstileResponse = form.find('[name="cf-turnstile-response"]').val();
173            // if (!turnstileResponse) { isValid = false; }
174
175            // SMS consent is a single required checkbox - it must be ticked.
176            var consentChecked = form.find('[name="sms_consent"]').is(':checked');
177            if (!consentChecked) {
178                form.find('.rsra-sms-consent-required').show();
179                return false;
180            }
181            form.find('.rsra-sms-consent-required').hide();
182
183            var tamkoProVal = form.find('[name="tamko_pro_status"]:checked').val();
184            if (!tamkoProVal) {
185                form.find('.rsra-tamko-pro-required').show();
186                isValid = false;
187                return false;
188            }
189            form.find('.rsra-tamko-pro-required').hide();
190
191            if (!isValid) {
192                 let firstInvalid = null;
193                 inputs.each(function() {
194                     if (!this.checkValidity() && $(this).attr('name') !== 'rsra_honeypot') {
195                         firstInvalid = this;
196                         return false;
197                     }
198                 });
199                 if(firstInvalid){ form[0].reportValidity(); }
200            }
201            return isValid;
202        }
203
204        function collectFormData() {
205            return {
206                role:       $('#rsra-role-select').val(),
207                firstName:  $('#rsra-first-name').val(),
208                lastName:   $('#rsra-last-name').val(),
209                email:      $('#rsra-email').val(),
210                phone:      phoneInputInstance ? phoneInputInstance.getNumber() : '',
211                smsConsent: form.find('[name="sms_consent"]:checked').val() || '',
212                tamkoPro:   form.find('[name="tamko_pro_status"]:checked').val() || ''
213            };
214        }
215        
216        function getHtmlFormattedData(data) {
217            const properRoleName = roleDisplayMap[data.role] || data.role || '';
218            let html = `<div><b><span>1.</span>Select Your Role*: </b>${properRoleName}</div>`;
219            html += `<div><b><span>2.</span>What is Your First Name?*: </b>${data.firstName || ''}</div>`;
220            html += `<div><b><span>
2203.</span>What is Your Last Name?*: </b>${data.lastName || ''}</div>`;
221            html += `<div><b><span>4.</span>What is Your Email Address?*: </b>${data.email || ''}</div>`;
222            html += `<div><b><span>5.</span>What is Your Best Contact Number?*: </b>${data.phone || ''}</div>`;
223            html += `<div><b><span>6.</span>SMS Consent: </b>${data.smsConsent || ''}</div>`;
224            html += `<div><b><span>7.</span>TAMKO PRO GOLD/PLATINUM/DIAMOND Contractor: </b>${data.tamkoPro || ''}</div>`;
225            return html;
226        }
227
228        function getDynamicCookieName() {
229            const formId = $('#rsra-form-id').val();
230            return formId ? 'cf_cookie_' + formId : null;
231        }
232
233        function saveProgress() {
234            const localStorageKey = getDynamicLocalStorageKey();
235            if (!localStorageKey) return;
236            const formData = collectFormData();
237            const jsonString = JSON.stringify(formData);
238            try {
239                localStorage.setItem(localStorageKey, jsonString);
240            } catch (e) { console.error('Could not save to local storage.', e); }
241            saveProgressToDB(formData);
242        }
243        
244        function saveProgressToDB(formData) {
245            const formId = $('#rsra-form-id').val();
246            const cookieName = getDynamicCookieName();
247            if (!cookieName) return;
248            const cookieId = getCookie(cookieName);
249            if (!cookieId) return;
250
251             $.ajax({
252                url: rsra_form_ajax.ajax_url,
253                type: 'POST',
254                data: {
255                    action: 'rsra_save_form_progress',
256                    nonce: rsra_form_ajax.nonce,
257                    form_id: formId,
258                    cf_cookie: cookieId,
259                    cf_data: JSON.stringify(formData),
260                    cf_data_all: getHtmlFormattedData(formData)
261                }
262            });
263        }
264
265        function populateFormFromJSON(jsonString) {
266            try {
267                const data = jsonString ? JSON.parse(jsonString) : {};
268                $('#rsra-role-select').val(data.role || '');
269                $('#rsra-first-name').val(data.firstName || '');
270                $('#rsra-last-name').val(data.lastName || '');
271                $('#rsra-email').val(data.email || '');
272                if (phoneInputInstance) {
273                    phoneInputInstance.setNumber(data.phone || '');
274                }
275            } catch (e) { console.error("Error parsing form data from JSON:", e); }
276        }
277
278        function loadProgress() {
279            const localStorageKey = getDynamicLocalStorageKey();
280            if (!localStorageKey) { populateFormFromJSON(null); return; }
281
282            try {
283                const localData = localStorage.getItem(localStorageKey);
284                if (localData) { populateFormFromJSON(localData); return; }
285            } catch (e) { console.error('Could not read from local storage.', e); }
286
287            const cookieName = getDynamicCookieName();
288            const cookieId = getCookie(cookieName);
289            if (!cookieId) { populateFormFromJSON(null); return; };
290            
291            $.ajax({
292                url: rsra_form_ajax.ajax_url,
293                type: 'POST',
294                data: {
295                    action: 'rsra_get_form_progress',
296                    nonce: rsra_form_ajax.nonce,
297                    form_id: $('#rsra-form-id').val(),
298                    cf_cookie: cookieId,
299                },
300                success: function(response) {
301                    if (response.success && response.data) { populateFormFromJSON(response.data); } 
302                    else { populateFormFromJSON(null); }
303                },
304                error: function() { populateFormFromJSON(null); }
305            });
306        }
307
308        $(document).on('click', '.rsraContractorsForm', function(e) {
309            e.preventDefault();
310            modalOverlay.find('.rsra-modal-title').text('Get Your Private Tour');
311            form.show();
312            let formId = null;
313            const classes = $(this).attr('class').split(' ');
314            classes.forEach(function(className) {
315                if (className.startsWith('form-id-')) { formId = className.replace('form-id-', ''); }
316            });
317            if (!formId) { formId = $(this).data('form-id'); }
318            if (!formId) {
319                modalOverlay.find('.rsra-modal-title').text('Configuration Error');
320                form.hide();
321                modalOverlay.addClass('is-visible');
322                return;
323            }
324            $('#rsra-form-id').val(formId);
325            const cookieName = getDynamicCookieName();
326            let cookieId = getCookie(cookieName);
327            if (!cookieId) {
328                cookieId = generateUniqueId();
329                setCookie(cookieName, cookieId, 30);
330            }
331            openModal();
332        });
333
334        $('.rsra-close-button').on('click', function(e) { e.preventDefault(); closeModal(); });
335        modalOverlay.on('click', function(e) { if ($(e.target).is(modalOverlay)) { closeModal(); } });
336        
337        form.on('mousedown', 'select', function() {
338             if ($(this).find('option[value=""]').length > 0) {
339                 $(this).find('option[value=""]').remove();
340             }
341        });
342
343        form.on('input change', 'input, select', function() { clearTimeout(debounceTimer); debounceTimer = setTimeout(saveProgress, 500); });
344        form.on('change', '[name="sms_consent"]', function() {
345            form.find('.rsra-sms-consent-required').toggle(!this.checked);
346        });
347        form.on('change', '[name="tamko_pro_status"]', function() {
348            form.find('.rsra-tamko-pro-required').hide();
349        });
350
351        form.on('submit', function(e) {
352            e.preventDefault();
353            
354            if (!validateForm()) { return; }
355            
356            const originalButtonText = submitButton.html();
357            submitButton.prop('disabled', true).html('<span class="rsra-spinner"></span> Submitting...');
358            form.addClass('form-loading');
359
360            // const siteKey = rsra_recaptcha_data.site_key; // DISABLED FOR TESTING
361            // grecaptcha.ready(function() { // DISABLED FOR TESTING
362            //     grecaptcha.execute(siteKey, {action: 'submit'}).then(function(recaptchaToken) { // DISABLED FOR TESTING
363            (function() {
364                var recaptchaToken = '';
365                    $('#rsra_recaptcha_token').val(recaptchaToken);
366
367                    const cookieName = getDynamicCookieName();
368                    const localStorageKey = getDynamicLocalStorageKey();
369                    const cookieId = getCookie(cookieName);
370                    let formData = collectFormData();
371                    
372                    const honeypotValue = form.find('input[name="rsra_honeypot"]').val();
373                    const turnstileResponse = form.find('[name="cf-turnstile-response"]').val();
374
375                    // --- Define Zapier Logic (To be called later) ---
376                    const formId = $('#rsra-form-id').val();
377                    const selectedRole = formData.role;
378                    const tamkoPro = formData.tamkoPro || '';
379                    const tamkoProZapierUrl = (rsra_form_ajax.tamko_pro_zapier_url || '');
380                    let zapierUrl = null;
381
382                    if (tamkoPro === 'yes' && tamkoProZapierUrl) {
383                        zapierUrl = tamkoProZapierUrl;
384                    } else if (selectedRole === 'sales-rep') {
385                        zapierUrl = 'https://hooks.zapier.com/hooks/catch/809273/u5evq9r/';
386                    } else {
387                        if (formId === 'cf5') { zapierUrl = 'https://hooks.zapier.com/hooks/catch/809273/u1n0eku/'; }
388                        else if (formId === 'ftc5') { zapierUrl = 'https://hooks.zapier.com/hooks/catch/809273/u5c9jz9/'; }
389                        else if (formId === 'rmr2') { zapierUrl = 'https://hooks.zapier.com/hooks/catch/809273/u5c5ymn/'; }
390                        else if (formId === 'rmsp') { zapierUrl = 'https://hooks.zapier.com/hooks/catch/809273/uc12eal/'; }
391                    }
392
393                    const zapierData = {
394                        'Unique Id':            cookieId,
395                        'Form':                 formNameMap[formId] || formId,
396                        'Role':                 roleDisplayMap[formData.role] || formData.role,
397                        firstName:              formData.firstName,
398                        lastName:               formData.lastName,
399                        email:                  formData.email,
400                        'Contact Number':       formData.phone,
401                        'SMS Consent':          formData.smsConsent,
402                        'TAMKO PRO Contractor': tamkoPro,
403                    };
404
405                    // --- Define Submit to WordPress ---
406                    const submitToWordPress = () => {
407                        $.ajax({
408                            url: rsra_form_ajax.ajax_url,
409                            type: 'POST',
410                            data: {
411                                action: 'rsra_submit_form',
412                                nonce: rsra_form_ajax.nonce,
413                                form_id: $('#rsra-form-id').val(),
414                                cf_cookie: cookieId,
415                                cf_data: JSON.stringify(formData),
416                                cf_data_all: getHtmlFormattedData(formData),
417                                rsra_honeypot: honeypotValue,
418                                'cf-turnstile-response': turnstileResponse,
419                                'rsra_recaptcha_token': recaptchaToken,
420								rsra_form_load_time: formLoadTime
421                            },
422                            success: function(response) {
423                                if (response.success && response.data.redirect) {
424                                    
425                                    // 1. Success! Clean Up Local State
426                                    if (localStorageKey) {
427                                        try { localStorage.removeItem(localStorageKey); } catch (e) { console.error(e); }
428                                    }
429                                    eraseCookie(cookieName);
430                                    form[0].reset();
431                                    if (typeof turnstile !== 'undefined' && turnstileWidgetId) { turnstile.reset(turnstileWidgetId); }
432                                    
433                                    // 2. NOW Send to Zapier (Only because WordPress gave success/green light)
434                                    if(zapierUrl){
435                                        fetch(zapierUrl, {
436                                            method: 'POST',
437                                            body: JSON.stringify(zapierData)
438                                        })
439                                        .then(() => {
440                                            // 3a. Redirect after Zapier
441                                            handleRedirect(response.data.redirect, { role: formData.role });
442                                        })
443                                        .catch(error => {
444                                            // 3b. Redirect even if Zapier fails (don't block user)
445                                            console.error('Zapier Error:', error);
446                                            handleRedirect(response.data.redirect, { role: formData.role });
447                                        });
448                                    } else {
449                                        // 3c. Redirect immediately if no Zapier
450                                        handleRedirect(response.data.redirect, { role: formData.role });
451                                    }
452
453                                } else {
454                                    // Error State (Spam/Block) -> Do NOT send to Zapier
455                                   	showPopup('Submission Issue', response.data || 'Please try again.', 'error');
456        							resetUI();
457                                }
458                            },
459                            error: function(xhr) {
460                                let errorMsg = 'An unexpected error occurred.';
461                                if(xhr.responseJSON && xhr.responseJSON.data){ errorMsg = xhr.responseJSON.data; }
462                                showPopup('Notice', errorMsg, 'error');
463    							resetUI();
464                            }
465                        });
466                    };
467
468                    function resetUI() {
469                        submitButton.prop('disabled', false).html(originalButtonText);
470                        form.removeClass('form-loading');
471                        if (typeof turnstile !== 'undefined' && turnstileWidgetId) { turnstile.reset(turnstileWidgetId); }
472                    }
473
474                    // --- EXECUTE: Call WordPress FIRST ---
475                    submitToWordPress();
476
477            // }); // DISABLED FOR TESTING
478            // }); // DISABLED FOR TESTING
479            })();
480        });
481
482        window.addEventListener('pageshow', function(event) {
483            if (event.persisted) {
484                const originalButtonText = 'Submit';
485                submitButton.prop('disabled', false).html(originalButtonText);
486                form.removeClass('form-loading');
487                form[0].reset();
488                try {
489                    localStorage.removeItem(getDynamicLocalStorageKey());
490                } catch (e) { console.error(e); }
491                populateFormFromJSON(null);
492                 if (typeof turnstile !== 'undefined' && turnstileWidgetId) {
493                    $('.cf-turnstile-widget').empty();
494                    turnstileWidgetId = null;
495                    renderTurnstile();
496                 }
497            }
498        });
499		
500    });
501
502})(jQuery);

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.