Skip to content
Advertisement

JS Sort Table – Sort Indicators

I’ve built this table with a sort function and now I’m also trying to set a class for the selected th so I can put some arrows with CSS, as sort indicators.

I need a way to set dynamic .asc and .desc classes to my selected th with JS somewhere on my sortTable() .. It also needs to be Pure JS.

var myData, asc = {'userId':true, 'id':true, 'title':true, 'completed':true};
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://jsonplaceholder.typicode.com/todos');
myRequest.onload = function () {
  myData = JSON.parse(myRequest.responseText);
  dataTable(myData);
};
myRequest.send();

function dataTable(data) {
  if (data.length > 0) {
    var temp = '';
    data.forEach((u) => {
      temp += '<tr>';
      temp += "<td style='text-align: center'>" + u.userId + '</td>';
      temp += "<td style='text-align: center'>" + u.id + '</td>';
      temp += '<td>' + u.title + '</td>';
      temp += "<td style='text-align: center'>" + u.completed + '</td>';
      temp += "<td>" + '<input type="button" value="Delete" onclick="deleteRow(this)"> <input type="button" value="Edit" onclick="insertToForm(this)">' + '</td></tr>';
      document.getElementById('data').innerHTML = temp;
    });
  } 
}
function sortTable(col){
    myData.sort(function(a, b) {
        if(asc[col]){
            return a[col] > b[col]? 1:-1;
        }
        else{
            return a[col] > b[col]? -1:1;;
        }
    });
    asc[col] = !asc[col];
    document.getElementById('data').innerHTML = '';
    dataTable(myData);
}
.container{
    display: flex;
    margin: 25px 10px;
}
.my-table {
    border-collapse: collapse;
    font-size: 0.9em;
    font-family: sans-serif;
    min-width: 400px;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
    margin-right: 15px;
}
.my-table td, th {
    padding: 12px 15px;
}
.my-table thead {
    background-color: #009879;
    color: #ffffff;
    text-align: left;
}
.my-table th {
    background-color: #009879;
    color: #ffffff;
    text-align: left;
    cursor: pointer;
}
.my-table tbody tr {
    border-bottom: 1px solid #dddddd;
}
tbody tr input {
    width: 50px;
}
.my-table tbody tr:nth-of-type(even) {
    background-color: #f3f3f3;
}
.my-table tbody tr:last-of-type {
    border-bottom: 2px solid #009879;
}
<table id="table" class="my-table">
   <thead>
       <tr>
           <th id="tbl-head-userid" onclick="sortTable('userId');">UserID</th>
           <th id="tbl-head-id" onclick="sortTable('id');">ID</th>
           <th id="tbl-head-title" onclick="sortTable('title');">Title</th>
           <th id="tbl-head-completed" onclick="sortTable('completed');">Completion</th>
           <th>Action</th>
       </tr>
   </thead>
   <tbody id="data">
                    
   </tbody>
</table>

Advertisement

Answer

I have edited the snipped. arrow buttons will be shown when the <th> is clicked and the icons on the other headers will be removed

var myData, asc = {'userId':true, 'id':true, 'title':true, 'completed':true};
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://jsonplaceholder.typicode.com/todos');
myRequest.onload = function () {
  myData = JSON.parse(myRequest.responseText);
  dataTable(myData);
};
myRequest.send();

function dataTable(data) {
  if (data.length > 0) {
    var temp = '';
    data.forEach((u) => {
      temp += '<tr>';
      temp += "<td style='text-align: center'>" + u.userId + '</td>';
      temp += "<td style='text-align: center'>" + u.id + '</td>';
      temp += '<td>' + u.title + '</td>';
      temp += "<td style='text-align: center'>" + u.completed + '</td>';
      temp += "<td>" + '<input type="button" value="Delete" onclick="deleteRow(this)"> <input type="button" value="Edit" onclick="insertToForm(this)">' + '</td></tr>';
      document.getElementById('data').innerHTML = temp;
    });
  } 
}
function sortTable(col, e){
    myData.sort(function(a, b) {
        if(asc[col]){
            return a[col] > b[col]? 1:-1;
        }
        else{
            return a[col] > b[col]? -1:1;;
        }
    });
    asc[col] = !asc[col];
    document.getElementById('data').innerHTML = '';
    dataTable(myData);
    var currentTarget = e.currentTarget;
   
  Array.from(currentTarget.parentElement.children).forEach(function(ele) {

    ele.classList.remove('asc', 'des');
    })

    if(!asc[col]) {
        currentTarget.classList.add('asc');
    } else {
      currentTarget.classList.add('des');
    }
}
.container{
    display: flex;
    margin: 25px 10px;
}
.my-table {
    border-collapse: collapse;
    font-size: 0.9em;
    font-family: sans-serif;
    min-width: 400px;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
    margin-right: 15px;
}
.my-table td, th {
    padding: 12px 15px;
}
.my-table thead {
    background-color: #009879;
    color: #ffffff;
    text-align: left;
}
.my-table th {
    background-color: #009879;
    color: #ffffff;
    text-align: left;
    cursor: pointer;
}
.my-table tbody tr {
    border-bottom: 1px solid #dddddd;
}
tbody tr input {
    width: 50px;
}
.my-table tbody tr:nth-of-type(even) {
    background-color: #f3f3f3;
}
.my-table tbody tr:last-of-type {
    border-bottom: 2px solid #009879;
}
th {
  position: relative;
}
th.asc:before,
th.des:after {
    border: 4px solid transparent;
    content: "";
    display: block;
    height: 0;
    right: 5px;
    top: 50%;
    position: absolute;
    width: 0;
}

th.asc:before {
    border-bottom-color: #fff;
    margin-top: -5px;
}
th.des:after {
    border-top-color: #ffff;
}
<table id="table" class="my-table">
   <thead>
       <tr>
           <th id="tbl-head-userid" onclick="sortTable('userId', event);">UserID</th>
           <th id="tbl-head-id" onclick="sortTable('id', event);">ID</th>
           <th id="tbl-head-title" onclick="sortTable('title', event);">Title</th>
           <th id="tbl-head-completed" onclick="sortTable('completed', event);">Completion</th>
           <th>Action</th>
       </tr>
   </thead>
   <tbody id="data">
                    
   </tbody>
</table>
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement