@alexsab-ru/scripts 0.16.1 → 0.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/form.js +91 -19
- package/package.json +1 -1
package/lib/form.js
CHANGED
|
@@ -79,6 +79,47 @@ const stateBtn = (btn, value, disable = false) => {
|
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
const hasFileUploadField = (form, selector) => {
|
|
83
|
+
if (!selector) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
return !!form.querySelector(selector);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const appendDropzoneFiles = (formData, { filesToUploadKey, fileFieldName }) => {
|
|
90
|
+
if (!filesToUploadKey || !fileFieldName) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const files = window[filesToUploadKey];
|
|
95
|
+
if (!Array.isArray(files)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
files.forEach((file) => {
|
|
100
|
+
formData.append(fileFieldName, file);
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const resetDropzones = ({ dropzonesKey, filesToUploadKey }) => {
|
|
105
|
+
if (!dropzonesKey || !filesToUploadKey) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const dropzones = window[dropzonesKey];
|
|
110
|
+
if (Array.isArray(dropzones)) {
|
|
111
|
+
dropzones.forEach((dropzone) => {
|
|
112
|
+
if (dropzone && typeof dropzone.removeAllFiles === 'function') {
|
|
113
|
+
dropzone.removeAllFiles();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (Array.isArray(window[filesToUploadKey])) {
|
|
119
|
+
window[filesToUploadKey] = [];
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
82
123
|
// Показ сообщения об ошибке
|
|
83
124
|
export const showErrorMes = (form, el, text) => {
|
|
84
125
|
let field = form.querySelector(el);
|
|
@@ -111,6 +152,11 @@ const propsParams = {
|
|
|
111
152
|
verbose: false,
|
|
112
153
|
agreeSelector: "agree",
|
|
113
154
|
sendMailCookie: "SEND_MAIL",
|
|
155
|
+
fileUploadSelector: ".file-upload",
|
|
156
|
+
fileFieldName: "file[]",
|
|
157
|
+
filesToUploadKey: "filesToUpload",
|
|
158
|
+
dropzonesKey: "dropzones",
|
|
159
|
+
successOnAttentionPhone: "79000000000",
|
|
114
160
|
}
|
|
115
161
|
|
|
116
162
|
export const errorIcon = '<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52"><path fill="#ed1c24" d="M26,0A26,26,0,1,0,52,26,26,26,0,0,0,26,0Zm9.6,17.5a1.94,1.94,0,0,1,2,2,2,2,0,1,1-2-2Zm-19.2,0a1.94,1.94,0,0,1,2,2,2,2,0,1,1-2-2ZM39.65,40.69a.93.93,0,0,1-.45.11,1,1,0,0,1-.89-.55,13.81,13.81,0,0,0-24.62,0,1,1,0,1,1-1.78-.9,15.8,15.8,0,0,1,28.18,0A1,1,0,0,1,39.65,40.69Z"></path></svg>';
|
|
@@ -171,6 +217,9 @@ const submitForm = async (form) => {
|
|
|
171
217
|
const phone = form.querySelector('[name="phone"]');
|
|
172
218
|
const name = form.querySelector('[name="name"]');
|
|
173
219
|
const dealer = form.querySelector('[name="dealer"]');
|
|
220
|
+
const hasFileUpload = hasFileUploadField(form, props.fileUploadSelector);
|
|
221
|
+
const ftaCookie = Boolean(getCookie('fta'));
|
|
222
|
+
const verbose = Boolean(props.verbose || ftaCookie);
|
|
174
223
|
|
|
175
224
|
let validate;
|
|
176
225
|
|
|
@@ -256,11 +305,14 @@ const submitForm = async (form) => {
|
|
|
256
305
|
reachGoal("form_submit");
|
|
257
306
|
|
|
258
307
|
let formData = new FormData(form);
|
|
308
|
+
if (hasFileUpload) {
|
|
309
|
+
appendDropzoneFiles(formData, props);
|
|
310
|
+
}
|
|
259
311
|
let sendMailCookie = props.sendMailCookie;
|
|
260
312
|
if(formData.get('dealer')) {
|
|
261
313
|
sendMailCookie += "_" + formData.get('dealer');
|
|
262
314
|
}
|
|
263
|
-
if(
|
|
315
|
+
if(ftaCookie) {
|
|
264
316
|
formData.append("fta", true);
|
|
265
317
|
}
|
|
266
318
|
if(getCookie('__gtm_campaign_url')) {
|
|
@@ -284,6 +336,9 @@ const submitForm = async (form) => {
|
|
|
284
336
|
.split("&")
|
|
285
337
|
.forEach(function (pair) {
|
|
286
338
|
let param = pair.split("=");
|
|
339
|
+
if(!param[0]){
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
287
342
|
if(formData.get(param[0])){
|
|
288
343
|
formData.set(param[0], decodeURIComponent(param[1]));
|
|
289
344
|
} else {
|
|
@@ -304,7 +359,7 @@ const submitForm = async (form) => {
|
|
|
304
359
|
try {
|
|
305
360
|
// Для multi-project берём routeKey/mod_id у выбранного дилера (data-атрибуты select).
|
|
306
361
|
// Если дилерские значения отсутствуют, используем старый глобальный props.ct_routeKey.
|
|
307
|
-
|
|
362
|
+
verbose && console.log('Calltouch submit debug:', {
|
|
308
363
|
formId: form.id || '',
|
|
309
364
|
phone: phone && phone.value ? phone.value : '',
|
|
310
365
|
name: name && name.value ? name.value : '',
|
|
@@ -321,7 +376,7 @@ const submitForm = async (form) => {
|
|
|
321
376
|
|
|
322
377
|
// Отправка заявки на обратный вызов в CallTouch.
|
|
323
378
|
if(calltouchRouteKey != '') {
|
|
324
|
-
const requestData = await createRequest(calltouchRouteKey, phone.value, name.value,
|
|
379
|
+
const requestData = await createRequest(calltouchRouteKey, phone.value, name.value, verbose, dealerModId);
|
|
325
380
|
formData.append("ct_callback", true);
|
|
326
381
|
formData.append("ctw_createRequest", JSON.stringify(requestData));
|
|
327
382
|
if (dealerModId !== '') {
|
|
@@ -359,21 +414,33 @@ const submitForm = async (form) => {
|
|
|
359
414
|
}
|
|
360
415
|
}
|
|
361
416
|
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
417
|
+
const requestOptions = hasFileUpload
|
|
418
|
+
? {
|
|
419
|
+
method: "POST",
|
|
420
|
+
body: formData,
|
|
421
|
+
}
|
|
422
|
+
: {
|
|
423
|
+
method: "POST",
|
|
424
|
+
mode: "cors",
|
|
425
|
+
cache: "no-cache",
|
|
426
|
+
credentials: "same-origin",
|
|
427
|
+
headers: {
|
|
428
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
429
|
+
},
|
|
430
|
+
body: new URLSearchParams([...formData]),
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
await fetch(url, requestOptions)
|
|
434
|
+
.then(async (res) => {
|
|
435
|
+
const text = await res.text();
|
|
436
|
+
try {
|
|
437
|
+
return JSON.parse(text);
|
|
438
|
+
} catch (error) {
|
|
439
|
+
throw new Error("Ошибка обработки данных");
|
|
440
|
+
}
|
|
441
|
+
})
|
|
375
442
|
.then((data) => {
|
|
376
|
-
|
|
443
|
+
verbose && console.log(data);
|
|
377
444
|
stateBtn(btn, btnText);
|
|
378
445
|
if (data.answer == "required") {
|
|
379
446
|
reachGoal("form_required");
|
|
@@ -390,7 +457,9 @@ const submitForm = async (form) => {
|
|
|
390
457
|
}
|
|
391
458
|
return;
|
|
392
459
|
} else {
|
|
393
|
-
|
|
460
|
+
const normalizedPhone = String(formData.get("phone") || (phone && phone.value ? phone.value : "")).replace(/\D/g, "");
|
|
461
|
+
const attentionPhone = String(props.successOnAttentionPhone || "").replace(/\D/g, "");
|
|
462
|
+
if(data.attention != true || (attentionPhone && normalizedPhone === attentionPhone)) {
|
|
394
463
|
reachGoal("form_success", formDataObj);
|
|
395
464
|
}
|
|
396
465
|
setCookie(sendMailCookie, true, {'domain': window.location.hostname,'path':'/','expires':600});
|
|
@@ -402,6 +471,9 @@ const submitForm = async (form) => {
|
|
|
402
471
|
}
|
|
403
472
|
}
|
|
404
473
|
form.reset();
|
|
474
|
+
if (hasFileUpload) {
|
|
475
|
+
resetDropzones(props);
|
|
476
|
+
}
|
|
405
477
|
})
|
|
406
478
|
.catch((error) => {
|
|
407
479
|
reachGoal("form_error");
|
|
@@ -477,4 +549,4 @@ document.querySelectorAll("form:not(.vue-form)").forEach((form) => {
|
|
|
477
549
|
await sendForm(form);
|
|
478
550
|
})
|
|
479
551
|
});
|
|
480
|
-
}
|
|
552
|
+
}
|