@alexsab-ru/scripts 0.15.1 → 0.15.3

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.
Files changed (2) hide show
  1. package/lib/form.js +108 -28
  2. package/package.json +1 -1
package/lib/form.js CHANGED
@@ -6,34 +6,51 @@ export const noValidPhone = (phoneValue) => {
6
6
  return ([...new Set(phoneValue.replace(/^(\+7)/g, "").replace(/\D/g, ""))].length === 1);
7
7
  };
8
8
 
9
- export function maskphone(e) {
10
- let num = this.value.replace(/^(\+7|8|7)/g, "").replace(/\D/g, "").split(/(?=.)/),
11
- i = num.length;
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(this.value != "" && this.value != "+") {
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
- this.value = num.join("");
20
+ input.value = num.join("");
20
21
  }
21
- }
22
+ };
23
+
22
24
 
25
+ export const phoneChecker = (phone, options = {}) => {
26
+ // Опция silent:
27
+ // - true => функция работает в "тихом" режиме (НЕ показывает сообщения), возвращает только true|false
28
+ // - false => ведёт себя как раньше: показывает разные сообщения об ошибках
29
+ const { silent = false } = options;
23
30
 
24
- export const phoneChecker = (phone) => {
25
31
  let form = phone.closest("form");
32
+
33
+ // Пустое значение
26
34
  if (!phone.value.length) {
27
- showErrorMes(form, ".phone", "Телефон является обязательным полем");
35
+ if (!silent && form) {
36
+ showErrorMes(form, ".phone", "Телефон является обязательным полем");
37
+ }
28
38
  return false;
29
- } else {
30
- const phoneRe = new RegExp(/^\+7 [0-9]{3} [0-9]{3}-[0-9]{2}-[0-9]{2}$/);
31
- if (!phoneRe.test(phone.value) || noValidPhone(phone.value)) {
39
+ }
40
+
41
+ // Формат и анти-флуд (одинаковые цифры)
42
+ const phoneRe = new RegExp(/^\+7 [0-9]{3} [0-9]{3}-[0-9]{2}-[0-9]{2}$/);
43
+ if (!phoneRe.test(phone.value) || noValidPhone(phone.value)) {
44
+ if (!silent && form) {
32
45
  showErrorMes(form, ".phone", "Введен некорректный номер телефона");
33
- return false;
34
46
  }
47
+ return false;
48
+ }
49
+
50
+ // Валидно — в шумном режиме прячем текст ошибки
51
+ if (!silent && form) {
52
+ showErrorMes(form, ".phone", "");
35
53
  }
36
- showErrorMes(form, ".phone", "");
37
54
  return true;
38
55
  };
39
56
 
@@ -62,12 +79,18 @@ const stateBtn = (btn, value, disable = false) => {
62
79
  }
63
80
  };
64
81
 
82
+ // Показ сообщения об ошибке
65
83
  export const showErrorMes = (form, el, text) => {
66
84
  let field = form.querySelector(el);
85
+ if (!field) {
86
+ console.warn('showErrorMes: element not found', { selector: el, form });
87
+ return;
88
+ }
67
89
  field.innerText = text;
68
90
  field.classList.remove("hidden");
69
91
  };
70
92
 
93
+ // Показ модального окна с сообщением об успехе/ошибке
71
94
  export const showMessageModal = (messageModal, icon, message) => {
72
95
  document.querySelectorAll(".modal-overlay").forEach((el) => {
73
96
  el.classList.add("hidden");
@@ -99,6 +122,7 @@ export const messageModal = document.getElementById("message-modal");
99
122
  export const connectForms = (url, props = propsParams) => {
100
123
  props = {...propsParams, ...props};
101
124
 
125
+
102
126
  document.querySelectorAll("input[name=phone]").forEach(function (element) {
103
127
  // element.addEventListener("focus", maskphone);
104
128
  element.addEventListener("input", maskphone);
@@ -137,7 +161,8 @@ export const connectForms = (url, props = propsParams) => {
137
161
  }
138
162
  });
139
163
 
140
- async function submitForm(form){
164
+
165
+ const submitForm = async (form) => {
141
166
  const btn = form.querySelector('[type="submit"]');
142
167
  const btnText = btn.value || btn.innerText;
143
168
  const agree = form.querySelector('[name="' + props.agreeSelector + '"]');
@@ -145,26 +170,81 @@ async function submitForm(form){
145
170
  const name = form.querySelector('[name="name"]');
146
171
  const dealer = form.querySelector('[name="dealer"]');
147
172
 
148
- if (!phoneChecker(phone)) {
149
- return;
150
- }
173
+ let validate;
174
+
175
+ // Валидируем форму. Поддерживаем 2 кейса:
176
+ // 1) Пользователь передал класс (конструктор), который имеет метод validate() или run() или поле isValid
177
+ // 2) Пользователь передал функцию, возвращающую boolean или объект с isValid
178
+ if (props.validation && typeof props.validation === 'function') {
179
+ try {
180
+ let instance;
181
+ let result;
182
+
183
+ // Пытаемся создать экземпляр (если передан класс). Если не конструктор — вызовем как функцию ниже
184
+ try {
185
+ instance = new props.validation(form);
186
+ } catch (e) {
187
+ // Если это не конструктор (например, стрелочная функция), пробуем вызвать как обычную функцию
188
+ result = props.validation(form);
189
+ }
151
190
 
152
- if(dealer && dealer.hasAttribute('required')){
153
- if(!dealer.value){
154
- showErrorMes(form, '.dealer', 'Выберите дилерский центр');
191
+ // Если есть экземпляр, пробуем стандартные методы
192
+ if (instance) {
193
+ if (typeof instance.validate === 'function') {
194
+ result = await instance.validate();
195
+ } else if (typeof instance.run === 'function') {
196
+ result = await instance.run();
197
+ } else if (typeof instance.isValid !== 'undefined') {
198
+ result = { isValid: instance.isValid };
199
+ }
200
+ }
201
+
202
+ // Нормализуем результат к виду { isValid: boolean }
203
+ if (typeof result === 'boolean') {
204
+ validate = { isValid: result };
205
+ } else if (result && typeof result === 'object' && 'isValid' in result) {
206
+ validate = { isValid: Boolean(result.isValid) };
207
+ } else if (instance && typeof instance.isValid !== 'undefined') {
208
+ validate = { isValid: Boolean(instance.isValid) };
209
+ } else {
210
+ // Если валидатор ничего не вернул, считаем, что он сам показал ошибки и блокируем отправку
211
+ validate = { isValid: false };
212
+ }
213
+ } catch (err) {
214
+ // Если кастомный валидатор упал — показываем в консоли и блокируем отправку, чтобы не уйти с невалидной формой
215
+ console.error('Validation error:', err);
216
+ validate = { isValid: false };
217
+ }
218
+ } else {
219
+ // Базовые проверки, если кастомный валидатор не передан
220
+ if (!phoneChecker(phone)) {
155
221
  return;
156
222
  }
157
- }
223
+
224
+ if(dealer && dealer.hasAttribute('required')){
225
+ if(!dealer.value){
226
+ showErrorMes(form, '.dealer', 'Выберите дилерский центр');
227
+ return;
228
+ }
229
+ }
158
230
 
159
- if (props.validation && typeof props.validation === 'function') {
160
- props.validation(form);
231
+ // agree обязателен: если не найден или не отмечен — показываем ошибку
232
+ if (!agree || !agree.checked) {
233
+ showErrorMes(form, "." + props.agreeSelector, "Чтобы продолжить, установите флажок");
234
+ return;
235
+ }
236
+
237
+ // Иначе считаем форму валидной
238
+ validate = { isValid: true };
161
239
  }
162
240
 
163
- // если флажок не установлен - фронт
164
- if (!agree.checked) {
165
- showErrorMes(form, "." + props.agreeSelector, "Чтобы продолжить, установите флажок");
241
+ // Если форма невалидна (isValid === false), прекращаем отправку
242
+ if (!validate.isValid) {
166
243
  return;
167
- } else {
244
+ }
245
+
246
+ // если флажок установлен - устанавливаем куки (проверяем на наличие agree)
247
+ if (agree && agree.checked) {
168
248
  setAgreeCookie(90);
169
249
  }
170
250
 
@@ -277,7 +357,7 @@ async function submitForm(form){
277
357
  deleteCookie(sendMailCookie);
278
358
  // Вызов callback_error при ошибке
279
359
  if (props.callback_error && typeof props.callback_error === 'function') {
280
- props.callback_error(data);
360
+ props.callback_error(error);
281
361
  } else if (messageModal) {
282
362
  showMessageModal(messageModal, errorIcon, errorText + "<br>" + error);
283
363
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexsab-ru/scripts",
3
- "version": "0.15.1",
3
+ "version": "0.15.3",
4
4
  "description": "common libs for websites",
5
5
  "main": "index.js",
6
6
  "scripts": {