From 83764df30ebf0edd1bbb285c5324ac9f1078b371 Mon Sep 17 00:00:00 2001 From: Olena Sobolieva Date: Mon, 4 May 2026 14:43:28 +0300 Subject: [PATCH 1/2] solutrion --- src/scripts/main.js | 209 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) diff --git a/src/scripts/main.js b/src/scripts/main.js index a765fdb1d..a06b31340 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1,3 +1,212 @@ 'use strict'; // write code here +const table = document.querySelector('table'); +const formInputs = [ + { + label: 'Name', + name: 'name', + type: 'text', + qa: 'name', + }, + { + label: 'Position', + name: 'position', + type: 'text', + qa: 'position', + }, + { + label: 'Office', + name: 'office', + type: 'select', + qa: 'office', + options: [ + 'Tokyo', + 'Singapore', + 'London', + 'New York', + 'Edinburgh', + 'San Francisco', + ], + }, + { + label: 'Age', + name: 'age', + type: 'number', + qa: 'age', + }, + { + label: 'Salary', + name: 'salary', + type: 'number', + qa: 'salary', + }, +]; + +const form = document.createElement('form'); + +form.noValidate = true; +form.setAttribute('novalidate', ''); + +form.noValidate = true; +form.setAttribute('novalidate', ''); +form.classList.add('new-employee-form'); + +formInputs.forEach((field) => { + const label = document.createElement('label'); + + label.textContent = `${field.label}:`; + + let element; + + if (field.type === 'select') { + element = document.createElement('select'); + + field.options.forEach((optionText) => { + const option = document.createElement('option'); + + option.textContent = optionText; + option.value = optionText; + element.append(option); + }); + } else { + element = document.createElement('input'); + element.type = field.type; + } + element.name = field.name; + element.dataset.qa = field.qa; + element.required = true; + element.autocomplete = 'off'; + label.append(element); + form.append(label); +}); + +const btn = document.createElement('button'); + +btn.textContent = 'Save to table'; +btn.type = 'submit'; +form.append(btn); +document.body.append(form); + +form.addEventListener('submit', (e) => { + e.preventDefault(); + + const formData = new FormData(form); + const employee = Object.fromEntries(formData.entries()); + + validateData(employee); +}); + +function validateData(obj) { + const notification = document.createElement('div'); + + notification.classList.add('notification'); + notification.dataset.qa = 'notification'; + + const isAnyEmpty = Object.values(obj).some((value) => value.trim() === ''); + let errorMsg = ''; + + if (isAnyEmpty) { + errorMsg = 'All fields are required'; + notification.classList.add('error'); + } + + const trimmedName = obj.name.trim(); + const trimmedPosition = obj.position.trim(); + + if (trimmedName.length < 4) { + notification.classList.add('error'); + errorMsg = 'Name must be at least 4 characters long'; + form.querySelector('[name="name"]').focus(); + } else if (trimmedPosition.length < 5) { + notification.classList.add('error'); + errorMsg = 'Position must be at least 5 characters long'; + form.querySelector('[name="position"]').focus(); + } else if (+obj.age < 18 || +obj.age > 90) { + notification.classList.add('error'); + errorMsg = 'Age must be between 18 and 90'; + form.querySelector('[name="age"]').focus(); + } + + if (notification.classList.contains('error')) { + notification.innerHTML = ` +

Error

+

${errorMsg}

+ `; + document.body.append(notification); + } else { + const newRow = document.createElement('tr'); + + newRow.innerHTML = ` + ${obj.name.slice(0, 1).toUpperCase()}${obj.name.slice(1)} + ${obj.position.slice(0, 1).toUpperCase()}${obj.position.slice(1)} + ${obj.office} + ${+obj.age} + $${Number(obj.salary).toLocaleString('en-US')} + `; + table.querySelector('tbody').append(newRow); + notification.classList.add('success'); + + notification.innerHTML = ` +

Success

+

Employee added successfully!

+ `; + document.body.append(notification); + form.reset(); + } + setTimeout(() => notification.remove(), 3000); +} + +table.addEventListener('click', (e) => { + const row = e.target.closest('tr'); + + if (!row || !table.tBodies[0].contains(row)) { + return; + } + + const prev = table.querySelector('.active'); + + if (prev) { + prev.classList.remove('active'); + } + + row.classList.add('active'); +}); + +const headers = [...table.querySelectorAll('thead th')]; + +headers.forEach((th, index) => { + th.addEventListener('click', () => { + const currentOrder = th.dataset.order; + const newOrder = currentOrder === 'asc' ? 'desc' : 'asc'; + + headers.forEach((h) => { + if (h !== th) { + delete h.dataset.order; + } + }); + + th.dataset.order = newOrder; + + const tbody = table.tBodies[0]; + const rows = [...tbody.rows]; + + rows.sort((a, b) => { + const aText = a.cells[index].textContent.trim(); + const bText = b.cells[index].textContent.trim(); + + const aNum = Number(aText.replace(/[$,]/g, '')); + const bNum = Number(bText.replace(/[$,]/g, '')); + + if (!Number.isNaN(aNum) && !Number.isNaN(bNum)) { + return newOrder === 'asc' ? aNum - bNum : bNum - aNum; + } + + return newOrder === 'asc' + ? aText.localeCompare(bText) + : bText.localeCompare(aText); + }); + + rows.forEach((row) => tbody.appendChild(row)); + }); +}); From 9f5bb383b52b61f595d143ce28ecc2b9c7620c99 Mon Sep 17 00:00:00 2001 From: Olena Sobolieva Date: Mon, 4 May 2026 14:58:12 +0300 Subject: [PATCH 2/2] new solution --- src/scripts/main.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/scripts/main.js b/src/scripts/main.js index a06b31340..7b04cb0c7 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1,6 +1,5 @@ 'use strict'; -// write code here const table = document.querySelector('table'); const formInputs = [ { @@ -45,9 +44,6 @@ const formInputs = [ const form = document.createElement('form'); -form.noValidate = true; -form.setAttribute('novalidate', ''); - form.noValidate = true; form.setAttribute('novalidate', ''); form.classList.add('new-employee-form'); @@ -112,16 +108,11 @@ function validateData(obj) { } const trimmedName = obj.name.trim(); - const trimmedPosition = obj.position.trim(); if (trimmedName.length < 4) { notification.classList.add('error'); errorMsg = 'Name must be at least 4 characters long'; form.querySelector('[name="name"]').focus(); - } else if (trimmedPosition.length < 5) { - notification.classList.add('error'); - errorMsg = 'Position must be at least 5 characters long'; - form.querySelector('[name="position"]').focus(); } else if (+obj.age < 18 || +obj.age > 90) { notification.classList.add('error'); errorMsg = 'Age must be between 18 and 90';