193 lines
6.1 KiB
JavaScript
193 lines
6.1 KiB
JavaScript
// Основной JavaScript файл
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Автоматическое скрытие уведомлений через 5 секунд
|
|
const alerts = document.querySelectorAll('.alert');
|
|
alerts.forEach(alert => {
|
|
setTimeout(() => {
|
|
alert.style.transition = 'opacity 0.5s';
|
|
alert.style.opacity = '0';
|
|
setTimeout(() => alert.remove(), 500);
|
|
}, 5000);
|
|
});
|
|
|
|
// Валидация форм на клиенте
|
|
const forms = document.querySelectorAll('form[data-validate]');
|
|
forms.forEach(form => {
|
|
form.addEventListener('submit', function(e) {
|
|
if (!validateForm(form)) {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
});
|
|
|
|
// Подтверждение удаления
|
|
const deleteButtons = document.querySelectorAll('[data-confirm]');
|
|
deleteButtons.forEach(button => {
|
|
button.addEventListener('click', function(e) {
|
|
if (!confirm(this.dataset.confirm || 'Вы уверены?')) {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
});
|
|
|
|
// Форматирование чисел
|
|
formatNumbers();
|
|
});
|
|
|
|
function validateForm(form) {
|
|
let isValid = true;
|
|
const requiredFields = form.querySelectorAll('[required]');
|
|
|
|
requiredFields.forEach(field => {
|
|
if (!field.value.trim()) {
|
|
showFieldError(field, 'Это поле обязательно для заполнения');
|
|
isValid = false;
|
|
} else {
|
|
clearFieldError(field);
|
|
}
|
|
|
|
// Проверка на отрицательные числа
|
|
if (field.type === 'number' && field.min && parseFloat(field.value) < parseFloat(field.min)) {
|
|
showFieldError(field, `Значение должно быть не меньше ${field.min}`);
|
|
isValid = false;
|
|
}
|
|
|
|
// Проверка email
|
|
if (field.type === 'email' && field.value) {
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(field.value)) {
|
|
showFieldError(field, 'Введите корректный email');
|
|
isValid = false;
|
|
}
|
|
}
|
|
});
|
|
|
|
return isValid;
|
|
}
|
|
|
|
function showFieldError(field, message) {
|
|
clearFieldError(field);
|
|
|
|
const errorDiv = document.createElement('div');
|
|
errorDiv.className = 'field-error';
|
|
errorDiv.style.color = '#ff6b6b';
|
|
errorDiv.style.fontSize = '0.85rem';
|
|
errorDiv.style.marginTop = '5px';
|
|
errorDiv.textContent = message;
|
|
|
|
field.style.borderColor = '#ff6b6b';
|
|
field.parentNode.appendChild(errorDiv);
|
|
}
|
|
|
|
function clearFieldError(field) {
|
|
field.style.borderColor = '';
|
|
const error = field.parentNode.querySelector('.field-error');
|
|
if (error) {
|
|
error.remove();
|
|
}
|
|
}
|
|
|
|
function formatNumbers() {
|
|
// Форматирование цен
|
|
const priceElements = document.querySelectorAll('.format-price');
|
|
priceElements.forEach(el => {
|
|
const price = parseFloat(el.textContent);
|
|
if (!isNaN(price)) {
|
|
el.textContent = price.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,') + ' ₽';
|
|
}
|
|
});
|
|
|
|
// Форматирование количества
|
|
const quantityElements = document.querySelectorAll('.format-quantity');
|
|
quantityElements.forEach(el => {
|
|
const quantity = parseInt(el.textContent);
|
|
if (!isNaN(quantity)) {
|
|
el.textContent = quantity.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Фильтрация таблиц
|
|
function filterTable(inputId, tableId) {
|
|
const input = document.getElementById(inputId);
|
|
const filter = input.value.toUpperCase();
|
|
const table = document.getElementById(tableId);
|
|
const rows = table.getElementsByTagName('tr');
|
|
|
|
for (let i = 1; i < rows.length; i++) {
|
|
const cells = rows[i].getElementsByTagName('td');
|
|
let found = false;
|
|
|
|
for (let j = 0; j < cells.length; j++) {
|
|
const cell = cells[j];
|
|
if (cell) {
|
|
const textValue = cell.textContent || cell.innerText;
|
|
if (textValue.toUpperCase().indexOf(filter) > -1) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
rows[i].style.display = found ? '' : 'none';
|
|
}
|
|
}
|
|
|
|
// Экспорт в CSV
|
|
function exportToCSV(tableId, filename) {
|
|
const table = document.getElementById(tableId);
|
|
const rows = table.querySelectorAll('tr');
|
|
const csv = [];
|
|
|
|
rows.forEach(row => {
|
|
const cols = row.querySelectorAll('td, th');
|
|
const rowData = [];
|
|
cols.forEach(col => {
|
|
rowData.push('"' + col.innerText.replace(/"/g, '""') + '"');
|
|
});
|
|
csv.push(rowData.join(','));
|
|
});
|
|
|
|
const csvContent = csv.join('\n');
|
|
const blob = new Blob(["\uFEFF" + csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
const link = document.createElement('a');
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
link.setAttribute('href', url);
|
|
link.setAttribute('download', filename || 'export.csv');
|
|
link.style.visibility = 'hidden';
|
|
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
}
|
|
|
|
// Печать
|
|
function printElement(elementId) {
|
|
const element = document.getElementById(elementId);
|
|
if (!element) return;
|
|
|
|
const printWindow = window.open('', '_blank');
|
|
printWindow.document.write(`
|
|
<html>
|
|
<head>
|
|
<title>Печать</title>
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
<style>
|
|
body { padding: 20px; }
|
|
@media print {
|
|
.no-print { display: none; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
${element.outerHTML}
|
|
<script>
|
|
window.onload = function() { window.print(); window.close(); }
|
|
</script>
|
|
</body>
|
|
</html>
|
|
`);
|
|
printWindow.document.close();
|
|
} |