@alexsab-ru/scripts 0.15.1 → 0.15.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 +85 -21
- package/package.json +1 -1
package/lib/form.js
CHANGED
|
@@ -6,19 +6,20 @@ export const noValidPhone = (phoneValue) => {
|
|
|
6
6
|
return ([...new Set(phoneValue.replace(/^(\+7)/g, "").replace(/\D/g, ""))].length === 1);
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
export const maskphone = (e) => {
|
|
10
|
+
const input = e.currentTarget;
|
|
11
|
+
let num = input.value.replace(/^(\+7|8|7)/g, "").replace(/\D/g, "").split(/(?=.)/);
|
|
12
|
+
const i = num.length;
|
|
12
13
|
|
|
13
|
-
if(
|
|
14
|
+
if (input.value !== "" && input.value !== "+") {
|
|
14
15
|
if (0 <= i) num.unshift("+7");
|
|
15
16
|
if (1 <= i) num.splice(1, 0, " ");
|
|
16
17
|
if (4 <= i) num.splice(5, 0, " ");
|
|
17
18
|
if (7 <= i) num.splice(9, 0, "-");
|
|
18
19
|
if (9 <= i) num.splice(12, 0, "-");
|
|
19
|
-
|
|
20
|
+
input.value = num.join("");
|
|
20
21
|
}
|
|
21
|
-
}
|
|
22
|
+
};
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
export const phoneChecker = (phone) => {
|
|
@@ -62,12 +63,18 @@ const stateBtn = (btn, value, disable = false) => {
|
|
|
62
63
|
}
|
|
63
64
|
};
|
|
64
65
|
|
|
66
|
+
// Показ сообщения об ошибке
|
|
65
67
|
export const showErrorMes = (form, el, text) => {
|
|
66
68
|
let field = form.querySelector(el);
|
|
69
|
+
if (!field) {
|
|
70
|
+
console.warn('showErrorMes: element not found', { selector: el, form });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
67
73
|
field.innerText = text;
|
|
68
74
|
field.classList.remove("hidden");
|
|
69
75
|
};
|
|
70
76
|
|
|
77
|
+
// Показ модального окна с сообщением об успехе/ошибке
|
|
71
78
|
export const showMessageModal = (messageModal, icon, message) => {
|
|
72
79
|
document.querySelectorAll(".modal-overlay").forEach((el) => {
|
|
73
80
|
el.classList.add("hidden");
|
|
@@ -99,6 +106,7 @@ export const messageModal = document.getElementById("message-modal");
|
|
|
99
106
|
export const connectForms = (url, props = propsParams) => {
|
|
100
107
|
props = {...propsParams, ...props};
|
|
101
108
|
|
|
109
|
+
|
|
102
110
|
document.querySelectorAll("input[name=phone]").forEach(function (element) {
|
|
103
111
|
// element.addEventListener("focus", maskphone);
|
|
104
112
|
element.addEventListener("input", maskphone);
|
|
@@ -137,7 +145,8 @@ export const connectForms = (url, props = propsParams) => {
|
|
|
137
145
|
}
|
|
138
146
|
});
|
|
139
147
|
|
|
140
|
-
|
|
148
|
+
|
|
149
|
+
const submitForm = async (form) => {
|
|
141
150
|
const btn = form.querySelector('[type="submit"]');
|
|
142
151
|
const btnText = btn.value || btn.innerText;
|
|
143
152
|
const agree = form.querySelector('[name="' + props.agreeSelector + '"]');
|
|
@@ -145,26 +154,81 @@ async function submitForm(form){
|
|
|
145
154
|
const name = form.querySelector('[name="name"]');
|
|
146
155
|
const dealer = form.querySelector('[name="dealer"]');
|
|
147
156
|
|
|
148
|
-
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
157
|
+
let validate;
|
|
151
158
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
159
|
+
// Валидируем форму. Поддерживаем 2 кейса:
|
|
160
|
+
// 1) Пользователь передал класс (конструктор), который имеет метод validate() или run() или поле isValid
|
|
161
|
+
// 2) Пользователь передал функцию, возвращающую boolean или объект с isValid
|
|
162
|
+
if (props.validation && typeof props.validation === 'function') {
|
|
163
|
+
try {
|
|
164
|
+
let instance;
|
|
165
|
+
let result;
|
|
166
|
+
|
|
167
|
+
// Пытаемся создать экземпляр (если передан класс). Если не конструктор — вызовем как функцию ниже
|
|
168
|
+
try {
|
|
169
|
+
instance = new props.validation(form);
|
|
170
|
+
} catch (e) {
|
|
171
|
+
// Если это не конструктор (например, стрелочная функция), пробуем вызвать как обычную функцию
|
|
172
|
+
result = props.validation(form);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Если есть экземпляр, пробуем стандартные методы
|
|
176
|
+
if (instance) {
|
|
177
|
+
if (typeof instance.validate === 'function') {
|
|
178
|
+
result = await instance.validate();
|
|
179
|
+
} else if (typeof instance.run === 'function') {
|
|
180
|
+
result = await instance.run();
|
|
181
|
+
} else if (typeof instance.isValid !== 'undefined') {
|
|
182
|
+
result = { isValid: instance.isValid };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Нормализуем результат к виду { isValid: boolean }
|
|
187
|
+
if (typeof result === 'boolean') {
|
|
188
|
+
validate = { isValid: result };
|
|
189
|
+
} else if (result && typeof result === 'object' && 'isValid' in result) {
|
|
190
|
+
validate = { isValid: Boolean(result.isValid) };
|
|
191
|
+
} else if (instance && typeof instance.isValid !== 'undefined') {
|
|
192
|
+
validate = { isValid: Boolean(instance.isValid) };
|
|
193
|
+
} else {
|
|
194
|
+
// Если валидатор ничего не вернул, считаем, что он сам показал ошибки и блокируем отправку
|
|
195
|
+
validate = { isValid: false };
|
|
196
|
+
}
|
|
197
|
+
} catch (err) {
|
|
198
|
+
// Если кастомный валидатор упал — показываем в консоли и блокируем отправку, чтобы не уйти с невалидной формой
|
|
199
|
+
console.error('Validation error:', err);
|
|
200
|
+
validate = { isValid: false };
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
// Базовые проверки, если кастомный валидатор не передан
|
|
204
|
+
if (!phoneChecker(phone)) {
|
|
155
205
|
return;
|
|
156
206
|
}
|
|
157
|
-
|
|
207
|
+
|
|
208
|
+
if(dealer && dealer.hasAttribute('required')){
|
|
209
|
+
if(!dealer.value){
|
|
210
|
+
showErrorMes(form, '.dealer', 'Выберите дилерский центр');
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
158
214
|
|
|
159
|
-
|
|
160
|
-
|
|
215
|
+
// agree обязателен: если не найден или не отмечен — показываем ошибку
|
|
216
|
+
if (!agree || !agree.checked) {
|
|
217
|
+
showErrorMes(form, "." + props.agreeSelector, "Чтобы продолжить, установите флажок");
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Иначе считаем форму валидной
|
|
222
|
+
validate = { isValid: true };
|
|
161
223
|
}
|
|
162
224
|
|
|
163
|
-
//
|
|
164
|
-
if (!
|
|
165
|
-
showErrorMes(form, "." + props.agreeSelector, "Чтобы продолжить, установите флажок");
|
|
225
|
+
// Если форма невалидна (isValid === false), прекращаем отправку
|
|
226
|
+
if (!validate.isValid) {
|
|
166
227
|
return;
|
|
167
|
-
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// если флажок установлен - устанавливаем куки (проверяем на наличие agree)
|
|
231
|
+
if (agree && agree.checked) {
|
|
168
232
|
setAgreeCookie(90);
|
|
169
233
|
}
|
|
170
234
|
|
|
@@ -277,7 +341,7 @@ async function submitForm(form){
|
|
|
277
341
|
deleteCookie(sendMailCookie);
|
|
278
342
|
// Вызов callback_error при ошибке
|
|
279
343
|
if (props.callback_error && typeof props.callback_error === 'function') {
|
|
280
|
-
props.callback_error(
|
|
344
|
+
props.callback_error(error);
|
|
281
345
|
} else if (messageModal) {
|
|
282
346
|
showMessageModal(messageModal, errorIcon, errorText + "<br>" + error);
|
|
283
347
|
}
|