PageSourceSearch

https://www.floortoceilingcarpet1dickinson.com/root/assets/js/gnix.form.submit.js

js floortoceilingcarpet1dickinson.com collected 2026-09-29 15:08:59 UTC 12,731 bytes, 323 lines download raw bytes

1document.querySelectorAll("form:not(.filter-dropdown-wrapper)").forEach(elem => {
2    elem.addEventListener('submit', function (event) {
3        return handleFormSubmit(event, this);
4    })
5});
6
7$(document).ready(function () {
8    $("div.custom-form").each((index, element) => {
9        const formData = $(element).data();
10        Object.keys(formData).forEach(key => {
11            if (formData[key] == null || formData[key] === "") {
12                delete formData[key];
13            }
14        });
15
16        const pageParams = Object.fromEntries(
17            new URLSearchParams(window.location.search)
18        );
19
20        const mergedParams = {
21            ...pageParams,
22            ...formData
23        };
24
25        const queryString = $.param(mergedParams);
26
27        $.get("/custom/ajax/form?" + queryString, (response) => {
28            $(element).html(response);
29            // if any col-md-6 elements are present, and there are odd number of them switch the last one to col-md-12
30            const colMd6Elements = $(element).find('.col-md-6');
31            if (colMd6Elements.length > 0 && colMd6Elements.length % 2 !== 0) {
32                colMd6Elements.last().removeClass('col-md-6').addClass('col-md-12');
33			}
34            // Initialize Parsley validation
35            const form = $(element).find("form");
36            form.parsley();
37
38            // Attach submit handler to the custom form
39            form.on('submit', function (event) {
40                return handleFormSubmit(event, this);
41            });
42
43            //update hidden input PageURL and LeadSourceUrl to the current page URL
44            const pageUrl = window.location.href;
45            $(element).find('input[name="PageURL"]').val(pageUrl);
46            $(element).find('input[name="LeadSourceUrl"]').val(pageUrl);
47        }).fail(() => {
48            console.error("Failed to load custom form.");
49        });
50    });
51});
52
53var gnixFormIsProcessing = false;
54function handleFormSubmit(event, cForm) {
55    if(gnixFormIsProcessing){
56        return false; // form is already processing        
57    }
58    if (window.jQuery && $(cForm).parsley().isValid()) {
59        event.preventDefault();
60        gnixFormIsProcessing = true;
61        buttonIsProcessing(true, cForm);
62
63        let canadaPostalPattern = /[A-CEGHJ-NPRSTVXYa-ceghj-nprstvxy]\d[A-CEGHJ-NPRSTV-Za-ceghj-nprstv-z][ -]?\d[A-CEGHJ-NPRSTV-Za-ceghj-nprstv-z]\d/g;
64        if ($(cForm).find("[name=PostalCode]").length && $(cForm).find("[name=PostalCode]").val().length > 0 && canadaPostalPattern.test($(cForm).find("[name=PostalCode]").val().trim())) {
65            cForm.submit();
66            gnixFormIsProcessing = false;
67            buttonIsProcessing("submitted", cForm);
68        } else {
69            fetchLeadOrigin(cForm).then(() => {
70                leadCleanUp(cForm);
71                if (window.grecaptcha && window.globalRecaptchaKey) {
72                    grecaptcha.ready(function () {
73                        grecaptcha.execute(window.globalRecaptchaKey, {
74                            action: 'submit'
75                        }).then(function (token) {
76                            $(cForm).find('.g-recaptcha-response').val(token);
77                            handleFormSubmission(event, cForm);
78                        });
79                    });
80                } else {
81                    handleFormSubmission(event, cForm);
82                }
83             }).catch(() => {
84            });
85        }
86    }
87    return false;
88}
89
90function leadCleanUp(cForm) {
91    if ($("input[name='Phone']", $(cForm)).length > 0) {
92        var cleanphone = $("input[name='Phone']", $(cForm)).val();
93        $("input[name='Phone']", $(cForm)).val(cleanphone.replace(/\D/g, ''))
94    }
95
96    if ($("input[name='CleanHomePhone']", $(cForm)).length > 0) {
97        var cleanphone = $("input[name='CleanHomePhone']", $(cForm)).val();
98        $("input[name='CleanHomePhone']", $(cForm)).val(cleanphone.replace(/\D/g, ''))
99    }
100
101    if ($("input[name='CleanMobilePhone']", $(cForm)).length > 0) {
102        var cleanphone = $("input[name='CleanMobilePhone']", $(cForm)).val();
103        $("input[name='CleanMobilePhone']", $(cForm)).val(cleanphone.replace(/\D/g, ''))
104    }
105
106    var notesField = $("input[name=OpportunityNotes]", $(cForm));
107    if (notesField.length == 0) {
108        notesField = $("textarea[name=OpportunityNotes]", $(cForm));
109    }
110
111    if (notesField.length > 0) {
112        let messageField = $("textarea[name=MyMessage]", $(cForm));
113        if (messageField.length == 0) {
114            messageField = $("textarea[name=Message]", $(cForm));
115        }
116
117        var notesVal = "";
118
119        if (messageField && messageField.length > 0) {
120            notesVal += messageField.val();
121        }
122
123        $(".add-to-notes").each(function () {
124            if ($(this).find("input").attr("name") && $(this).find("input").attr("name") !== undefined) {
125                notesVal += "\n\n" + $(this).find("input").attr("name") + ": " + $(this).find("input").val();
126            }
127
128            // Also check for select elements within .add-to-notes
129            if ($(this).find("textarea").attr("name") && $(this).find("textarea").attr("name") !== undefined) {
130                notesVal += "\n\n" + $(this).find("textarea").attr("name") + ": " + $(this).find("textarea").val();
131            }
132
133            if ($(this).find("select").attr("name") && $(this).find("select").attr("name") !== undefined) {
134                notesVal += "\n\n" + $(this).find("select").attr("name") + ": " + $(this).find("select").val();
135            }
136        })
137
138        $(notesField).val(notesVal);
139    }
140}
141
142function handleFormSubmission(event, cForm) {
143    if (event.target.className.indexOf("external-form-handling") == -1) {
144        if (event.target.className.indexOf("gnix-ajax-form") > -1) {
145            submitViaAjax(cForm);
146        } else {
147            cForm.submit();
148        }
149    }
150       gnixFormIsProcessing = false;
151       buttonIsProcessing("submitted", cForm);
152}
153
154function submitViaAjax(formElem) {
155    /* get the action attribute from the <form action=""> element */
156    var $form = $(formElem),
157        url = $form.attr('action');
158    /* Send the data using post with element id name and name2*/
159
160    $form.children('[type=submit]').addClass("disabled");
161    var origText = $form.children('[type=submit]').html();
162    $form.children('[type=submit]').html(`<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>`);
163
164    if (!url) {
165        url = window.location;
166    }
167
168    $.ajax({
169        url: url,
170        type: 'POST',
171        data: $form.serialize()
172    }).done(function (result) {
173        $form.addClass("d-none");
174        $form.parent().children("div.form-thank-you").removeClass("d-none");
175    }).fail(function (result) {
176        // Try to parse the response text as JSON
177        try {
178            if (result.responseText) {
179                const errorResponse = JSON.parse(result.responseText);
180                handleServerValidationErrors($form, errorResponse);
181            }
182        } catch (e) {
183            console.error("Could not parse error response:", e);
184        }
185        $form.children('[type=submit]').removeClass("disabled");
186        $form.children('[type=submit]').html(origText);
187    }).always(function (result) {
188        $form.children('[type=submit]').removeClass("disabled");
189        $form.children('[type=submit]').html(origText);
190    });
191}
192
193function buttonIsProcessing(state, cForm) {
194    var $btn = $(cForm).find('button[type=submit]');
195
196    if (state === true) {
197        // Start processing: disable + show spinner
198        if (!$btn.data('original-html')) {
199            $btn.data('original-html', $btn.html());
200        }
201        $btn.prop('disabled', true);
202        $btn.html('<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>Processing...');
203
204    } else if (state === false) {
205        // Reset: restore original
206        $btn.prop('disabled', false);
207        if ($btn.data('original-html')) {
208            $btn.html($btn.data('original-html'));
209            $btn.removeData('original-html');
210        }
211
212    } else if (state === "submitted") {
213        // Final state: disable + show "Form Submitted"
214        if (!$btn.data('original-html')) {
215            $btn.data('original-html', $btn.html());
216        }
217        $btn.prop('disabled', true);
218        $btn.text("Form Submitted"); // no spinner, just text
219    }
220}
221
222function handleServerValidationErrors($form, response) {
223    // Check if we have errors to display in the ValidationProblemDetails format
224    if (response && response.errors) {
225        // Get all error fields
226        const errorFields = Object.keys(response.errors);
227
228        // Check if the only error is related to g-recaptcha
229        const isOnlyCaptchaError = errorFields.length === 1 && errorFields[0] === "g-recaptcha";
230
231        // Only show captcha modal if it's the only error
232        if (isOnlyCaptchaError) {
233            showCaptchaModal();
234        }
235
236        // Process each error field
237        errorFields.forEach(function (fieldName) {
238            const errorMessages = response.errors[fieldName];
239
240            if (fieldName && errorMessages && errorMessages.length > 0) {
241                // Find the field by name
242                const $field = $form.find(`[name="${fieldName}"]`);
243
244                if ($field.length > 0) {
245                    // Get the Parsley instance for this field
246                    const fieldInstance = $field.parsley();
247
248                    if (fieldInstance) {
249                        // Create a unique error name to avoid conflicts
250                        const errorName = fieldName + "-custom";
251
252                        // Remove any existing errors with this name
253                        fieldInstance.removeError(errorName, { updateClass: true });
254
255                        // Add the new error message
256                        fieldInstance.addError(errorName, {
257                            message: errorMessages[0], // Use the first error message
258                            updateClass: true
259                        });
260
261                        // Remove existing event handlers to prevent duplicates
262                        $field.off('focus.customError input.customError change.customError');
263
264                        // Add event handlers to clear errors when field is focused and then changed
265                        $field.on('focus.customError', function () {
266                            // Store reference to the field for the change event
267                            $(this).data('focused', true);
268                        });
269
270                        // Handle input/change events
271                        $field.on('input.customError change.customError', function () {
272                            // Only process if field was previously focused
273                            if ($(this).data('focused') && $(this).val().trim() !== '') {
274                                const fieldInstance = $(this).parsley();
275                                if (fieldInstance) {
276                                    // Remove the custom error
277                                    fieldInstance.removeError(errorName, { updateClass: true });
278
279                                    // If no other errors exist, remove error class
280                                    if (fieldInstance.isValid()) {
281                                        $(this).removeClass('parsley-error');
282                                        $(this).addClass('parsley-success');
283                                    }
284                                }
285                            }
286                        });
287                    }
288                }
289            }
290        });
291
292        // Focus on the first field with an error
293        const $firstErrorField = $form.find('.parsley-error').first();
294        if ($firstErrorField.length > 0) {
295            $firstErrorField.focus();
296        }
297    }
298}
299
300async function fetchLeadOrigin(formElem) {
301    var hiddenInput = $(formElem).find('input[name="__leadOrigin"]');
302    if (hiddenInput.length === 0) {
303        // If the hidden input doesn't exist, create it
304        hiddenInput = $('<input>', {
305            type: 'hidden',
306            name: '__leadOrigin'
307        }).appendTo(formElem);
308    }
309
310    try {
311        const response = await fetch("https://api.ipify.org/?format=json");
312        const data = await response.json();
313        if (data) {
314            // && data.serverVariables && data.serverVariables.RemoteIpAddress) {
315            let leadOrigin = btoa(data.ip);
316            hiddenInput.val(leadOrigin);
317        } else {
318            hiddenInput.val(btoa("0.0.0.0"));
319        }
320    } catch (error) {
321        hiddenInput.val(btoa("0.0.0.0"));
322    }
323}

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.