/
RoditelevVV
/
web-static-labs
Обзор
Документация
Войти
/
RoditelevVV
/
web-static-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
html/lab5/task4/script.js
280 строк
10 KB
karpov
finish lab3, lab4
12 мар 2026, 08:19
12 мар 2026, 08:19
74cd197
Код
Авторство
О чём код?
class ContactsManager { constructor() { this.contacts = JSON.parse(localStorage.getItem('contacts')) || []; this.filteredContacts = [...this.contacts]; this.currentFilters = { lastName: '', firstName: '', age: '', phone: '' }; this.initializeElements(); this.setupEventListeners(); this.renderContacts(); this.updateContactsCount(); } initializeElements() { this.contactForm = document.getElementById('contactForm'); this.lastNameInput = document.getElementById('lastName'); this.firstNameInput = document.getElementById('firstName'); this.ageInput = document.getElementById('age'); this.phoneInput = document.getElementById('phone'); this.filterLastName = document.getElementById('filterLastName'); this.filterFirstName = document.getElementById('filterFirstName'); this.filterAge = document.getElementById('filterAge'); this.filterPhone = document.getElementById('filterPhone'); this.applyFilterBtn = document.getElementById('applyFilterBtn'); this.resetFilterBtn = document.getElementById('resetFilterBtn'); this.contactsTableBody = document.getElementById('contactsTableBody'); this.emptyState = document.getElementById('emptyState'); this.noResultsState = document.getElementById('noResultsState'); this.contactsCount = document.getElementById('contactsCount'); } setupEventListeners() { this.contactForm.addEventListener('submit', (e) => { e.preventDefault(); this.addContact(); }); this.applyFilterBtn.addEventListener('click', () => { this.applyFilters(); }); this.resetFilterBtn.addEventListener('click', () => { this.resetFilters(); }); [this.filterLastName, this.filterFirstName, this.filterAge, this.filterPhone].forEach(input => { input.addEventListener('keypress', (e) => { if (e.key === 'Enter') { this.applyFilters(); } }); }); } addContact() { const contact = { id: Date.now(), lastName: this.lastNameInput.value.trim(), firstName: this.firstNameInput.value.trim(), age: this.ageInput.value ? parseInt(this.ageInput.value) : '', phone: this.phoneInput.value.trim() }; if (!contact.lastName || !contact.firstName || !contact.phone) { this.showNotification('Заполните все обязательные поля!', 'error'); return; } if (contact.age && (contact.age < 0 || contact.age > 150)) { this.showNotification('Возраст должен быть от 0 до 150 лет!', 'error'); return; } this.contacts.unshift(contact); this.saveContacts(); this.applyFilters(); this.contactForm.reset(); this.showNotification('Контакт успешно добавлен!', 'success'); this.lastNameInput.focus(); } deleteContact(contactId) { if (confirm('Вы уверены, что хотите удалить этот контакт?')) { this.contacts = this.contacts.filter(contact => contact.id !== contactId); this.saveContacts(); this.applyFilters(); this.showNotification('Контакт удален!', 'success'); } } applyFilters() { this.currentFilters = { lastName: this.filterLastName.value.toLowerCase().trim(), firstName: this.filterFirstName.value.toLowerCase().trim(), age: this.filterAge.value.toLowerCase().trim(), phone: this.filterPhone.value.toLowerCase().trim() }; this.filteredContacts = this.contacts.filter(contact => { return ( contact.lastName.toLowerCase().includes(this.currentFilters.lastName) && contact.firstName.toLowerCase().includes(this.currentFilters.firstName) && (contact.age === '' || contact.age.toString().includes(this.currentFilters.age)) && contact.phone.toLowerCase().includes(this.currentFilters.phone) ); }); this.renderContacts(); this.updateContactsCount(); if (Object.values(this.currentFilters).some(filter => filter !== '')) { this.showNotification('Фильтры применены!', 'info'); } } resetFilters() { this.filterLastName.value = ''; this.filterFirstName.value = ''; this.filterAge.value = ''; this.filterPhone.value = ''; this.currentFilters = { lastName: '', firstName: '', age: '', phone: '' }; this.filteredContacts = [...this.contacts]; this.renderContacts(); this.updateContactsCount(); this.showNotification('Фильтры сброшены!', 'info'); } renderContacts() { this.contactsTableBody.innerHTML = ''; if (this.filteredContacts.length === 0) { if (this.contacts.length === 0) { this.emptyState.style.display = 'flex'; this.noResultsState.style.display = 'none'; } else { this.emptyState.style.display = 'none'; this.noResultsState.style.display = 'flex'; } return; } this.emptyState.style.display = 'none'; this.noResultsState.style.display = 'none'; this.filteredContacts.forEach(contact => { const row = this.createContactRow(contact); this.contactsTableBody.appendChild(row); }); } createContactRow(contact) { const row = document.createElement('tr'); row.className = 'contact-row'; row.innerHTML = ` <td>${this.escapeHtml(contact.lastName)}</td> <td>${this.escapeHtml(contact.firstName)}</td> <td>${contact.age || '-'}</td> <td>${this.escapeHtml(contact.phone)}</td> <td> <button class="action-btn delete-btn" data-contact-id="${contact.id}"> 🗑️ Удалить </button> </td> `; const deleteBtn = row.querySelector('.delete-btn'); deleteBtn.addEventListener('click', () => { this.deleteContact(contact.id); }); return row; } updateContactsCount() { const total = this.contacts.length; const filtered = this.filteredContacts.length; if (filtered === total) { this.contactsCount.textContent = total; } else { this.contactsCount.textContent = `${filtered} из ${total}`; } } saveContacts() { localStorage.setItem('contacts', JSON.stringify(this.contacts)); } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `notification ${type}`; notification.textContent = message; notification.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 15px 20px; border-radius: 8px; color: white; font-weight: 500; z-index: 1000; animation: slideIn 0.3s ease-out; max-width: 300px; `; if (type === 'success') { notification.style.background = 'linear-gradient(135deg, #00b09b, #96c93d)'; } else if (type === 'error') { notification.style.background = 'linear-gradient(135deg, #ff416c, #ff4b2b)'; } else { notification.style.background = 'linear-gradient(135deg, #3498db, #2980b9)'; } document.body.appendChild(notification); setTimeout(() => { notification.style.animation = 'slideOut 0.3s ease-in'; setTimeout(() => { if (notification.parentNode) { notification.parentNode.removeChild(notification); } }, 300); }, 3000); if (!document.querySelector('#notification-styles')) { const style = document.createElement('style'); style.id = 'notification-styles'; style.textContent = ` @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } `; document.head.appendChild(style); } } } document.addEventListener('DOMContentLoaded', () => { new ContactsManager(); });