vgapp 0.6.9 → 0.7.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # VEGAS-APP 0.6.9 - 0.7.0 (Ноябрь, 21, 2025)
2
+ * Изменения коснулись модуля vgformsender в частности кнопку submit, дата атрибуты можно вешать на нее или на саму форму
3
+ 1. Опциональное состояние кнопки(submit) data-button-enabled="false" - никаких действий с текстом кнопки не будет
4
+ 2. data-button-disabled - по умолчанию `true`, блокирует кнопку при отправке
5
+ 3. data-button-spinner-enabled - по умолчанию `false`, добавляет спиннер загрузки в кнопку
6
+ 4. data-button-spinner-element - добавит код по умолчанию `<span class="spinner-border spinner-border-sm me-2"></span>`, можно придумать свой
7
+ 5. data-button-initial - можно вписать текст, или он сам возьмет содержимое кнопки.
8
+ 6. data-button-send - текст во время отправки, по умолчанию `Отправляем...`
9
+
10
+ * Исправлены ошибки в разных модулях
11
+
12
+ ---
13
+
1
14
  # VEGAS-APP 0.6.6 - 0.6.8 (Ноябрь, 17, 2025)
2
15
  * isLeaveBackDrop (boolean) - для методов .hide() модулей VGModal и VGSidebar. Если программно нужно сменить модалки или сайдбары и/или одно на другое при этом не будет затронут задний фон Backdrop
3
16
  * Исправлены ошибки в разных модулях
@@ -34,48 +34,50 @@ class BaseModule {
34
34
  }
35
35
 
36
36
  _route(callback) {
37
- const _this = this;
38
- let $content = null;
37
+ let $content = null,
38
+ timeout = this._params.ajax.timeout || 0;
39
39
 
40
- if (_this._isLoaded) return;
40
+ if (this._isLoaded) return;
41
41
 
42
42
  const setData = (data) => {
43
43
  if ($content) $content.innerHTML = data;
44
44
  };
45
45
 
46
- if (!_this._params.hasOwnProperty('ajax')) {
46
+ if (!this._params.hasOwnProperty('ajax')) {
47
47
  return;
48
48
  }
49
49
 
50
- if (!_this._params.ajax.route) {
50
+ if (!this._params.ajax.route) {
51
51
  return;
52
52
  }
53
53
 
54
- if (!'method' in _this._params.ajax) {
55
- _this._params.ajax.method = 'get';
54
+ if (!'method' in this._params.ajax) {
55
+ this._params.ajax.method = 'get';
56
56
  }
57
57
 
58
- if ('target' in _this._params.ajax && _this._params.ajax.target) {
59
- $content = Selectors.find(_this._params.ajax.target);
58
+ if ('target' in this._params.ajax && this._params.ajax.target) {
59
+ $content = Selectors.find(this._params.ajax.target);
60
60
  }
61
61
 
62
- if ('loader' in _this._params.ajax && _this._params.ajax.loader) {
63
- if ('output' in _this._params.ajax && _this._params.ajax.output) {
62
+ if ('loader' in this._params.ajax && this._params.ajax.loader) {
63
+ if ('output' in this._params.ajax && this._params.ajax.output) {
64
64
  setData('<div class="vg-loader"></div>');
65
65
  }
66
66
  }
67
67
 
68
- Ajax[_this._params.ajax.method](_this._params.ajax.route, _this._params.ajax.data || {}, function (status, data) {
69
- if ('once' in _this._params.ajax && _this._params.ajax.once) {
70
- _this._isLoaded = true;
71
- }
68
+ setTimeout(() => {
69
+ Ajax[this._params.ajax.method](this._params.ajax.route, this._params.ajax.data || {}, (status, data) => {
70
+ if ('once' in this._params.ajax && this._params.ajax.once) {
71
+ this._isLoaded = true;
72
+ }
72
73
 
73
- if ('output' in _this._params.ajax && _this._params.ajax.output) {
74
- setData(data.response);
75
- }
74
+ if ('output' in this._params.ajax && this._params.ajax.output) {
75
+ setData(data.response);
76
+ }
76
77
 
77
- execute(callback, [status, data, $content]);
78
- });
78
+ execute(callback, [status, data, $content]);
79
+ });
80
+ }, timeout)
79
81
  }
80
82
 
81
83
  _dismissElement() {
@@ -3,7 +3,7 @@ import {Manipulator} from "../../../utils/js/dom/manipulator";
3
3
  import EventHandler from "../../../utils/js/dom/event";
4
4
  import VGModal from "../../vgmodal/js/vgmodal";
5
5
  import {
6
- execute,
6
+ execute, getDeepestLastChild,
7
7
  isObject,
8
8
  isVisible,
9
9
  makeRandomString,
@@ -16,6 +16,12 @@ import VGCollapse from "../../vgcollapse/js/vgcollapse";
16
16
  import {getSVG} from "../../module-fn";
17
17
  import VGHideShowPass from "./hideshowpass";
18
18
 
19
+ /**
20
+ * TODO
21
+ * доделай динамическое добавление полей в форму,
22
+ * но не меняй место их получения (их нужно получить прямо перед отправкой, после того как выполнился промис beforeSend)
23
+ */
24
+
19
25
  /**
20
26
  * Constants
21
27
  */
@@ -66,6 +72,7 @@ class VGFormSender extends BaseModule {
66
72
  route: '',
67
73
  target: '',
68
74
  method: 'get',
75
+ timeout: 1000,
69
76
  },
70
77
  classes: {
71
78
  general: 'vg-form-sender',
@@ -81,9 +88,20 @@ class VGFormSender extends BaseModule {
81
88
  afterError: noop,
82
89
  },
83
90
  interceptors: {
91
+ beforeSend: () => new Promise((resolve, reject) => resolve()),
84
92
  success: false,
85
93
  error: false
86
- }
94
+ },
95
+ button: {
96
+ enabled: true,
97
+ disabled: true,
98
+ send: 'Отправляем...',
99
+ initial: 'Отправить',
100
+ spinner: {
101
+ enabled: false,
102
+ element: '<span class="spinner-border spinner-border-sm me-2"></span>'
103
+ }
104
+ },
87
105
  }, params));
88
106
 
89
107
  this._params.ajax.route = Manipulator.get(this._element, 'action').toLowerCase();
@@ -93,6 +111,9 @@ class VGFormSender extends BaseModule {
93
111
  this._params.isBtnText = Manipulator.get(this._element, 'data-btn-text') !== 'false';
94
112
  this._params.isJsonParse = Manipulator.get(this._element, 'data-json-parse') !== 'false';
95
113
  this._params.isShowPass = Manipulator.get(this._element, 'data-show-pass') === 'true';
114
+
115
+ this._params = this._getParams(this._button, this._params);
116
+ this._params.button.initial = this._button.innerHTML || this._params.button.initial;
96
117
  }
97
118
 
98
119
  static get NAME() {
@@ -133,40 +154,45 @@ class VGFormSender extends BaseModule {
133
154
 
134
155
  _this._alertBefore();
135
156
 
136
- _this._params.ajax.data = data;
157
+ const submit = () => {
158
+ _this._params.ajax.data = new FormData(_this._element);
159
+ _this._route(function (status, data) {
160
+ _this._element.classList.remove('was-validated');
137
161
 
138
- _this._route(function (status, data) {
139
- _this._element.classList.remove('was-validated');
140
-
141
- if (_this._params.response.enabled) {
142
- data.response = _this._params.response;
143
- }
162
+ if (_this._params.response.enabled) {
163
+ data.response = _this._params.response;
164
+ }
144
165
 
145
- if (_this._params.alert.enabled) {
146
- if (typeof status === 'string' && status === 'error') {
147
- if (_this._params.redirect.error) {
148
- window.location.href = _this._params.redirect.error;
149
- } else {
150
- if (!_this._params.interceptors.error) {
151
- _this._alertError(event, data);
152
- execute(_this._params.callback.afterError, [_this._element, _this, event, data]);
166
+ if (_this._params.alert.enabled) {
167
+ if (typeof status === 'string' && status === 'error') {
168
+ if (_this._params.redirect.error) {
169
+ window.location.href = _this._params.redirect.error;
153
170
  } else {
154
- execute(_this._params.callback.afterError, [_this._element, _this, event, data]);
171
+ if (!_this._params.interceptors.error) {
172
+ _this._alertError(event, data);
173
+ execute(_this._params.callback.afterError, [_this._element, _this, event, data]);
174
+ } else {
175
+ execute(_this._params.callback.afterError, [_this._element, _this, event, data]);
176
+ }
155
177
  }
156
- }
157
- } else if (typeof status === 'string' && status === 'success') {
158
- if (_this._params.redirect.success) {
159
- window.location.href = _this._params.redirect.success;
160
- } else {
161
- if (!_this._params.interceptors.success) {
162
- _this._alertSuccess(event, data);
163
- execute(_this._params.callback.afterSuccess, [_this._element, _this, event, data]);
178
+ } else if (typeof status === 'string' && status === 'success') {
179
+ if (_this._params.redirect.success) {
180
+ window.location.href = _this._params.redirect.success;
164
181
  } else {
165
- execute(_this._params.callback.afterSuccess, [_this._element, _this, event, data]);
182
+ if (!_this._params.interceptors.success) {
183
+ _this._alertSuccess(event, data);
184
+ execute(_this._params.callback.afterSuccess, [_this._element, _this, event, data]);
185
+ } else {
186
+ execute(_this._params.callback.afterSuccess, [_this._element, _this, event, data]);
187
+ }
166
188
  }
167
189
  }
168
190
  }
169
- }
191
+ });
192
+ };
193
+
194
+ _this._params.interceptors.beforeSend().then(() => {
195
+ submit();
170
196
  });
171
197
  }
172
198
 
@@ -202,55 +228,35 @@ class VGFormSender extends BaseModule {
202
228
  }
203
229
 
204
230
  _statusButton(status) {
205
- const _this = this;
206
-
207
- if (!_this._button) return;
231
+ if (!this._button) return;
208
232
 
209
- let btnSubmitText = _this._button,
210
- btnText = {
211
- send: 'Отправляем...',
212
- text: 'Отправить'
213
- };
214
-
215
- if (Manipulator.has(_this._button, 'data-spinner') && status === 'before') {
216
- _this._button.insertAdjacentHTML('afterbegin', '<span class="spinner-border spinner-border-sm me-2"></span>');
217
- }
233
+ if (status === 'before') {
234
+ const button = getDeepestLastChild(this._button) || this._button;
218
235
 
219
- if (Manipulator.has(_this._button, 'data-text')) {
220
- btnText.text = Manipulator.get(_this._button, 'data-text');
221
- } else {
222
- let $btnText = _this._button.querySelector('[data-text]');
223
- if ($btnText) {
224
- btnText.text = Manipulator.get($btnText, 'data-text');
225
- btnSubmitText = $btnText;
236
+ if (this._params.button.spinner.enabled) {
237
+ this._button.insertAdjacentHTML('afterbegin', this._params.button.spinner.element);
226
238
  }
227
- }
228
239
 
229
- if (Manipulator.has(_this._button, 'data-text-send')) {
230
- btnText.send = Manipulator.get(_this._button, 'data-text-send');
231
- } else {
232
- let $btnTextSend = _this._button.querySelector('[data-text-send]');
233
- if ($btnTextSend) {
234
- btnText.send = Manipulator.get($btnTextSend, 'data-text-send');
235
- btnSubmitText = $btnTextSend;
240
+ if (this._params.button.enabled) {
241
+ button.innerHTML = this._params.button.send
236
242
  }
237
- }
238
243
 
239
- if (status === 'before') {
240
- if (_this._params.isBtnText) {
241
- btnSubmitText.innerHTML = btnText.send;
244
+ if (this._params.button.disabled) {
245
+ Manipulator.set(this._button,'disabled', 'disabled');
242
246
  }
243
- Manipulator.set(_this._button,'disabled', 'disabled');
244
247
  }
245
248
 
246
249
  if (status === 'after') {
247
- if (_this._params.isBtnText) {
248
- btnSubmitText.innerHTML = btnText.text;
250
+ if (this._params.button.enabled) {
251
+ this._button.innerHTML = this._params.button.initial;
252
+ }
253
+ if (this._params.button.disabled) {
254
+ Manipulator.remove(this._button,'disabled');
255
+ }
256
+ if (this._params.button.spinner.enabled) {
257
+ let spinner = this._button.querySelector('.spinner-border');
258
+ if (spinner) spinner.remove();
249
259
  }
250
- Manipulator.remove(_this._button,'disabled');
251
-
252
- let spinner = _this._button.querySelector('.spinner-border');
253
- if (spinner) spinner.remove();
254
260
  }
255
261
  }
256
262
 
@@ -523,7 +529,7 @@ EventHandler.on(document, EVENT_SUBMIT_DATA_API, function (event) {
523
529
  }
524
530
  }
525
531
 
526
- const collectData = function(data, fields) {
532
+ /*const collectData = function(data, fields) {
527
533
  for (let name in fields) {
528
534
  if (typeof fields[name] === 'object') {
529
535
  for (let key in fields[name]) {
@@ -538,19 +544,19 @@ EventHandler.on(document, EVENT_SUBMIT_DATA_API, function (event) {
538
544
  }
539
545
 
540
546
  return data;
541
- }
547
+ }*/
542
548
 
543
549
  if (!instance._params.submit) {
544
550
  event.preventDefault();
545
551
 
546
- let data = new FormData(instance._element);
552
+ //let data = new FormData(instance._element);
547
553
 
548
554
  // TODO доделать
549
555
  /*if (Array.isArray(instance._params.ajax.fields) && instance._params.ajax.fields.length) {
550
556
  data = collectData(data, instance._params.ajax.fields);
551
557
  }*/
552
558
 
553
- return instance.request(data, event);
559
+ return instance.request(event);
554
560
  }
555
561
  })
556
562
 
@@ -17,24 +17,30 @@ class Params {
17
17
  merge(params, element) {
18
18
  let mParams = mergeDeepObject(params, this.fromElement(element));
19
19
 
20
- for (let key in mParams) {
21
- if (key.indexOf('-') !== -1) {
22
- let keys = key.split('-'),
23
- value = normalizeData(mParams[key]);
24
-
25
- if (keys[0] in mParams) {
26
- if (keys[1] in mParams[keys[0]]) {
27
- mParams[keys[0]][keys[1]] = value;
28
- }
20
+ function stringToNestedObjectWithValue(str, value, params) {
21
+ const keys = str.split('-');
22
+ let result = {};
23
+ let currentLevel = result;
24
+
25
+ for (let i = 0; i < keys.length; i++) {
26
+ const key = keys[i];
27
+
28
+ if (i < keys.length - 1) {
29
+ currentLevel[key] = {};
30
+ currentLevel = currentLevel[key];
31
+ } else {
32
+ currentLevel[key] = value;
29
33
  }
30
-
31
- delete mParams[key];
32
34
  }
35
+
36
+ return mergeDeepObject(params, result);
33
37
  }
34
38
 
35
- if ('params' in mParams) {
36
- mParams = mergeDeepObject(mParams, mParams.params);
37
- delete mParams.params;
39
+ for (let key in mParams) {
40
+ if (key.indexOf('-') !== -1) {
41
+ mParams = stringToNestedObjectWithValue(key, mParams[key], mParams);
42
+ delete mParams[key];
43
+ }
38
44
  }
39
45
 
40
46
  return mParams;
@@ -345,9 +345,24 @@ const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed
345
345
  return list[Math.max(0, Math.min(index, listLength - 1))]
346
346
  }
347
347
 
348
+ /**
349
+ * Рекурсивный поиск самого глубокого последнего потомка
350
+ * @param element
351
+ * @returns {*}
352
+ */
353
+ function getDeepestLastChild(element) {
354
+ let current = element;
355
+
356
+ while (current.lastElementChild) {
357
+ current = current.lastElementChild;
358
+ }
359
+
360
+ return current;
361
+ }
362
+
348
363
  /**
349
364
  *
350
365
  */
351
366
  const isRTL = () => document.documentElement.dir === 'rtl'
352
367
 
353
- export {isElement, isVisible, isDisabled, isObject, isEmptyObj, mergeDeepObject, removeElementArray, normalizeData, execute, executeAfterTransition, reflow, noop, makeRandomString, isRTL, transliterate, getElement, getNextActiveElement}
368
+ export {getDeepestLastChild, isElement, isVisible, isDisabled, isObject, isEmptyObj, mergeDeepObject, removeElementArray, normalizeData, execute, executeAfterTransition, reflow, noop, makeRandomString, isRTL, transliterate, getElement, getNextActiveElement}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vgapp",
3
- "version": "0.6.9",
3
+ "version": "0.7.1",
4
4
  "description": "",
5
5
  "author": {
6
6
  "name": "Vegas Studio",