Compare commits
No commits in common. "main" and "v0.1" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +0,0 @@
|
||||
.idea/
|
||||
43
README.md
43
README.md
@ -35,11 +35,10 @@
|
||||
|
||||
## Основные концепции
|
||||
|
||||
Библиотека работает с тремя основными режимами открытия диалога:
|
||||
Библиотека работает с двумя основными режимами открытия диалога:
|
||||
|
||||
- **create** — создание нового элемента (пустая форма)
|
||||
- **update** — редактирование существующего элемента (форма с подгруженными данными)
|
||||
- **create from** — создание нового элемента из существующего (форма с подгруженными данными)
|
||||
|
||||
Каждый диалог имеет:
|
||||
- Уникальный строковый идентификатор (dialogId)
|
||||
@ -144,19 +143,6 @@ dialog.openUpdate(42, 'Редактирование пользователя')
|
||||
});
|
||||
```
|
||||
|
||||
#### openCreateFrom(itemId, title)
|
||||
Открывает диалог в режиме создания с загруженными данными через GET endpoint.
|
||||
|
||||
```javascript
|
||||
dialog.openUpdate(42, 'Создание копии пользователя')
|
||||
.onSuccess(function(result) {
|
||||
console.log('Создана копия:', result);
|
||||
})
|
||||
.onError(function(error) {
|
||||
console.error('Ошибка:', error);
|
||||
});
|
||||
```
|
||||
|
||||
#### getConfig()
|
||||
Возвращает текущую конфигурацию диалога.
|
||||
|
||||
@ -210,16 +196,6 @@ api.onDelete(function(itemId) {
|
||||
});
|
||||
```
|
||||
|
||||
#### onOpen(callback)
|
||||
Устанавливает обработчик успешного открытия. Если диалог открыт
|
||||
в режиме редактирования, функция будет вызвана после загрузки всех данных.
|
||||
|
||||
```javascript
|
||||
api.onOpen(function() {
|
||||
console.log('Диалог открыт и загружен');
|
||||
});
|
||||
```
|
||||
|
||||
#### setValues(values)
|
||||
Устанавливает значения полей формы.
|
||||
|
||||
@ -294,14 +270,6 @@ crud_d.openUpdate('user_form', 42, 'Редактирование')
|
||||
});
|
||||
```
|
||||
|
||||
#### openCreateFrom(dialogId, itemId, title)
|
||||
```javascript
|
||||
crud_d.openUpdate('user_form', 42, 'Копирование')
|
||||
.onSuccess(function(result) {
|
||||
console.log('Создан из объекта:', result);
|
||||
});
|
||||
```
|
||||
|
||||
#### closeDialog(dialogId)
|
||||
```javascript
|
||||
crud_d.closeDialog('user_form');
|
||||
@ -680,15 +648,6 @@ dialog.openCreate('Новый заказ')
|
||||
- При удалении: подтверждение → DELETE запрос → `onDelete`/`onError`
|
||||
- Автоматическое закрытие диалога при успехе
|
||||
|
||||
3. **Создание из существующего элемента (create from):**
|
||||
- GET запрос на get endpoint для загрузки данных
|
||||
- Заполнение формы полученными данными
|
||||
- Валидация формы
|
||||
- POST запрос на create endpoint
|
||||
- `onSuccess` при успехе
|
||||
- `onError` при ошибке
|
||||
- Автоматическое закрытие диалога при успехе
|
||||
|
||||
### Цепочка методов
|
||||
|
||||
Все методы настройки возвращают `this`, что позволяет использовать цепочку вызовов:
|
||||
|
||||
48
crud_d.js
48
crud_d.js
@ -1,3 +1,4 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Хранилище зарегистрированных диалогов
|
||||
@ -322,7 +323,6 @@ async function apiRequest(method, url, data = null) {
|
||||
const options = {
|
||||
method,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content ?? '',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
};
|
||||
@ -365,7 +365,7 @@ function createModal(dialogId, title, fields, options = {}, mode = 'create', ite
|
||||
|
||||
// Заголовок
|
||||
const header = dom.div().cls('modal-header');
|
||||
const titleText = mode === 'create' ? title : mode === 'create_from' ? `Скопировать из: ${title}` : `Редактирование: ${title}`;
|
||||
const titleText = mode === 'create' ? title : `Редактирование: ${title}`;
|
||||
const titleEl = dom.h5().cls('modal-title').text(titleText);
|
||||
const closeBtn = dom.button().cls('btn-close').atr('data-bs-dismiss', 'modal').atr('aria-label', 'Close');
|
||||
header.child(titleEl);
|
||||
@ -413,7 +413,7 @@ function createModal(dialogId, title, fields, options = {}, mode = 'create', ite
|
||||
const categoryNames = Object.keys(finalCategories);
|
||||
|
||||
const tabNav = dom.ul().cls('nav nav-tabs').atr('role', 'tablist');
|
||||
const tabContent = dom.div().cls('tab-content').cls('mt-3');
|
||||
const tabContent = dom.div().cls('tab-content');
|
||||
|
||||
categoryNames.forEach((catName, index) => {
|
||||
const tabId = `tab_${dialogId}_${catName.replace(/[^a-zA-Z0-9]/g, '_')}`;
|
||||
@ -475,7 +475,7 @@ function createModal(dialogId, title, fields, options = {}, mode = 'create', ite
|
||||
const submitSpinner = dom.span().cls('spinner-border spinner-border-sm').atr('role', 'status')
|
||||
.atr('aria-hidden', 'true').css('display: none');
|
||||
|
||||
if (mode === 'create' || mode === 'create_from') {
|
||||
if (mode === 'create') {
|
||||
submitBtn.text('Создать');
|
||||
submitBtn.child(submitSpinner);
|
||||
footer.child(cancelBtn);
|
||||
@ -630,10 +630,6 @@ window.crud_d = {
|
||||
return this._open(title, 'create');
|
||||
},
|
||||
|
||||
openCreateFrom: function(itemId, title = 'Скопировать из') {
|
||||
return this._open(title, 'create_from', itemId);
|
||||
},
|
||||
|
||||
// Открытие в режиме обновления
|
||||
openUpdate: function(itemId, title = 'Редактирование') {
|
||||
return this._open(title, 'update', itemId);
|
||||
@ -652,10 +648,6 @@ window.crud_d = {
|
||||
activeDialogs.set(dialogId, modal);
|
||||
|
||||
const api = {
|
||||
onOpen: function(callback) {
|
||||
modal.onOpen = callback;
|
||||
return this;
|
||||
},
|
||||
onSuccess: function(callback) {
|
||||
modal.onSuccess = callback;
|
||||
return this;
|
||||
@ -689,7 +681,7 @@ window.crud_d = {
|
||||
};
|
||||
|
||||
// Загрузка данных для режима update
|
||||
if ((mode === 'update' || mode === 'create_from') && itemId) {
|
||||
if (mode === 'update' && itemId) {
|
||||
modal.showLoadingOverlay();
|
||||
|
||||
const getEndpoint = config.endpoints.get;
|
||||
@ -706,9 +698,6 @@ window.crud_d = {
|
||||
.then(data => {
|
||||
modal.setValues(data);
|
||||
modal.hideLoadingOverlay();
|
||||
if (typeof modal.onOpen === 'function') {
|
||||
modal.onOpen(modal);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
modal.hideLoadingOverlay();
|
||||
@ -716,14 +705,6 @@ window.crud_d = {
|
||||
});
|
||||
}
|
||||
|
||||
if (mode === 'create') {
|
||||
setTimeout(() => {
|
||||
if (typeof modal.onOpen === 'function') {
|
||||
modal.onOpen(modal);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// Обработчик сохранения/создания
|
||||
modal.submitBtn.addEventListener('click', async () => {
|
||||
const errors = modal.validate();
|
||||
@ -739,7 +720,7 @@ window.crud_d = {
|
||||
const formData = modal.getFormData();
|
||||
let result;
|
||||
|
||||
if (mode === 'create' || mode === 'create_from') {
|
||||
if (mode === 'create') {
|
||||
const createEndpoint = config.endpoints.create;
|
||||
if (!createEndpoint) {
|
||||
throw new Error('Create endpoint не установлен');
|
||||
@ -842,6 +823,8 @@ window.crud_d = {
|
||||
return dialogApi;
|
||||
},
|
||||
|
||||
// Глобальные методы для работы по имени диалога
|
||||
|
||||
// Установка эндпоинтов по имени диалога
|
||||
setCreateEndpoint: function(dialogId, endpoint) {
|
||||
const dialog = dialogs.get(dialogId);
|
||||
@ -893,19 +876,6 @@ window.crud_d = {
|
||||
}
|
||||
},
|
||||
|
||||
openCreateFrom: function(dialogId, itemId, title = 'Скопировать из') {
|
||||
const dialog = dialogs.get(dialogId);
|
||||
if (dialog) {
|
||||
const api = this.makeDialog(dialogId, dialog.fields, dialog.options);
|
||||
// Копируем эндпоинты
|
||||
api.getConfig().endpoints = dialog.endpoints;
|
||||
return api.openCreateFrom(itemId, title);
|
||||
} else {
|
||||
console.error(`Диалог "${dialogId}" не найден`);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
openUpdate: function(dialogId, itemId, title = 'Редактирование') {
|
||||
const dialog = dialogs.get(dialogId);
|
||||
if (dialog) {
|
||||
@ -937,3 +907,5 @@ window.crud_d = {
|
||||
activeDialogs.clear();
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
Loading…
x
Reference in New Issue
Block a user