My class sorts a table alphabetically by the name of the name of the employees and also by the time worked. The problem that I have is that I can make it to “unsort” the table (sort it to the original state) after clicking the name or worked time headings. I thought it would be simple but no I can’t figure it out.
Sorry if it is bad code. I am learning and I basically wrote the class without knowing too much JS.
Thank you!
export { SortingTable };
class SortingTable {
#data = null;
#sortedData = null;
#sortedTimeData = null;
#originalData = null;
constructor(table, selector) {
this.table = table;
this.selector = selector;
}
#getBodyData() {
const body = this.table;
const rows = body.getElementsByTagName('tr');
const data = [];
const originalData = [];
for (let i = 0; i < rows.length; i++) {
data.push(rows[i]); // Push the actual row
originalData.push(rows[i].cloneNode(true)); // Push a deep copy of the row
}
this.data = data;
this.originalData = originalData;
}
#removeBody(){
const body = this.table.getElementsByTagName('tbody')[0]
while (body.childElementCount){
body.removeChild(body.firstElementChild)
}
}
#sortAlphaData() {
this.data.sort((a, b) => {
const elementA = a.querySelector(this.selector);
const elementB = b.querySelector(this.selector);
const nameA = elementA ? elementA.innerText : '';
const nameB = elementB ? elementB.innerText : '';
return nameA.localeCompare(nameB);
});
this.sortedData = this.data;
}
#sortTimeData(){
const data = this.data
const seconds = []
const newData = []
for (let i = 0; i < data.length; i++){
let wholeTime = data[i].querySelector('#workedTime')?.innerText ?? '';
// console.log(wholeTime)
const splitTime = wholeTime.split(':')
const totalSeconds = (parseFloat(splitTime[0]) * 3600) +
(parseFloat(splitTime[1]) * 60) +
(parseFloat(splitTime[2]))
seconds.push(totalSeconds)
const objectData = {
totalSeconds: totalSeconds,
originalData: data[i]
}
newData.push(objectData)
}
newData.sort((a, b) => a.totalSeconds - b.totalSeconds)
this.sortedTimeData = newData
}
#rebuildAlphaBody() {
const body = this.table.getElementsByTagName('tbody')[0];
const data = this.sortedData;
// Append the sorted rows directly to the body
for (let i = 0; i < data.length; i++) {
body.appendChild(data[i]); // Reuse the original row elements
}
}
#rebuildOriginalBody() {
const body = this.table.getElementsByTagName('tbody')[0];
const data = this.originalData;
// Append the sorted rows directly to the body
for (let i = 0; i < data.length; i++) {
body.appendChild(data[i]); // Reuse the original row elements
}
}
#rebuildTimeBody(){
const data = this.sortedTimeData
const body = this.table.getElementsByTagName('tbody')[0]
for (let i = 0; i < data.length; i++){
body.appendChild(data[i]['originalData'])
}
}
sortAlpha(){
this.#getBodyData()
this.#sortAlphaData()
this.#removeBody()
this.#rebuildAlphaBody()
}
sortTime(){
this.#getBodyData()
this.#sortTimeData()
this.#removeBody()
this.#rebuildTimeBody()
}
unsort() {
console.log("Original Data:", this.originalData);
if (!this.originalData) {
console.error("Error: originalData is not initialized. Call a sorting method first.");
return;
}
this.#removeBody();
this.#rebuildOriginalBody();
}
}
I tried to create a deep copy of the original data so when the this.data was sorted it wouldn’t affect the original data but this console.log(“Original Data:”, this.originalData); is prints undefined.
I am not sure what to do after this.
Thank you