# Документация библиотеки CRUD Dialogs Библиотека для создания модальных диалоговых окон на основе Bootstrap с поддержкой CRUD операций, вкладок и гибкой настройкой макета. ## Оглавление 1. [Подключение](#подключение) 2. [Основные концепции](#основные-концепции) 3. [API Reference](#api-reference) - [makeDialog](#makedialog) - [Методы объекта диалога](#методы-объекта-диалога) - [Глобальные методы](#глобальные-методы) 4. [Типы полей](#типы-полей) 5. [Настройки диалога](#настройки-диалога) 6. [Layout и категории](#layout-и-категории) 7. [Примеры использования](#примеры-использования) --- ## Подключение ```html ``` --- ## Основные концепции Библиотека работает с тремя основными режимами открытия диалога: - **create** — создание нового элемента (пустая форма) - **update** — редактирование существующего элемента (форма с подгруженными данными) - **create from** — создание нового элемента из существующего (форма с подгруженными данными) Каждый диалог имеет: - Уникальный строковый идентификатор (dialogId) - Набор полей с типами и настройками - Эндпоинты для CRUD операций (устанавливаются отдельно) - Опциональные настройки отображения (ширина, категории) Управлять диалогом можно: - Через объект, полученный при создании - Через глобальные методы, используя dialogId --- ## API Reference ### makeDialog Создает новый диалог и возвращает объект для работы с ним. ```javascript crud_d.makeDialog(dialogId, fields, options) ``` **Параметры:** | Параметр | Тип | Обязательный | Описание | |----------|-----|--------------|----------| | dialogId | string | Да | Уникальный идентификатор диалога (не DOM id) | | fields | object | Да | Объект с описанием полей | | options | object | Нет | Дополнительные настройки диалога | **Возвращает:** Объект диалога с методами управления. **Пример:** ```javascript const dialog = crud_d.makeDialog('user_form', { name: ['text', { label: 'Имя', required: true }, ''], email: ['email', { label: 'Email', required: true }, ''] }, { width: 'lg' }); ``` --- ### Методы объекта диалога #### setCreateEndpoint(endpoint) Устанавливает endpoint для создания элемента (POST). ```javascript dialog.setCreateEndpoint('/api/users') ``` #### setUpdateEndpoint(endpoint) Устанавливает endpoint для обновления элемента (PUT). Используйте `{id}` для подстановки ID элемента. ```javascript dialog.setUpdateEndpoint('/api/users/{id}') ``` #### setGetEndpoint(endpoint) Устанавливает endpoint для получения данных элемента (GET). Используйте `{id}` для подстановки ID элемента. ```javascript dialog.setGetEndpoint('/api/users/{id}') ``` #### setDeleteEndpoint(endpoint) Устанавливает endpoint для удаления элемента (DELETE). Используйте `{id}` для подстановки ID элемента. ```javascript dialog.setDeleteEndpoint('/api/users/{id}') ``` #### openCreate(title) Открывает диалог в режиме создания. ```javascript dialog.openCreate('Новый пользователь') .onSuccess(function(result) { console.log('Создан:', result); }) .onError(function(error) { console.error('Ошибка:', error); }); ``` #### openUpdate(itemId, title) Открывает диалог в режиме редактирования. Автоматически загружает данные через GET endpoint. ```javascript dialog.openUpdate(42, 'Редактирование пользователя') .onSuccess(function(result) { console.log('Обновлен:', result); }) .onDelete(function(id) { console.log('Удален:', id); }) .onError(function(error) { console.error('Ошибка:', error); }); ``` #### openCreateFrom(itemId, title) Открывает диалог в режиме создания с загруженными данными через GET endpoint. ```javascript dialog.openUpdate(42, 'Создание копии пользователя') .onSuccess(function(result) { console.log('Создана копия:', result); }) .onError(function(error) { console.error('Ошибка:', error); }); ``` #### getConfig() Возвращает текущую конфигурацию диалога. ```javascript const config = dialog.getConfig(); console.log(config.fields, config.options, config.endpoints); ``` #### destroy() Удаляет регистрацию диалога и закрывает его, если открыт. ```javascript dialog.destroy(); ``` --- ### Методы API при открытом диалоге При открытии диалога возвращается объект с методами для управления текущим экземпляром: ```javascript const api = dialog.openCreate('Заголовок'); ``` #### onSuccess(callback) Устанавливает обработчик успешного выполнения операции. ```javascript api.onSuccess(function(result) { // result - данные, возвращенные сервером console.log('Успех:', result); }); ``` #### onError(callback) Устанавливает обработчик ошибок. ```javascript api.onError(function(error) { console.error('Ошибка:', error.message); }); ``` #### onDelete(callback) Устанавливает обработчик успешного удаления (только для режима update). ```javascript api.onDelete(function(itemId) { console.log('Удален элемент с ID:', itemId); }); ``` #### onOpen(callback) Устанавливает обработчик успешного открытия. Если диалог открыт в режиме редактирования, функция будет вызвана после загрузки всех данных. ```javascript api.onOpen(function() { console.log('Диалог открыт и загружен'); }); ``` #### setValues(values) Устанавливает значения полей формы. ```javascript api.setValues({ name: 'Иван', email: 'ivan@example.com' }); ``` #### getFormData() Возвращает текущие данные формы. ```javascript const data = api.getFormData(); console.log(data); ``` #### close() Закрывает диалог программно. ```javascript api.close(); ``` #### show() Показывает диалог (если был скрыт). ```javascript api.show(); ``` --- ### Глобальные методы Работа с диалогами через глобальный объект `crud_d` по dialogId. #### setCreateEndpoint(dialogId, endpoint) ```javascript crud_d.setCreateEndpoint('user_form', '/api/users'); ``` #### setUpdateEndpoint(dialogId, endpoint) ```javascript crud_d.setUpdateEndpoint('user_form', '/api/users/{id}'); ``` #### setGetEndpoint(dialogId, endpoint) ```javascript crud_d.setGetEndpoint('user_form', '/api/users/{id}'); ``` #### setDeleteEndpoint(dialogId, endpoint) ```javascript crud_d.setDeleteEndpoint('user_form', '/api/users/{id}'); ``` #### openCreate(dialogId, title) ```javascript crud_d.openCreate('user_form', 'Новый пользователь') .onSuccess(function(result) { console.log('Создан:', result); }); ``` #### openUpdate(dialogId, itemId, title) ```javascript crud_d.openUpdate('user_form', 42, 'Редактирование') .onSuccess(function(result) { console.log('Обновлен:', result); }); ``` #### 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'); ``` #### getRegisteredDialogs() ```javascript const dialogs = crud_d.getRegisteredDialogs(); console.log(dialogs); // ['user_form', 'product_form'] ``` #### closeAll() ```javascript crud_d.closeAll(); ``` --- ## Типы полей ### text Текстовое поле ввода. ```javascript fieldName: ['text', { label: 'Название поля', // string - заголовок required: true, // boolean - обязательно для заполнения placeholder: 'Подсказка', // string - текст-подсказка readonly: false, // boolean - только для чтения maxlength: 100 // number - максимальная длина }, 'значение по умолчанию'] ``` ### number Числовое поле ввода. ```javascript fieldName: ['number', { label: 'Цена', required: true, min: 0, // number - минимальное значение max: 1000000, // number - максимальное значение step: 0.01 // number - шаг изменения }, 0] ``` ### email Поле для email с валидацией формата. ```javascript fieldName: ['email', { label: 'Email', required: true, placeholder: 'user@example.com' }, ''] ``` ### password Поле для пароля (скрытый ввод). ```javascript fieldName: ['password', { label: 'Пароль', required: true, placeholder: 'Введите пароль' }, ''] ``` ### textarea Многострочное текстовое поле. ```javascript fieldName: ['textarea', { label: 'Описание', required: false, rows: 5 // number - количество строк }, ''] ``` ### select Выпадающий список. ```javascript fieldName: ['select', { label: 'Категория', required: true, options: [ // array - список опций { value: 'electronics', label: 'Электроника' }, { value: 'books', label: 'Книги' }, { value: 'clothing', label: 'Одежда' } ] }, 'electronics'] // значение по умолчанию ``` ### checkbox Флажок (чекбокс). ```javascript fieldName: ['checkbox', { label: 'Активен', required: false }, true] // значение по умолчанию ``` ### date Поле выбора даты. ```javascript fieldName: ['date', { label: 'Дата рождения', required: true }, '2024-01-01'] ``` ### custom Кастомное поле на основе HTMLElement. ```javascript const customElement = document.createElement('div'); customElement.innerHTML = ` `; fieldName: ['custom', customElement, '#ff0000'] ``` --- ## Настройки диалога Объект options передается третьим параметром в `makeDialog`: ```javascript { width: 'lg', // Ширина диалога: 'sm', 'lg', 'xl' или CSS значение ('800px', '90%') categories: { // Категории (вкладки) 'Основное': [ ['name', 'price'], ['description'] ], 'Дополнительно': [ ['sku', 'weight'], ['dimensions'] ] } } ``` --- ## Layout и категории ### Без категорий Если категории не указаны, все поля отображаются последовательно по одному в ряду. ```javascript crud_d.makeDialog('simple', { name: ['text', { label: 'Имя' }, ''], email: ['email', { label: 'Email' }, ''], phone: ['text', { label: 'Телефон' }, ''] }); ``` ### Layout в категориях Каждая категория содержит массив рядов. Ряд — это массив имен полей, которые будут в одной строке. ```javascript categories: { 'Основная информация': [ ['first_name', 'last_name'], // 2 поля в ряд ['email', 'phone'], // 2 поля в ряд ['address'] // 1 поле в ряд ], 'Дополнительно': [ ['birth_date', 'gender'], // 2 поля в ряд ['notes'] // 1 поле в ряд ] } ``` ### Автоматическая категория "Дополнительно" - Если указана только одна категория, все поля, не попавшие в неё, автоматически добавляются во вкладку "Дополнительно" - Если категорий несколько, нераспределенные поля также добавляются в "Дополнительно" - Если категории не указаны вообще, все поля идут подряд без вкладок ### Ширина колонок в ряду Автоматически рассчитывается на основе количества полей: - 1 поле: `col-12` (полная ширина) - 2 поля: `col-md-6` (по половине) - 3 поля: `col-md-4` (по трети) - 4 поля: `col-md-3` (по четверти) --- ## Примеры использования ### Простой диалог создания ```javascript const dialog = crud_d.makeDialog('simple_user', { name: ['text', { label: 'Имя', required: true }, ''], email: ['email', { label: 'Email', required: true }, ''] }); dialog.setCreateEndpoint('/api/users'); // Открытие dialog.openCreate('Новый пользователь') .onSuccess(function(result) { alert('Пользователь создан!'); }); ``` ### Диалог с обновлением и удалением ```javascript const dialog = crud_d.makeDialog('user_edit', { name: ['text', { label: 'Имя', required: true }, ''], email: ['email', { label: 'Email', required: true }, ''], role: ['select', { label: 'Роль', options: [ { value: 'user', label: 'Пользователь' }, { value: 'admin', label: 'Администратор' } ] }, 'user'] }); dialog.setGetEndpoint('/api/users/{id}'); dialog.setUpdateEndpoint('/api/users/{id}'); dialog.setDeleteEndpoint('/api/users/{id}'); // Открытие на редактирование dialog.openUpdate(42, 'Редактирование пользователя') .onSuccess(function(result) { console.log('Обновлен:', result); // Обновить список пользователей }) .onDelete(function(id) { console.log('Удален:', id); // Удалить из списка }) .onError(function(error) { alert('Ошибка: ' + error.message); }); ``` ### Сложный диалог с категориями ```javascript const dialog = crud_d.makeDialog('product_form', { name: ['text', { label: 'Название', required: true }, ''], price: ['number', { label: 'Цена', required: true, min: 0 }, 0], quantity: ['number', { label: 'Количество', min: 0 }, 0], category: ['select', { label: 'Категория', options: [ { value: 'electronics', label: 'Электроника' }, { value: 'clothing', label: 'Одежда' } ] }, 'electronics'], description: ['textarea', { label: 'Описание', rows: 5 }, ''], weight: ['number', { label: 'Вес (кг)', step: 0.1 }, null], dimensions: ['text', { label: 'Размеры' }, ''], manufacturer: ['text', { label: 'Производитель' }, ''], in_stock: ['checkbox', { label: 'В наличии' }, true] }, { width: 'lg', categories: { 'Основное': [ ['name'], ['price', 'quantity', 'in_stock'], ['category'], ['description'] ], 'Характеристики': [ ['weight', 'dimensions'], ['manufacturer'] ] } }); dialog.setCreateEndpoint('/api/products'); dialog.setGetEndpoint('/api/products/{id}'); dialog.setUpdateEndpoint('/api/products/{id}'); dialog.setDeleteEndpoint('/api/products/{id}'); ``` ### Глобальное управление ```javascript // Регистрируем диалог crud_d.makeDialog('quick_user', { name: ['text', { label: 'Имя' }, ''], email: ['email', { label: 'Email' }, ''] }); // Устанавливаем эндпоинты глобально crud_d.setCreateEndpoint('quick_user', '/api/users'); crud_d.setGetEndpoint('quick_user', '/api/users/{id}'); // Открываем из любого места crud_d.openCreate('quick_user', 'Быстрое создание') .onSuccess(function(result) { console.log('Готово!', result); }); // Закрываем при необходимости crud_d.closeDialog('quick_user'); // Закрыть все открытые диалоги crud_d.closeAll(); ``` ### Кастомное поле ```javascript // Создаем кастомный элемент для выбора цвета const colorPicker = document.createElement('div'); colorPicker.className = 'mb-3'; colorPicker.innerHTML = `