Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/test.yml-template
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Test

on:
pull_request:
branches: [ master ]

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x]

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm start & sleep 5 && npm test
- name: Upload tests report(cypress mochaawesome merged HTML report)
if: ${{ always() }}
uses: actions/upload-artifact@v2
with:
name: report
path: reports
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
1. Replace `<your_account>` with your GitHub username in the link
- [DEMO LINK](https://<your_account>.github.io/js_employees_table_DOM/)
- [DEMO LINK](https://Inna-code10.github.io/js_employees_table_DOM/)
2. Follow [this instructions](https://mate-academy.github.io/layout_task-guideline/)
- Run `npm run test` command to test your code;
- Run `npm run test:only -- -n` to run fast test ignoring linter;
Expand Down Expand Up @@ -44,11 +44,11 @@ Start table:
```
- Add qa attributes for each input field:
```
data-qa="name"
data-qa="position"
data-qa="office"
data-qa="age"
data-qa="salary"
data-qa="name"
data-qa="position"
data-qa="office"
data-qa="age"
data-qa="salary"
```
- Select should have 6 options: `Tokyo`, `Singapore`, `London`, `New York`, `Edinburgh`, `San Francisco`.
- Use texts for labels and buttons from the screenshot below.
Expand All @@ -64,7 +64,7 @@ Start table:
- Notification titles and descriptions are up to you.
- Add qa attribute for notification: `data-qa="notification"` and class `error`/`success` depending on the result.

##### Implement editing of table cells by double-clicking on them (optional).
##### Implement editing of table cells by double-clicking on them (optional).
- Double click on the cell of the table, which should remove the text, and append input with `cell-input` class.
- The input value should be replaced by the input text.
- Only one cell can be edited at a time.
Expand Down
9 changes: 5 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
"postinstall": "npm run update",
"test": "npm run lint && npm run test:only"
},
"dependencies": {},
"devDependencies": {
"@linthtml/linthtml": "^0.9.6",
"@mate-academy/eslint-config": "latest",
"@mate-academy/jest-mochawesome-reporter": "^1.0.0",
"@mate-academy/linthtml-config": "latest",
"@mate-academy/scripts": "^1.8.5",
"@mate-academy/scripts": "^2.1.3",
"@mate-academy/stylelint-config": "latest",
"@parcel/transformer-sass": "^2.12.0",
"cypress": "^13.13.0",
Expand Down
143 changes: 142 additions & 1 deletion src/scripts/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,144 @@
'use strict';

// write code here
const table = document.querySelector('table');
const headers = table.querySelectorAll('th');
const tbody = table.querySelector('tbody');

let sortDirection = true;
let currentColumn = null;

headers.forEach((th, index) => {
th.addEventListener('click', () => {
if (currentColumn === index) {
sortDirection = !sortDirection;
} else {
sortDirection = true;
currentColumn = index;
}

const rows = Array.from(tbody.querySelectorAll('tr'));

rows.sort((a, b) => {
let aText = a.children[index].textContent;
let bText = b.children[index].textContent;

if (index === 4) {
aText = Number(aText.replace(/[$,]/g, ''));
bText = Number(bText.replace(/[$,]/g, ''));
}

if (!isNaN(aText)) {
aText = Number(aText);
}

if (!isNaN(bText)) {
bText = Number(bText);
}

if (aText > bText) {
return sortDirection ? 1 : -1;
}

if (aText < bText) {
return sortDirection ? -1 : 1;
}

return 0;
});
tbody.append(...rows);
});
});

tbody.addEventListener('click', (e) => {
const row = e.target.closest('tr');

if (!row) {
return;
}

tbody.querySelectorAll('tr').forEach((tr) => tr.classList.remove('active'));
row.classList.add('active');
});

const form = document.createElement('form');

form.className = 'new-employee-form';

form.innerHTML = `
<label>Name: <input data-qa="name" name="name" type="text"></label>
<label>Position: <input data-qa="position" name="position" type="text"></label>
<label>Office:
<select data-qa="office" name="office">
<option>Tokyo</option>
<option>Singapore</option>
<option>London</option>
<option>New York</option>
<option>Edinburgh</option>
<option>San Francisco</option>
</select>
</label>
<label>Age: <input data-qa="age" name="age" type="number"></label>
<label>Salary: <input data-qa="salary" name="salary" type="number"></label>
<button type="submit">Save to table</button>
`;

document.body.append(form);

function showNotification(message, type) {
const div = document.createElement('div');

div.className = `notification ${type}`;
div.dataset.qa = 'notification';
div.textContent = message;
document.body.append(div);

setTimeout(() => {
div.style.display = 'none';
}, 2000);
}

form.addEventListener('submit', (e) => {
e.preventDefault();

const userName = form.name.value.trim();
const position = form.position.value.trim();
const office = form.office.value;
const age = Number(form.age.value);
const salary = Number(form.salary.value);

if (!userName || !position || !age || !salary) {
showNotification('All fields are required', 'error');

return;
}

if (userName.length < 4) {
showNotification('Name too short', 'error');

return;
}

if (age < 18 || age > 90) {
showNotification('Invalid age', 'error');

return;
}

const formattedSalary = `$${salary.toLocaleString('en-US')}`;

const row = document.createElement('tr');

row.innerHTML = `
<td>${userName}</td>
<td>${position}</td>
<td>${office}</td>
<td>${age}</td>
<td>${formattedSalary}</td>
`;

tbody.append(row);

showNotification('Employee added!', 'success');

form.reset();
});
Loading