Newbie here how can I sort all of the following table row attach an onclick listener on the header after it is displayed.
ID | Name | Inventory Volume |
---|---|---|
1 | Rachel | Data is not enough |
2 | Ross | 100 |
3 | Monica | 1 |
4 | Connor | Data is not enough |
5 | Dustin | -5 |
into this sorting example is in descending, the words should be the last.
ID | Name | Inventory Volume |
---|---|---|
2 | Ross | 100 |
3 | Monica | 10 |
5 | Dustin | -5 |
1 | Rachel | Data is not enough |
4 | Connor | Data is not enough |
But I also want the other columns to be sorted as well and the other columns to have the function to sort as well.
Tried this solution but only works for the column. https://jsfiddle.net/7wnke5q2/
function sortData(data, method) {
let lessData = 'Data Not Enough'
let lastItems = []
let sortedList;
if (method == 'descending') {
sortedList = data.sort((a, b) => {
return a - b
})
} else if (method == 'ascending') {
sortedList = data.sort((a, b) => {
return b - a
})
}
for (let i = 0; i < sortedList.length; i++) {
if (sortedList[i] == lessData) {
let item = sortedList[i]
sortedList.splice(i, 1)
sortedList.push(item)
}
}
sortedList = sortedList.concat(lastItems)
return sortedList
}
Could you please help me out. Thanks in advance!
If i understand, you need all "Data Not Enough" at the end. So, it can works:
function sortData(data, method) {
let lessData = 'Data Not Enough'
let sortedList;
sortedList = data.sort((a, b) => {
if(a=='Data Not Enough')
return 1
if(b=='Data Not Enough')
return -1
return method=='ascending'?a-b:b-a
})
return sortedList
}
something like that ?
just click on header columns to sort the table
const myTableHead = document.querySelector('#my-table thead') , myTableHead_TH = document.querySelectorAll('#my-table thead th') , myTableBody = document.querySelector('#my-table tbody') , myTableBody_TR = [...document.querySelectorAll('#my-table tbody tr')] , sortOrder = ['','asc','desc'] , isDNE = str => str.trim() === 'Data is not enough' ; myTableHead.onclick = ({target}) => { if (!target.matches('th')) return let idx = (sortOrder.findIndex(x=>x===target.className) +1) %3 myTableHead_TH.forEach(th=>th.className='') target.className = sortOrder[idx] if ( sortOrder[idx] ) { myTableBody_TR .sort(dynaSort(target.cellIndex, target.dataset.type, sortOrder[idx] )) .forEach(tr=>myTableBody.appendChild(tr) ) } } function dynaSort( colIndex, colType, order='asc' ) { let sortOrder = (order === 'desc') ? -1 : 1 return function(row_a,row_b) { let a = row_a.cells[colIndex].textContent , b = row_b.cells[colIndex].textContent ; if (isDNE(a) && isDNE(b)) return 0 if (isDNE(a)) return +1 if (isDNE(b)) return -1 if (colType==='str') return (a.trim().localeCompare(b.trim())) *sortOrder return (Number(a) - Number(b)) *sortOrder } }
table { border-collapse : collapse; margin : 2em 1em; font-family: Arial, Helvetica, sans-serif; } td,th { padding : .2em .8em; border : 1px solid darkblue; } th::after { display : block; float : inline-end; content : '\\25B7'; margin : 0 0 0 1em; transition : 180ms; color : transparent; } th.asc::after { transform : rotate(-90deg); color : whitesmoke; } th.desc::after { transform : rotate(+90deg); color : whitesmoke; } thead { background : #437c97; color : whitesmoke; cursor : pointer; }
<table id="my-table" > <thead> <tr> <th data-type="num">ID</th> <th data-type="str">Name</th> <th data-type="num">Inventory Volume</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Rachel</td> <td>Data is not enough</td> </tr> <tr> <td>2</td> <td>Ross</td> <td> 100 </td> </tr> <tr> <td>3</td> <td>Monica</td> <td> 1 </td> </tr> <tr> <td>4</td> <td>Connor</td> <td>Data is not enough</td> </tr> <tr> <td>5</td> <td>Dustin</td> <td> -5 </td> </tr> </tbody> </table>
function sort(e, method) {
//Get table
while ((e = e.parentElement) && !e.classList.contains("table"));
//Get rows
let rows = Array.from(e.getElementsByTagName("tr"));
//Get each value for each row
let values = rows.map(row => {
let tds = Array.from(row.getElementsByTagName("td"));
return tds.map(td => td.innerHTML);
});
/*
values is a 2D array which contains each row and column
values = [
[Name, Volume], --> The headers need to be removed
[Joey, Data Not Enough],
[Ross, -5],
[Monica, 1],
[Ben, 100],
[Chandler, Data Not Enough]
];
*/
values.shift(); //remove headers
// Now we need to sort the array by volume
values.sort((a, b) => {
var exception = "Data Not Enough";
if(a[1] == exception)
return 1;
if(b[1] == exception)
return -1;
return method == 'ascending' ? a[1] - b[1] : b[1] - a[1];
});
/******* Put sort values on table *************/
// Get body
let body = e.getElementsByTagName("tbody")[0];
// Erase Body
body.innerHTML = "";
// Iterate each row
values.forEach(row => {
// Create new row element
let tr = document.createElement("tr");
// Iterate each column
row.forEach(val => {
// Create new value
let td = document.createElement("td");
// Append values
td.append(val);
tr.append(td);
});
// Append row to body
body.append(tr);
});
}
Here it is a snippet to try the complete code , I added a <tbody>
to the table.
function sort(e, method) { while ((e = e.parentElement) && !e.classList.contains("table")); let rows = Array.from(e.getElementsByTagName("tr")); let values = rows.map(row => { let tds = Array.from(row.getElementsByTagName("td")); return tds.map(td => td.innerHTML); }); values.shift(); values.sort((a, b) => { var exception = "Data Not Enough"; if(a[1] == exception) return 1; if(b[1] == exception) return -1; return method == 'ascending' ? a[1] - b[1] : b[1] - a[1]; }); let body = e.getElementsByTagName("tbody")[0]; body.innerHTML = ""; values.forEach(row => { let tr = document.createElement("tr"); row.forEach(val => { let td = document.createElement("td"); td.append(val); tr.append(td); }); body.append(tr); }); }
.clickable { cursor: pointer; } .clickable:hover { opacity: 0.7; }
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <table class="table"> <thead> <tr> <th scope="col">Name</th> <th scope="col" class="clickable" onclick='sort(this, "descending")'>Volume</th> </tr> </thead> <tbody> <tr> <td>Joey</td> <td>Data Not Enough</td> </tr> <tr> <td>Ross</td> <td>-5</td> </tr> <tr> <td>Monica</td> <td>1</td> </tr> <tr> <td>Ben</td> <td>100</td> </tr> <tr> <td>Chandler</td> <td>Data Not Enough</td> </tr> </tbody> </table>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.