i'm building a dynamic table which i also need to sort, and the arrows to go accordingly with the values (ascending or descending if the sort is happening) if the values are ascending the arrow will always be up, if the values are descending the arrow is down, but also to toggle when clicking the same th and when clicking on another element the arrow should be accordingly with the sorting status. i've tried something here, but it's not working as it should.
many thanks in advance if you guys can help me with that
https://jsfiddle.net/947xkevd/
const API = 'https://raw.githubusercontent.com/alex-cenusa/movies/master/movies.json';
async function getData() {
try {
let response = await fetch(API);
if (response.status == 200) {
let data = await response.json();
return data;
} else {
throw new Error(response.status);
}
} catch (error) {
console.log(error);
}
}
getData().then((data) => {
const KEY = data.data.key.forEach((key) => {
const LEGEND_WRAPPER = document.querySelector('.color-code-wrapper');
const UNIT_TYPE = key.type;
const KEY_BTN = document.createElement('button');
KEY_BTN.innerText = UNIT_TYPE;
const KEY_BTN_COLOR = key.color;
KEY_BTN.style.backgroundColor = KEY_BTN_COLOR;
LEGEND_WRAPPER.appendChild(KEY_BTN);
});
const TABLE_WRAPPER = document.querySelector('.table-wrapper');
let col = [];
for (let i = 0; i < data.data.movies.length; i++) {
for (let key in data.data.movies[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
let button_style = {
"Comedy": "blue-button",
"Thriller": "pink-button",
"Alternative": "green-button",
"Documentary": "red-button"
}
function mergeObjectValues(key, obj, tablecell) {
let merge_string = [];
let button;
for (let i = 0; i < obj.length; i++) {
if (merge_string.indexOf(obj[i][key]) == -1) {
merge_string.push(obj[i][key]);
if (key == 'type') {
button = document.createElement('button');
button.classList.add(button_style[obj[i][key]]);
button.innerHTML = obj[i][key];
tablecell.append(button);
} else {
merge_string.push(obj[i][key]);
tablecell.innerHTML = obj[i][key];
}
}
}
return tablecell;
}
const table = document.createElement('table');
let tr = table.insertRow(-1); // table row.
for (let i = 0; i < col.length; i++) {
let th = document.createElement('th'); // table header.
th.setAttribute('class', 'sort-cta');
th.innerHTML = col[i];
tr.appendChild(th);
const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent;
const comparer = (idx, asc) => (a, b) =>
((v1, v2) => (v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2)))(
getCellValue(asc ? a : b, idx),
getCellValue(asc ? b : a, idx)
);
th.addEventListener('click', () => {
sort();
});
function sort() {
const table = th.closest('table');
Array.from(table.querySelectorAll('tr:nth-child(n+2)'))
.sort(comparer(Array.from(th.parentNode.children).indexOf(th), (this.asc = !this.asc)))
.forEach((tr) => table.appendChild(tr));
}
}
let col_key = {
"Type/Use": "type",
"Rental": "name"
}
for (let i = 0; i < data.data.movies.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
let tabCell = tr.insertCell(-1);
var tablecontent = data.data.movies[i][col[j]];
// console.log(col);
// console.log(tablecontent instanceof Array);
if (tablecontent instanceof Array) {
tabCell = mergeObjectValues(col_key[col[j]], tablecontent, tabCell);
} else {
tabCell.innerHTML = tablecontent;
}
}
}
TABLE_WRAPPER.appendChild(table);
const sorLnk = document.querySelectorAll('.sort-cta');
sorLnk.forEach((item) => {
item.addEventListener('click', () => {
[...item.parentElement.children].forEach((sib) => {
sib.classList.remove('down');
item.classList.add('down');
});
});
});
});
.color-code-wrapper {
display: flex;
justify-content: space-around;
align-items: center;
max-width: 400px;
}
.title {
font-weight: 600;
}
button {
border: none;
border-radius: 30px;
padding: 4px 10px;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
color: #fff;
font-weight: 600;
}
table {
width: 100%;
margin: 32px 0;
}
tr {
text-align: left;
border-bottom: 1px solid #dddddd;
}
tr:first-of-type {
border-bottom: 1px solid #333;
}
th {
padding: 8px 0;
}
td {
padding: 8px 0;
font-size: 1.4rem;
}
.blue-button {
background-color: rgb(64, 0, 255);
}
.pink-button {
background-color: rgb(255, 0, 191);
}
.red-button {
background-color: rgb(255, 0, 0);
}
.green-button {
background-color: rgb(0, 255, 64);
}
.sort-cta {
cursor: pointer;
border: none;
text-transform: capitalize;
background-color: transparent;
}
.sort-cta:after {
content: '\25b2';
margin: 0 4px;
font-size: 12px;
}
.sort-cta.down:after {
content: '\25BC';
}
}
<div class="available-movies-component">
<div class="color-code-wrapper">
<span class="title">Key</span>
</div>
<div class="table-wrapper">
</div>
</div>