@alexsab-ru/scripts 0.5.5 → 0.6.0
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/cookie.js +1 -1
- package/lib/form.js +181 -121
- package/package.json +1 -1
package/lib/cookie.js
CHANGED
|
@@ -28,7 +28,7 @@ export function setCookie(name, value, props)
|
|
|
28
28
|
|
|
29
29
|
export function deleteCookie(name)
|
|
30
30
|
{
|
|
31
|
-
setCookie(name, null, { 'domain':
|
|
31
|
+
setCookie(name, null, { 'domain':window.location.hostname,'path':'/','expires': -1 })
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export function cookiecook(days = 90)
|
package/lib/form.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { getCookie } from './cookie';
|
|
1
|
+
import { getCookie, setCookie, deleteCookie } from './cookie';
|
|
2
2
|
import { createRequest } from './calltouch';
|
|
3
3
|
import { reachGoal, getFormDataObject } from './analytics';
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
export const noValidPhone = (phoneValue) => {
|
|
7
6
|
return ([...new Set(phoneValue.replace(/^(\+7)/g, "").replace(/\D/g, ""))].length === 1);
|
|
8
7
|
};
|
|
@@ -119,145 +118,206 @@ const showMessageModal = (messageModal, icon, message) => {
|
|
|
119
118
|
messageModal.classList.remove("hidden");
|
|
120
119
|
};
|
|
121
120
|
|
|
122
|
-
|
|
121
|
+
const propsParams = {
|
|
122
|
+
callback: null,
|
|
123
|
+
callback_error: null,
|
|
124
|
+
ct_routeKey: '',
|
|
125
|
+
confirmModalText: '',
|
|
126
|
+
verbose: false,
|
|
127
|
+
}
|
|
123
128
|
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
export const connectForms = (url, props = propsParams) => {
|
|
130
|
+
props = {...propsParams, ...props};
|
|
131
|
+
|
|
132
|
+
async function submitForm(form){
|
|
126
133
|
const btn = form.querySelector('[type="submit"]');
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
stateBtn(btn, "Отправляем...", true);
|
|
135
|
+
const agree = form.querySelector('[name="agree"]');
|
|
136
|
+
const phone = form.querySelector('[name="phone"]');
|
|
137
|
+
const errorIcon =
|
|
138
|
+
'<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>';
|
|
139
|
+
const successIcon =
|
|
140
|
+
'<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52"><path fill="#279548" 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,0a2,2,0,1,1-2,2A2,2,0,0,1,16.4,17.5ZM40.09,32.15a15.8,15.8,0,0,1-28.18,0,1,1,0,0,1,1.78-.9,13.81,13.81,0,0,0,24.62,0,1,1,0,1,1,1.78.9Z"></path></svg>';
|
|
141
|
+
const errorText =
|
|
142
|
+
'<b class="text-bold block text-2xl mb-4">Упс!</b> Что-то пошло не так. Перезагрузите страницу и попробуйте снова. ';
|
|
143
|
+
const successText = '<b class="text-bold block text-2xl mb-4">Спасибо!</b> В скором времени мы свяжемся с Вами!';
|
|
144
|
+
const messageModal = document.getElementById("message-modal");
|
|
130
145
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
'<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>';
|
|
135
|
-
const successIcon =
|
|
136
|
-
'<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52"><path fill="#279548" 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,0a2,2,0,1,1-2,2A2,2,0,0,1,16.4,17.5ZM40.09,32.15a15.8,15.8,0,0,1-28.18,0,1,1,0,0,1,1.78-.9,13.81,13.81,0,0,0,24.62,0,1,1,0,1,1,1.78.9Z"></path></svg>';
|
|
137
|
-
const errorText =
|
|
138
|
-
'<b class="text-bold block text-2xl mb-4">Упс!</b> Что-то пошло не так. Перезагрузите страницу и попробуйте снова. ';
|
|
139
|
-
const successText = '<b class="text-bold block text-2xl mb-4">Спасибо!</b> В скором времени мы свяжемся с Вами!';
|
|
140
|
-
const messageModal = document.getElementById("message-modal");
|
|
146
|
+
if (!phoneChecker(phone)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
141
149
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
150
|
+
// если флажок не установлен - фронт
|
|
151
|
+
if (!agree.checked) {
|
|
152
|
+
showErrorMes(form, ".agree", "Чтобы продолжить, установите флажок");
|
|
153
|
+
stateBtn(btn, "Отправить");
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
145
156
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
// Отпрвка цели что форма submit только после всех проверок
|
|
158
|
+
reachGoal("form_submit");
|
|
159
|
+
|
|
160
|
+
let formData = new FormData(form);
|
|
161
|
+
if(getCookie('fta')) {
|
|
162
|
+
formData.append("fta", true);
|
|
163
|
+
}
|
|
164
|
+
if(getCookie('__gtm_campaign_url')) {
|
|
165
|
+
let source = new URL(getCookie('__gtm_campaign_url'));
|
|
166
|
+
source.search.slice(1).split("&").forEach(function(pair) {
|
|
167
|
+
let param = pair.split("=");
|
|
168
|
+
formData.append(param[0], param[1]);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
formData.append(
|
|
172
|
+
"page_url",
|
|
173
|
+
window.location.origin + window.location.pathname
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
if(typeof window.re != 'undefined') {
|
|
177
|
+
formData.append("re", window.re);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
window.location.search
|
|
181
|
+
.slice(1)
|
|
182
|
+
.split("&")
|
|
183
|
+
.forEach(function (pair) {
|
|
184
|
+
let param = pair.split("=");
|
|
185
|
+
if(formData.get(param[0])){
|
|
186
|
+
formData.set(param[0], decodeURIComponent(param[1]));
|
|
187
|
+
} else {
|
|
188
|
+
formData.append(param[0], decodeURIComponent(param[1]));
|
|
189
|
+
}
|
|
190
|
+
});
|
|
154
191
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
192
|
+
let formDataObj = {};
|
|
193
|
+
try {
|
|
194
|
+
// Отправка заявки на обратный возов в CallTouch
|
|
195
|
+
if(props.ct_routeKey != '') {
|
|
196
|
+
const requestData = await createRequest(props.ct_routeKey, phone.value, props.verbose);
|
|
197
|
+
formData.append("ct_callback", true);
|
|
198
|
+
formData.append("ctw_createRequest", JSON.stringify(requestData));
|
|
199
|
+
} else {
|
|
200
|
+
throw new Error('Empty ct_routeKey');
|
|
158
201
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
let param = pair.split("=");
|
|
163
|
-
formData.append(param[0], param[1]);
|
|
164
|
-
});
|
|
202
|
+
} catch (error) {
|
|
203
|
+
if(props.ct_routeKey != '') {
|
|
204
|
+
formData.append("ctw_createRequest", error);
|
|
165
205
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
);
|
|
206
|
+
props.verbose && console.error("Error during request Calltouch callback:", error);
|
|
207
|
+
formDataObj = getFormDataObject(formData, form.id);
|
|
208
|
+
}
|
|
170
209
|
|
|
171
|
-
|
|
172
|
-
formData.append("re", window.re);
|
|
173
|
-
}
|
|
210
|
+
const params = new URLSearchParams([...formData]);
|
|
174
211
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
212
|
+
await fetch(url, {
|
|
213
|
+
method: "POST",
|
|
214
|
+
mode: "cors",
|
|
215
|
+
cache: "no-cache",
|
|
216
|
+
credentials: "same-origin",
|
|
217
|
+
headers: {
|
|
218
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
219
|
+
},
|
|
220
|
+
body: params,
|
|
221
|
+
})
|
|
222
|
+
.then((res) => res.json())
|
|
223
|
+
.then((data) => {
|
|
224
|
+
props.verbose && console.log(data);
|
|
225
|
+
stateBtn(btn, "Отправить");
|
|
226
|
+
if (data.answer == "required") {
|
|
227
|
+
reachGoal("form_required");
|
|
228
|
+
showErrorMes(form, data.field, data.message);
|
|
229
|
+
return;
|
|
230
|
+
} else if (data.answer == "error") {
|
|
231
|
+
reachGoal("form_error");
|
|
186
232
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
233
|
+
// Вызов callback_error при ошибке
|
|
234
|
+
if (props.callback_error && typeof props.callback_error === 'function') {
|
|
235
|
+
props.callback_error();
|
|
236
|
+
} else if (messageModal) {
|
|
237
|
+
setCookie('SEND_MAIL', true, {'domain': window.location.hostname,'path':'/','expires':600});
|
|
238
|
+
showMessageModal(messageModal, errorIcon, errorText + "<br>" + data.error);
|
|
239
|
+
}
|
|
240
|
+
return;
|
|
194
241
|
} else {
|
|
195
|
-
|
|
242
|
+
reachGoal("form_success", formDataObj);
|
|
243
|
+
|
|
244
|
+
// Вызов callback при успехе
|
|
245
|
+
if (props.callback && typeof props.callback === 'function') {
|
|
246
|
+
props.callback();
|
|
247
|
+
} else if (messageModal) {
|
|
248
|
+
setCookie('SEND_MAIL', true, {'domain': window.location.hostname,'path':'/','expires':600});
|
|
249
|
+
showMessageModal(messageModal, successIcon, successText);
|
|
250
|
+
}
|
|
196
251
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
252
|
+
form.reset();
|
|
253
|
+
})
|
|
254
|
+
.catch((error) => {
|
|
255
|
+
reachGoal("form_error");
|
|
256
|
+
console.error("Ошибка отправки данных формы: " + error);
|
|
257
|
+
deleteCookie('SEND_MAIL');
|
|
258
|
+
// Вызов callback_error при ошибке
|
|
259
|
+
if (props.callback_error && typeof props.callback_error === 'function') {
|
|
260
|
+
props.callback_error();
|
|
261
|
+
} else if (messageModal) {
|
|
262
|
+
showMessageModal(messageModal, errorIcon, errorText + "<br>" + error);
|
|
200
263
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
264
|
+
stateBtn(btn, "Отправить");
|
|
265
|
+
});
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
204
268
|
|
|
205
|
-
|
|
269
|
+
async function sendForm(form) {
|
|
270
|
+
if (getCookie('SEND_MAIL')) {
|
|
271
|
+
const confirmModal = document.getElementById('confirm-modal');
|
|
272
|
+
if (confirmModal) {
|
|
273
|
+
confirmModal.querySelector('p').innerHTML = props.confirmModalText || '<span style="color: tomato; font-weight: bold">ПЕРЕДАЙ ТЕКСТ В ОБЪЕКТЕ <br><pre style="color: black; font-weight: 400">props = {confirmModalText: <i>"text"</i>}</pre></span>';
|
|
274
|
+
confirmModal.classList.remove("hidden");
|
|
206
275
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
mode: "cors",
|
|
210
|
-
cache: "no-cache",
|
|
211
|
-
credentials: "same-origin",
|
|
212
|
-
headers: {
|
|
213
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
214
|
-
},
|
|
215
|
-
body: params,
|
|
216
|
-
})
|
|
217
|
-
.then((res) => res.json())
|
|
218
|
-
.then((data) => {
|
|
219
|
-
verbose && console.log(data);
|
|
220
|
-
stateBtn(btn, "Отправить");
|
|
221
|
-
if (data.answer == "required") {
|
|
222
|
-
reachGoal("form_required");
|
|
223
|
-
showErrorMes(form, data.field, data.message);
|
|
224
|
-
return;
|
|
225
|
-
} else if (data.answer == "error") {
|
|
226
|
-
reachGoal("form_error");
|
|
276
|
+
const accept = confirmModal.querySelector('#accept-confirm');
|
|
277
|
+
const acceptClose = confirmModal.querySelector('#accept-close');
|
|
227
278
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
279
|
+
// Проверка на уже добавленный обработчик
|
|
280
|
+
if (!accept.dataset.listenerAdded) {
|
|
281
|
+
accept.dataset.listenerAdded = 'true';
|
|
282
|
+
accept.addEventListener('click', async () => {
|
|
283
|
+
// Закрываем модальное окно
|
|
284
|
+
confirmModal.classList.add("hidden");
|
|
285
|
+
// Удаляем куку
|
|
286
|
+
deleteCookie('SEND_MAIL');
|
|
287
|
+
// Повторно отправляем форму
|
|
288
|
+
await submitForm(form);
|
|
234
289
|
return;
|
|
235
|
-
}
|
|
236
|
-
|
|
290
|
+
});
|
|
291
|
+
}
|
|
237
292
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
293
|
+
// Проверка на уже добавленный обработчик
|
|
294
|
+
if (!acceptClose.dataset.listenerAdded) {
|
|
295
|
+
acceptClose.dataset.listenerAdded = 'true';
|
|
296
|
+
acceptClose.addEventListener('click', () => {
|
|
297
|
+
// Закрываем модальное окно
|
|
298
|
+
const modals = document.querySelectorAll('.modal-overlay');
|
|
299
|
+
form.reset();
|
|
300
|
+
if (modals.length) {
|
|
301
|
+
modals.forEach((modal) => modal.classList.add("hidden"));
|
|
243
302
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
303
|
+
confirmModal.classList.add("hidden");
|
|
304
|
+
return;
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
}else{
|
|
310
|
+
// Если куки нет, просто отправляем форму
|
|
311
|
+
await submitForm(form);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
250
315
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
stateBtn(btn, "Отправить");
|
|
258
|
-
});
|
|
259
|
-
return false;
|
|
260
|
-
};
|
|
316
|
+
// Отправка всех форм
|
|
317
|
+
document.querySelectorAll("form").forEach((form) => {
|
|
318
|
+
form.addEventListener('submit', async (event) => {
|
|
319
|
+
event.preventDefault();
|
|
320
|
+
await sendForm(form);
|
|
321
|
+
})
|
|
261
322
|
});
|
|
262
|
-
|
|
263
323
|
}
|