export const ESCAPE_MAP = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; export function escapeHtml(str) { if (!str) return ''; return String(str).replace(/[&<>"']/g, m => ESCAPE_MAP[m]); } export function showAlert(elementId, msg, type) { const el = document.getElementById(elementId); if (!el) return; el.className = 'form-alert ' + type; el.textContent = msg; } export function hideAlert(elementId) { const el = document.getElementById(elementId); if (!el) return; el.className = 'form-alert'; el.textContent = ''; } export function applyRippleEffect() { document.addEventListener('click', function (e) { const btn = e.target.closest('.btn-primary, .btn-delete, .btn-logout'); if (!btn) return; const rect = btn.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; if (getComputedStyle(btn).position === 'static') { btn.style.position = 'relative'; } btn.style.overflow = 'hidden'; btn.appendChild(ripple); setTimeout(() => ripple.remove(), 600); }); } export function initMultiSelect(boxId, menuId, textId, checkboxContainerId) { const box = document.getElementById(boxId); const menu = document.getElementById(menuId); const container = document.getElementById(checkboxContainerId); if (!box || !menu || !container) return; // Remove old listeners to prevent duplication if re-initialized const newBox = box.cloneNode(true); box.parentNode.replaceChild(newBox, box); newBox.addEventListener('click', (e) => { e.stopPropagation(); const isOpen = menu.classList.contains('open'); document.querySelectorAll('.dropdown-menu').forEach(m => m.classList.remove('open')); document.querySelectorAll('.select-box').forEach(b => b.classList.remove('active')); if (!isOpen) { menu.classList.add('open'); newBox.classList.add('active'); } }); menu.addEventListener('click', (e) => { e.stopPropagation(); }); container.addEventListener('change', () => { updateSelectText(checkboxContainerId, textId); }); } export function updateSelectText(containerId, textId) { const container = document.getElementById(containerId); const textEl = document.getElementById(textId); if (!container || !textEl) return; const checked = Array.from(container.querySelectorAll('input:checked')); if (checked.length === 0) { textEl.textContent = 'Выберите оборудование...'; } else if (checked.length === 1) { textEl.textContent = checked[0].parentElement.textContent.trim(); } else { textEl.textContent = `Выбрано: ${checked.length}`; } } export function closeAllDropdownsOnOutsideClick() { document.addEventListener('click', () => { document.querySelectorAll('.dropdown-menu').forEach(m => m.classList.remove('open')); document.querySelectorAll('.select-box').forEach(b => b.classList.remove('active')); }); }