236 lines
7.4 KiB
JavaScript
236 lines
7.4 KiB
JavaScript
|
/* global $, document */
|
|||
|
|
|||
|
// Функция для создания модального окна
|
|||
|
function createModal(options) {
|
|||
|
// Если модальное окно уже существует, удаляем его
|
|||
|
$('.modal-overlay').remove();
|
|||
|
|
|||
|
// Опции по умолчанию
|
|||
|
const defaultOptions = {
|
|||
|
title: 'Сообщение',
|
|||
|
content: '',
|
|||
|
closeText: 'Закрыть',
|
|||
|
onClose: null,
|
|||
|
showCancel: false,
|
|||
|
cancelText: 'Отмена',
|
|||
|
confirmText: 'Подтвердить',
|
|||
|
onConfirm: null,
|
|||
|
onCancel: null,
|
|||
|
size: 'normal', // 'normal', 'large', 'small'
|
|||
|
customClass: '',
|
|||
|
autoClose: false, // Автоматическое закрытие по таймеру
|
|||
|
autoCloseTime: 2000 // Время до автоматического закрытия (2 секунды)
|
|||
|
};
|
|||
|
|
|||
|
// Объединяем пользовательские опции с опциями по умолчанию
|
|||
|
const settings = $.extend({}, defaultOptions, options);
|
|||
|
|
|||
|
// Создаем структуру модального окна
|
|||
|
const $modalOverlay = $('<div>', { class: 'modal-overlay' });
|
|||
|
const $modal = $('<div>', { class: `modal ${settings.customClass}` });
|
|||
|
|
|||
|
// Устанавливаем ширину в зависимости от размера
|
|||
|
if (settings.size === 'large') {
|
|||
|
$modal.css('max-width', '700px');
|
|||
|
} else if (settings.size === 'small') {
|
|||
|
$modal.css('max-width', '400px');
|
|||
|
}
|
|||
|
|
|||
|
// Создаем заголовок
|
|||
|
const $modalHeader = $('<div>', { class: 'modal-header' });
|
|||
|
const $modalTitle = $('<h3>', { text: settings.title });
|
|||
|
const $modalClose = $('<button>', {
|
|||
|
class: 'modal-close',
|
|||
|
html: '×',
|
|||
|
click: function() {
|
|||
|
closeModal();
|
|||
|
if (typeof settings.onClose === 'function') {
|
|||
|
settings.onClose();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
$modalHeader.append($modalTitle, $modalClose);
|
|||
|
|
|||
|
// Создаем тело
|
|||
|
const $modalBody = $('<div>', { class: 'modal-body' });
|
|||
|
if (typeof settings.content === 'string') {
|
|||
|
$modalBody.html(settings.content);
|
|||
|
} else {
|
|||
|
$modalBody.append(settings.content);
|
|||
|
}
|
|||
|
|
|||
|
// Создаем футер
|
|||
|
const $modalFooter = $('<div>', { class: 'modal-footer' });
|
|||
|
|
|||
|
// Если нужно показать кнопку отмены
|
|||
|
if (settings.showCancel) {
|
|||
|
const $cancelButton = $('<button>', {
|
|||
|
class: 'btn btn-secondary',
|
|||
|
text: settings.cancelText,
|
|||
|
click: function() {
|
|||
|
closeModal();
|
|||
|
if (typeof settings.onCancel === 'function') {
|
|||
|
settings.onCancel();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
$modalFooter.append($cancelButton);
|
|||
|
}
|
|||
|
|
|||
|
// Кнопка подтверждения/закрытия
|
|||
|
const $confirmButton = $('<button>', {
|
|||
|
class: settings.showCancel ? 'btn btn-primary' : 'btn',
|
|||
|
text: settings.showCancel ? settings.confirmText : settings.closeText,
|
|||
|
click: function() {
|
|||
|
closeModal();
|
|||
|
if (settings.showCancel && typeof settings.onConfirm === 'function') {
|
|||
|
settings.onConfirm();
|
|||
|
} else if (!settings.showCancel && typeof settings.onClose === 'function') {
|
|||
|
settings.onClose();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
$modalFooter.append($confirmButton);
|
|||
|
|
|||
|
// Добавляем прогресс-бар, если включено автоматическое закрытие
|
|||
|
if (settings.autoClose) {
|
|||
|
const $progressBar = $('<div>', { class: 'modal-progress' });
|
|||
|
$modal.append($progressBar);
|
|||
|
}
|
|||
|
|
|||
|
// Собираем модальное окно
|
|||
|
$modal.append($modalHeader, $modalBody, $modalFooter);
|
|||
|
$modalOverlay.append($modal);
|
|||
|
|
|||
|
// Добавляем модальное окно в DOM
|
|||
|
$('body').append($modalOverlay);
|
|||
|
|
|||
|
// Закрытие по клику на фоне
|
|||
|
$modalOverlay.on('click', function(e) {
|
|||
|
if (e.target === this) {
|
|||
|
closeModal();
|
|||
|
if (typeof settings.onClose === 'function') {
|
|||
|
settings.onClose();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
// Функция закрытия модального окна
|
|||
|
function closeModal() {
|
|||
|
$modalOverlay.removeClass('active');
|
|||
|
setTimeout(function() {
|
|||
|
$modalOverlay.remove();
|
|||
|
}, 300);
|
|||
|
}
|
|||
|
|
|||
|
// Активируем модальное окно
|
|||
|
setTimeout(function() {
|
|||
|
$modalOverlay.addClass('active');
|
|||
|
|
|||
|
// Активируем прогресс-бар и запускаем таймер закрытия, если включено автоматическое закрытие
|
|||
|
if (settings.autoClose) {
|
|||
|
const $progressBar = $modal.find('.modal-progress');
|
|||
|
|
|||
|
setTimeout(() => {
|
|||
|
$progressBar.addClass('active');
|
|||
|
}, 50);
|
|||
|
|
|||
|
setTimeout(() => {
|
|||
|
closeModal();
|
|||
|
if (typeof settings.onClose === 'function') {
|
|||
|
settings.onClose();
|
|||
|
}
|
|||
|
}, settings.autoCloseTime);
|
|||
|
}
|
|||
|
}, 10);
|
|||
|
|
|||
|
// Возвращаем объект модального окна
|
|||
|
return {
|
|||
|
$modal: $modal,
|
|||
|
$overlay: $modalOverlay,
|
|||
|
close: closeModal
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// Функция для отображения модального окна с сообщением (замена alert)
|
|||
|
function showAlert(message, title, callback, autoClose = false) {
|
|||
|
return createModal({
|
|||
|
title: title || 'Сообщение',
|
|||
|
content: message,
|
|||
|
onClose: callback,
|
|||
|
autoClose: autoClose,
|
|||
|
autoCloseTime: 2000
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
// Функция для отображения модального окна с подтверждением (замена confirm)
|
|||
|
function showConfirm(message, callback, title) {
|
|||
|
return createModal({
|
|||
|
title: title || 'Подтверждение',
|
|||
|
content: message,
|
|||
|
showCancel: true,
|
|||
|
onConfirm: function() {
|
|||
|
if (typeof callback === 'function') {
|
|||
|
callback(true);
|
|||
|
}
|
|||
|
},
|
|||
|
onCancel: function() {
|
|||
|
if (typeof callback === 'function') {
|
|||
|
callback(false);
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
// Функция для генерации QR-кода
|
|||
|
function generateQRCode(data, size) {
|
|||
|
const typeNumber = 0; // Автоматическое определение
|
|||
|
const errorCorrectionLevel = 'L'; // Низкий уровень коррекции ошибок
|
|||
|
const qr = qrcode(typeNumber, errorCorrectionLevel);
|
|||
|
qr.addData(data);
|
|||
|
qr.make();
|
|||
|
return qr.createImgTag(size || 8, 0);
|
|||
|
}
|
|||
|
|
|||
|
// Функция для отображения QR-кода в модальном окне
|
|||
|
function showQRCodeModal(url, title) {
|
|||
|
const qrCode = generateQRCode(url);
|
|||
|
const content = `
|
|||
|
<div class="qr-container">
|
|||
|
<div class="qr-code">
|
|||
|
${qrCode}
|
|||
|
</div>
|
|||
|
<div class="qr-link-container">
|
|||
|
<input type="text" class="qr-link-input" value="${url}" readonly>
|
|||
|
<button class="btn btn-copy-link">Копировать</button>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
`;
|
|||
|
|
|||
|
const modal = createModal({
|
|||
|
title: title || 'QR-код для доступа',
|
|||
|
content: content,
|
|||
|
size: 'large'
|
|||
|
});
|
|||
|
|
|||
|
// Добавляем обработчик для кнопки копирования
|
|||
|
modal.$modal.find('.btn-copy-link').on('click', function() {
|
|||
|
const input = modal.$modal.find('.qr-link-input');
|
|||
|
input.select();
|
|||
|
document.execCommand('copy');
|
|||
|
|
|||
|
// Показываем уведомление о копировании
|
|||
|
const $button = $(this);
|
|||
|
const originalText = $button.text();
|
|||
|
$button.text('Скопировано!');
|
|||
|
$button.addClass('copied');
|
|||
|
|
|||
|
setTimeout(function() {
|
|||
|
$button.text(originalText);
|
|||
|
$button.removeClass('copied');
|
|||
|
}, 1500);
|
|||
|
});
|
|||
|
|
|||
|
return modal;
|
|||
|
}
|