Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort the table and re-generate it with help of pure JavaScript

I need to sort the table by name. For sorting, I use the function

function sortArray(index) {
  let arr = [];
  rows.forEach( elem => {
    arr.push(elem.children[index].textContent); 
  })
  let sort = arr.sort( (a, b) => {
    if ( a > b) {
      return 1;
    }
    if (a < b) {
      return -1;
    }
    return 0;
  });
  console.log(sort);
  return sort;
  }

but I don't know how to redraw the table. Table I create from JSON file dynamically. In order to start sorting, you need to click on the name of the field and then the already sorted table should be displayed.

const buildHeader = data =>
  Object.keys(data)
    .map(k => `<th>${k}</th>`)
    .join("");
const buildRow = data =>
  Object.keys(data)
    .map(k => `<td>${data[k]}</td>`)
    .join("");
let element = document.querySelector(".people");

function showPeople(people) {
  let table = document.createElement("table");
  table.classList.add("people__table");
  let thead = document.createElement("thead");
  thead.innerHTML = `<tr class="head">${buildHeader(people[0])}</tr>`;
  table.appendChild(thead);
  let tbody = document.createElement("tbody");
  tbody.innerHTML = people
    .map(p => `<tr class="person">${buildRow(p)}</tr>`)
    .join("");
  table.appendChild(tbody);
  element.appendChild(table);
}

const customPeople = data =>
  data.map((p, i) => {
    return {
      name: p.name,
      sex: p.sex,
      born: p.born,
      died: p.died,
      age: p.died - p.born,
      mother: p.mother,
      father: p.father,
    };
  });

showPeople(customPeople(ANCESTRY_FILE));
like image 481
Олександр Семенюк Avatar asked Dec 29 '25 11:12

Олександр Семенюк


1 Answers

Something like this sortTable function would do the job:

function sortTable(tbody, index, ascending) {
    Array.prototype.slice.call(tbody.children).sort(
        (tr1, tr2) => tr1.children[index].textContent.localeCompare(tr2.children[index].textContent) * (ascending ? 1 : -1)
        ).forEach(tr => tbody.appendChild(tr));
    }

// demonstration
(function(){
    const thead_tr = document.getElementById('thdtr');
    const tbody = document.getElementById('tbd');
        
    function makeCell() {
        const td = document.createElement('td');
        td.appendChild(document.createTextNode(Math.round(Math.random() * 999999999).toString(36)));
        return td;
        }

    function makeRow() {
        const tr = document.createElement('tr');
        for(let i = 0; i < thead_tr.children.length; i++) tr.appendChild(makeCell());
        return tr;
        }
    
    // adds click-to-sort functionality
    Array.prototype.forEach.call(thead_tr.children, (th, index) => {
        let asc_toggle = false; // false will start off in ascending order
        th.addEventListener('click', event => sortTable(tbody, index, asc_toggle = !asc_toggle));
        });
    
    // fills the table with random alphanumeric data
    for(let i = 0; i < 100; i++) tbody.appendChild(makeRow());
    }());
<table>
    <thead>
        <tr id="thdtr">
            <th>col 1</th>
            <th>col 2</th>
            <th>col 3</th>
        </tr>
    </thead>
    <tbody id="tbd">
    </tbody>
<table>

My sortTable function is a generic in-place table sorting function that should work on any table. It accepts 3 parameters:

  1. tbody - DOMElement - A reference to either the tbody element or the table element itself, whichever contains the tr (row) elements.
  2. index - Number - The index of the column to sort by (starts at 0).
  3. ascending - Boolean - Whether the order is ascending (true) or descending (false)

Example usage for use with your current code:

sortTable(document.querySelector('.people__table tbody'), 0, true);

like image 197
Jonathan Gray Avatar answered Dec 30 '25 23:12

Jonathan Gray