@alexsab-ru/scripts 0.5.4 → 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 +182 -118
- 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,141 +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
|
+
}
|
|
154
179
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
+
});
|
|
191
|
+
|
|
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
|
-
|
|
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");
|
|
232
|
+
|
|
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);
|
|
184
239
|
}
|
|
185
|
-
|
|
240
|
+
return;
|
|
241
|
+
} else {
|
|
242
|
+
reachGoal("form_success", formDataObj);
|
|
186
243
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
+
}
|
|
194
251
|
}
|
|
195
|
-
|
|
196
|
-
|
|
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);
|
|
263
|
+
}
|
|
264
|
+
stateBtn(btn, "Отправить");
|
|
265
|
+
});
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
200
268
|
|
|
201
|
-
|
|
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");
|
|
202
275
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
mode: "cors",
|
|
206
|
-
cache: "no-cache",
|
|
207
|
-
credentials: "same-origin",
|
|
208
|
-
headers: {
|
|
209
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
210
|
-
},
|
|
211
|
-
body: params,
|
|
212
|
-
})
|
|
213
|
-
.then((res) => res.json())
|
|
214
|
-
.then((data) => {
|
|
215
|
-
verbose && console.log(data);
|
|
216
|
-
stateBtn(btn, "Отправить");
|
|
217
|
-
if (data.answer == "required") {
|
|
218
|
-
reachGoal("form_required");
|
|
219
|
-
showErrorMes(form, data.field, data.message);
|
|
220
|
-
return;
|
|
221
|
-
} else if (data.answer == "error") {
|
|
222
|
-
reachGoal("form_error");
|
|
276
|
+
const accept = confirmModal.querySelector('#accept-confirm');
|
|
277
|
+
const acceptClose = confirmModal.querySelector('#accept-close');
|
|
223
278
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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);
|
|
230
289
|
return;
|
|
231
|
-
}
|
|
232
|
-
|
|
290
|
+
});
|
|
291
|
+
}
|
|
233
292
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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"));
|
|
239
302
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
303
|
+
confirmModal.classList.add("hidden");
|
|
304
|
+
return;
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
}else{
|
|
310
|
+
// Если куки нет, просто отправляем форму
|
|
311
|
+
await submitForm(form);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
246
315
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
stateBtn(btn, "Отправить");
|
|
254
|
-
});
|
|
255
|
-
return false;
|
|
256
|
-
};
|
|
316
|
+
// Отправка всех форм
|
|
317
|
+
document.querySelectorAll("form").forEach((form) => {
|
|
318
|
+
form.addEventListener('submit', async (event) => {
|
|
319
|
+
event.preventDefault();
|
|
320
|
+
await sendForm(form);
|
|
321
|
+
})
|
|
257
322
|
});
|
|
258
|
-
|
|
259
323
|
}
|