parent
9409685c9a
commit
1895abdec6
@ -0,0 +1,3 @@
|
||||
{
|
||||
"liveServer.settings.port": 5501
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Sorted-table</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<script src="script.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="sortableTable"></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,138 @@
|
||||
const data = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'iPhone 9',
|
||||
price: 549,
|
||||
inStock: true,
|
||||
category: 'smartphones',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'iPhone X',
|
||||
price: 899,
|
||||
inStock: true,
|
||||
category: 'smartphones',
|
||||
},
|
||||
{
|
||||
|
||||
id: 3,
|
||||
title: 'Samsung Universe 9',
|
||||
price: 1249,
|
||||
inStock: true,
|
||||
category: 'smartphones',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: 'Huawei P30',
|
||||
price: 499,
|
||||
inStock: false,
|
||||
category: 'smartphones',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: 'OPPOF19',
|
||||
price: 280,
|
||||
inStock: false,
|
||||
category: 'smartphones',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: 'MacBook Pro',
|
||||
price: 1749,
|
||||
inStock: true,
|
||||
category: 'laptops',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
title: 'Samsung Galaxy Book',
|
||||
price: 1499,
|
||||
inStock: false,
|
||||
category: 'laptops'
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
title: 'Microsoft Surface Laptop 4',
|
||||
price: 1499,
|
||||
inStock: false,
|
||||
category: 'laptops',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
title: 'HP Pavilion 15-DK1056WM',
|
||||
price: 1099,
|
||||
inStock: true,
|
||||
category: 'laptops',
|
||||
},
|
||||
{
|
||||
|
||||
id: 10,
|
||||
title: 'Infinix INBOOK',
|
||||
price: 1099,
|
||||
inStock: true,
|
||||
category: 'laptops',
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
const createTable = productData => {
|
||||
const tableElem = document.createElement('table');
|
||||
const tableHead = document.createElement('thead');
|
||||
const tableBody = document.createElement('tbody');
|
||||
|
||||
const headers = Object.keys(productData[0]);
|
||||
tableHead.appendChild(createHeaderRow(headers));
|
||||
|
||||
productData.forEach(rowData => {
|
||||
tableBody.appendChild(createProductRow(rowData));
|
||||
})
|
||||
|
||||
tableElem.appendChild(tableHead);
|
||||
tableElem.appendChild(tableBody);
|
||||
|
||||
return tableElem;
|
||||
}
|
||||
|
||||
const createHeaderRow = columnNames => {
|
||||
const tr = document.createElement('tr');
|
||||
columnNames.forEach(columnName => {
|
||||
const th = document.createElement('th');
|
||||
th.textContent = columnName[0].toUpperCase() + columnName.slice(1);
|
||||
const searchUp = document.createElement('span');
|
||||
searchUp.textContent = '🔼';
|
||||
const searchDown = document.createElement('span');
|
||||
searchDown.textContent = '🔽';
|
||||
|
||||
searchUp.onclick = () => sortDataBy(columnName, 'ASC');
|
||||
searchDown.onclick = () => sortDataBy(columnName, 'DESC');
|
||||
|
||||
th.appendChild(searchDown);
|
||||
th.appendChild(searchUp);
|
||||
tr.appendChild(th);
|
||||
})
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
const createProductRow = product => {
|
||||
const tr = document.createElement('tr');
|
||||
Object.values(product).forEach(value => {
|
||||
const td = document.createElement('td');
|
||||
td.textContent = value;
|
||||
tr.appendChild(td);
|
||||
});
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
const sortDataBy = (columnName, direction) => {
|
||||
const sortedASCData = [...data.sort((a, b) => a[columnName] > b[columnName] ? 1 : -1)];
|
||||
const sortedDESCData = [...data.sort((a, b) => a[columnName] < b[columnName] ? 1 : -1)];
|
||||
renderTable(direction === 'ASC' ? sortedASCData : sortedDESCData);
|
||||
};
|
||||
|
||||
const renderTable = productData => {
|
||||
const sortableTableElement = document.getElementById('sortableTable');
|
||||
sortableTableElement.innerHTML = '';
|
||||
sortableTableElement.appendChild(createTable(productData));
|
||||
};
|
||||
renderTable(data);
|
@ -0,0 +1,12 @@
|
||||
body{
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
|
||||
}
|
||||
table, th{
|
||||
text-align: left;
|
||||
border: 1px solid black;
|
||||
}
|
||||
th>span{
|
||||
margin: 2.5rem;
|
||||
cursor: pointer;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<script src="script.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="ratings"></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,67 @@
|
||||
const initialQuestions = [
|
||||
{
|
||||
label: 'Friendliness',
|
||||
rating: 0,
|
||||
},
|
||||
{
|
||||
label: 'Cleanliness',
|
||||
rating: 0,
|
||||
},
|
||||
{
|
||||
label: 'Food',
|
||||
rating: 0,
|
||||
},
|
||||
{
|
||||
label: 'Service',
|
||||
rating: 0,
|
||||
},
|
||||
];
|
||||
|
||||
const storedQuestions = JSON.parse(localStorage.getItem('storedQuestions'));
|
||||
|
||||
const questions = storedQuestions || initialQuestions;
|
||||
|
||||
const makeStarRating = question => {
|
||||
const container = document.createElement('div');
|
||||
const label = document.createElement('label');
|
||||
label.textContent = question.label;
|
||||
container.appendChild(label);
|
||||
container.appendChild(makeStars(5, question));
|
||||
|
||||
return container;
|
||||
};
|
||||
|
||||
const makeStars = (maxValue, question) => {
|
||||
const starContainer = document.createElement('div');
|
||||
|
||||
for (let starPosition = 1; starPosition <= maxValue; starPosition++) {
|
||||
const starElement = document.createElement('span');
|
||||
starContainer.appendChild(starElement);
|
||||
if (starPosition <= question.rating) {
|
||||
starElement.classList.add('filled');
|
||||
} else {
|
||||
starElement.classList.add('empty');
|
||||
}
|
||||
|
||||
starElement.onclick = () => {
|
||||
for (let i = 0; i < maxValue; i++) {
|
||||
if (i < starPosition) {
|
||||
starContainer.children[i].classList.add('filled');
|
||||
} else {
|
||||
starContainer.children[i].classList.remove('filled');
|
||||
starContainer.children[i].classList.add('empty');
|
||||
}
|
||||
}
|
||||
question.rating = starPosition;
|
||||
localStorage.setItem('storedQuestions', JSON.stringify(questions));
|
||||
}
|
||||
}
|
||||
|
||||
return starContainer;
|
||||
}
|
||||
|
||||
const ratingsElement = document.getElementById('ratings');
|
||||
|
||||
questions.forEach(question => {
|
||||
ratingsElement.appendChild(makeStarRating(question))
|
||||
});
|
@ -0,0 +1,24 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#ratings {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
border: 2px solid black;
|
||||
padding: 1rem;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.empty::before {
|
||||
content: '☆';
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.filled::before {
|
||||
content: '★';
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ☆★ */
|
Loading…
Reference in new issue