Home > database >  Sorting a dynamic table in Javascript
Sorting a dynamic table in Javascript

Time:10-30

I'm receiving an array of objects in form of a json file, and using ajax to display certain key-value pairs in a table. My next step is to sort the rendered table, but I'm unsure of how to proceed.

<div id="data-table">
    <table id="html-data-table">
        <tr>
            <th>Name</th>
            <th>Age</th>
        </tr>
    </table>    
</div>

Javascript code which creates the table:

newData.map(row => {
        let newRow = document.createElement("tr"); // new row is created
        Object.values(row).map((value) => {
            //console.log(value);
            let cell = document.createElement("td"); // new data for the row is added
            cell.innerText = value;
            newRow.appendChild(cell);
        })
        mytable.appendChild(newRow);
    });

I want to sort this both columns individually. What method can I use?

CodePudding user response:

You can use Array.sort() to sort your data, in this example I added two buttons to handle sorting by name and age:

const newData = [
  { name: "dave", age: 22 },
  { name: "charlie", age: 32 },
  { name: "eve", age: 19 },
  { name: "alice", age: 27 },
  { name: "bob", age: 20 }
]

const mytable = document.querySelector("#html-data-table tbody")
const btnSortName = document.getElementById("sortName")
const btnSortAge = document.getElementById("sortAge")


// RENDER UNSORTED TABLE
renderTable(newData)


btnSortName.addEventListener('click', (e) => {
  const sorted = newData.sort((a,b) => a.name.localeCompare(b.name))
  renderTable(sorted)
})


btnSortAge.addEventListener('click', (e) => {
  const sorted = newData.sort((a,b) => a.age - b.age)
  renderTable(sorted)
})



function renderTable(data) {
  mytable.innerHTML = ''
  
  data.map(row => {
    let newRow = document.createElement("tr"); // new row is created
    Object.values(row).map((value) => {
      //console.log(value);
      let cell = document.createElement("td"); // new data for the row is added
      cell.innerText = value;
      newRow.appendChild(cell);
    })
    mytable.appendChild(newRow);
  });
}
<div id="data-table">
  <table id="html-data-table">
    <thead>
      <tr>
        <th>Name</th>
        <th>Age</th>
      </tr>
    </thead>
    <tbody></tbody>
  </table>
</div>


<button id="sortName">Sort by Name</button>
<button id="sortAge">Sort by Age</button>

CodePudding user response:

Here is a method of sorting the table in place, independent of any generating data structures. The only additionally required information is the sortmode array that specifies whether a text sort or a numeric sort is wanted for a particular column.

const data=[{name:"Harry",age:32, height:183},{name:"Hermione",age:30, height:175},{name:"Ron",age:31,height:187},{name:"Hagrid",age:53,height:180},{name:"Ginny",age:27,height:170},{name:"Dumbledore",age:273,height:185}],
  sortmode=[0,1,1]; // 0: text, 1: numeric
  mytable=document.querySelector("#data-table tbody");

// fill table: code from OP
data.map(row => {
 let newRow = document.createElement("tr"); // new row is created
 Object.values(row).map((value) => {
  //console.log(value);
  let cell = document.createElement("td"); // new data for the row is added
  cell.innerText = value;
  newRow.appendChild(cell);
 })
 mytable.appendChild(newRow);
});

// sorting: my code
document.querySelector("#data-table thead").onclick=ev=>{
 let col=[...ev.target.parentNode.children].indexOf(ev.target);
 [...mytable.children]
  .sort((a,b)=>
    sortmode[col]
     ? a.children[col].textContent - b.children[col].textContent
     : a.children[col].textContent.localeCompare(b.children[col].textContent)
   )
  .forEach(tr=>mytable.append(tr))

}
td:nth-child(n 2) {text-align:right}
<div id="data-table">
Please click on the column headings to sort the table:
<table id="html-data-table">
   <thead>
    <tr><th>Name</th><th>Age</th><th>Height</th></tr>
   </thead><tbody></tbody>
</table>    
</div>

  • Related