PageSourceSearch

https://ph3a.com.br/Content/site/js/zohoform.js

js ph3a.com.br collected 2026-10-09 18:06:44 UTC 11,026 bytes, 353 lines download raw bytes

1/*!
2* JavaScript para validacoes do Formulario do zoho
3*/
4$(document).ready(function () {
5    const $birthDate = $("#Date");
6
7    if ($birthDate.length) {
8        $birthDate.attr("placeholder", "--/--/----");
9        $birthDate.attr("autocomplete", "off");
10        $birthDate.attr("inputmode", "numeric");
11        $birthDate.on("input", function () {
12            this.value = DateMask(this.value);
13        });
14        $birthDate.on("blur", function () {
15            ValidateFields("Date", this.value);
16        });
17
18        if (typeof AirDatepicker === "function") {
19            new AirDatepicker("#Date", {
20                locale: {
21                    days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"],
22                    daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"],
23                    daysMin: ["Do", "Se", "Te", "Qa", "Qi", "Se", "Sa"],
24                    months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
25                    monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"],
26                    today: "Hoje",
27                    clear: "Limpar",
28                    dateFormat: "dd/MM/yyyy",
29                    timeFormat: "HH:mm",
30                    firstDay: 0
31                },
32                autoClose: true,
33                dateFormat: "dd/MM/yyyy",
34                maxDate: new Date(),
35                onSelect: function () {
36                    ValidateFields("Date", $birthDate.val());
37                }
38            });
39        }
40    }
41
42    $(".input-custom").on('focusout', function () {
43        const _ = this;
44        let name = _.getAttribute('name');
45        let value = _.value;
46        ValidateFields(name, value);
47    });
48
49    $("#Privacy_Policy").on('change', function () {
50        ValidateCheckbox();
51    });
52
53    $("#zoho-form").submit(function (e) {
54        e.preventDefault();
55        const inputs = document.querySelectorAll('.input-custom');
56        let error = 0;
57        let success = 0;
58        for (const input of inputs) {
59            let name = input.getAttribute('name');
60            let value = input.value;
61            success = ValidateFields(name, value, 'form');
62            if (error == 0 && !success) { $(`#${name}`).focus(); error++; }  //focus first error
63        }
64
65        if (!ValidateCheckbox() && error == 0) {
66            error++;
67        }
68
69        //submit form
70        if (error == 0) {
71            //set url de retorno
72            let successUrl = window.location.href;
73            $("[name='zf_redirect_url']").val(`https://ph3a.com.br/lp/obrigado?utm=site`);
74            syncZohoProductFields();
75            //set date to zoho format (dd-mm-yyyy)
76            let _date = $('#Date').val();
77            _date = NormalizeZohoDate(_date);
78            $("#Date").attr("type", "text").val(_date);
79
80            $("#Btn_Zoho").attr("disabled", true);
81            this.submit();
82        }
83    });
84
85    $("[data-js='telefone-comercial']").on('input', function (e) { e.target.value = PhoneMask(e.target.value, 'telefone') });
86    $("[data-js='telefone-celular']").on('input', function (e) { e.target.value = PhoneMask(e.target.value, 'celular') });
87
88    function getQueryParameter(name) {
89        const urlParams = new URLSearchParams(window.location.search);
90        return urlParams.get(name) || "";
91    }
92
93    /* UTM: para rastrear as campanhas */
94    $('input[name="utm_source"]').val(getQueryParameter("utm_source"));
95    $('input[name="utm_campaign"]').val(getQueryParameter("utm_campaign"));
96    $('input[name="utm_medium"]').val(getQueryParameter("utm_medium"));
97    syncZohoProductFields();
98
99    /* Produto de interesse: mapeado pela rota produto */
100    function getZohoProductFromUrl() {
101        const path = window.location.pathname.toLowerCase();
102
103        const map = {
104            "/produto/databusca": "DataBusca",
105            "/produto/datatag": "DataTag",
106            "/produto/datafraud": "DataFraud",
107            "/produto/datadossie": "DataDossiê",
108            "/produto/datarc6": "DataRC6",
109            "/produto/datacubobi": "DataCuboBI"
110        };
111
112        return map[path] || "Chat - produto não especificado";
113    }
114
115    function setOrCreateHiddenField(targetForm, name, value) {
116        let field = targetForm.querySelector(`input[name='${name}']`);
117        if (!field) {
118            field = document.createElement("input");
119            field.type = "hidden";
120            field.name = name;
121            field.id = name;
122            targetForm.appendChild(field);
123        }
124        field.value = value;
125    }
126
127    function syncZohoProductFields() {
128        const targetForm = document.getElementById("zoho-form");
129        if (!targetForm) {
130            return;
131        }
132
133        const produto = getZohoProductFromUrl();
134        if (!produto) {
135            return;
136        }
137
138        setOrCreateHiddenField(targetForm, "Dropdown", produto);
139        setOrCreateHiddenField(targetForm, produto, produto);
140    }
141
142    function NormalizeZohoDate(value) {
143        const date = (value || "").trim();
144
145        // dd/mm/yyyy -> dd-mm-yyyy
146        let match = date.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
147        if (match) {
148            return `${match[1]}-${match[2]}-${match[3]}`;
149        }
150
151        // yyyy-mm-dd -> dd-mm-yyyy
152        match = date.match(/^(\d{4})-(\d{2})-(\d{2})$/);
153        if (match) {
154            return `${match[3]}-${match[2]}-${match[1]}`;
155        }
156
157        return date;
158    }
159
160});
161
162//Zoho Validation Fields
163function ValidateFields(name, value, tipo) {
164    let x = true;
164 //caso o status seja alterado para false, nao submete
165
166    switch (name) {
167        case 'Full_Name':
168            x = ValidateFullName();
169            break;
170        case 'SingleLine':
171        case 'MultiLine':
172            x = ValidateLength();
173            break;
174        case 'Email':
175            x = ValidateEmail();
176            break;
177        case 'SingleLine3':
178        case 'SingleLine4':
179            let phoneType = name == 'SingleLine3' ? 'phone' : 'cell';
180            x = ValidatePhone(phoneType);
181            break;
182        case 'Dropdown':
183        case 'Dropdown1':
184            x = value == 0 ? false : true;
185            DisplayError(!x);
186            break;
187        case 'Date':
188            x = ValidateDate();
189            break;
190    }
191
192    return (x) ? true : false;
193
194    //Global Validations
195    function DisplayError(error) {
196        const errorElement = $(`#${name}`).closest("._group").find("._error").first();
197        error ? errorElement.show() : errorElement.hide();
198    }   
199
200    function ValidateLength() {
201        let x = (value.trim().length <= 0) ? false : true;
202        DisplayError(!x)
203        return x;
204    }
205
206    function ValidateDate() {
207        let parsedDate = ParseBrazilianDate(value);
208        let x = parsedDate !== null;
209        DisplayError(!x);
210        return x;
211    }
212
213    function ValidateFullName() {
214
215        let err = false;
216
217        if (value.trim().length <= 0) {
218            err = 1;
219        }
220
221        let nameParts = value.trim().split(" ");
222        if (nameParts.length < 2) {
223            err = 1;
224        }
225
226        let isValidPart = /^[a-zA-Z\u00C0-\u017F\s]+$/;
227        for (let part of nameParts) {
228            if (!isValidPart.test(part)) {
229                err = 1;
230            }
231        }
232
233        if (err) {
234            DisplayError(true);
235            return false;
236        } else {
237            const firstName = nameParts.shift().trim();
238            const lastName = nameParts.join(" ").trim();
239            $('input[name="Name_First"]').val(firstName);
240            $('input[name="Name_Last"]').val(lastName);
241            DisplayError(false);
242            return true;
243        }
244
245    }
246
247    function ValidateEmail() {
248        const isValidEmail = value => { return value.match(/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/); }
249        if (!isValidEmail(value)) {
250            $(`#${name}`).next().show();
251            return false
252        } else {
253            $(`#${name}`).next().hide();
254            return true
255        }
256    }
257    function ValidatePhone(str) {
258        let sizeOfPhone = str == 'phone' ? 14 : 15;
259        if (value.trim().length < sizeOfPhone) {
260            $(`#${name}`).next().show();
261            return false
262        } else {
263            if (sizeOfPhone === 15 && value.trim()[5] !== '9') {
264                $(`#${name}`).next().show();
265                return false
266            }
267            $(`#${name}`).next().hide();
268            return true
269        }
270    }
271}
272
273function ValidateCheckbox() {
274    const checkbox = $("#Privacy_Policy");
275    const errorDiv = checkbox.closest("label").next("._error");
276    if (!checkbox.is(":checked")) {
277        errorDiv.show();
278        return false;
279    } else {
280        errorDiv.hide();
281        return true;
282    }
283}
284
285//Máscara para telefone e celular Zoho
286function PhoneMask(phone, tipo) {
287    if (tipo == 'telefone') {
288        return phone.replace(/\D/g, '')
289            .replace(/^(\d)/, '($1')
290            .replace(/^(\(\d{2})(\d)/, '$1) $2')
291            .replace(/(\d{4})(\d{1,5})/, '$1-$2')
292            .replace(/(-\d{4})\d+?$/, '$1');
293    }
294    if (tipo == 'celular') {
295        return phone.replace(/\D/g, '')
296            .replace(/^(\d)/, '($1')
297            .replace(/^(\(\d{2})(\d)/, '$1) $2')
298            .replace(/(\d{5})(\d{1,5})/, '$1-$2')
299            .replace(/(-\d{4})\d+?$/, '$1');
300    }
301}
302
303function DateMask(dateValue) {
304    const numbersOnly = (dateValue || "").replace(/\D/g, "").slice(0, 8);
305    const day = numbersOnly.slice(0, 2);
306    const month = numbersOnly.slice(2, 4);
307    const year = numbersOnly.slice(4, 8);
308
309    if (numbersOnly.length <= 2) {
310        return day;
311    }
312
313    if (numbersOnly.length <= 4) {
314        return `${day}/${month}`;
315    }
316
317    return `${day}/${month}/${year}`;
318}
319
320function ParseBrazilianDate(dateValue) {
321    const match = (dateValue || "").trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
322    if (!match) {
323        return null;
324    }
325
326    const day = parseInt(match[1], 10);
327    const month = parseInt(match[2], 10);
328    const year = parseInt(match[3], 10);
329
330    if (year < 1900 || year > 2100) {
331        return null;
332    }
333
334    const parsed = new Date(year, month - 1, day);
335    const isValidDate =
336        parsed.getFullYear() === year &&
337        parsed.getMonth() === (month - 1) &&
338        parsed.getDate() === day;
339
340    if (!isValidDate) {
341        return null;
342    }
343
344    const today = new Date();
345    today.setHours(0, 0, 0, 0);
346    parsed.setHours(0, 0, 0, 0);
347
348    if (parsed > today) {
349        return null;
350    }
351
352    return parsed;
353}

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.