SortTable using only JS

Hi all,

I have loaded JSON data into HTML table using only Javascript code.

Now can anyone help me for, Sorting the columns ?

Thanks in advance

The best solution for sorting and working with tables is DataTables - I’ve used it recently for a few projects and have really come to appreciate all that it can do.

Hi paul,

thanks for your reply.

I am trying it to implement in pure javascript.

Is there any suggestions for that

THanks

It should help if you post an (adequate but not extensive) example of the JSON you’re working with.

What do you mean by pure javascript? DataTables is pure Javascript, as is jQuery too. No PHP or other scripting language need be used at all.

1 Like

Hi paul,

I do not use any JQueryin my script.

Ex:

JSON DATA
[{ “first_name”: “Billy”, “last_name”: “Campbell”, “phone”: “62-(500)527-5325” }, { “first_name”: “Jonathan”, “last_name”: “Black”, “country”: “Russia”, “phone”: “7-(729)811-4597” }, { “first_name”: “cheryl”, “last_name”: “Harvey”, “country”: “Indonesia”, “phone”: “62-(825)454-3810” }]

Using the above data I have created my table.

Code:
function tblGene(){

// Declaring a variable to store JSON data.
var data = [{ "first_name": "Billy", "last_name": "Campbell", "phone": "62-(500)527-5325" }, { "first_name": "Jonathan", "last_name": "Black", "country": "Russia", "phone": "7-(729)811-4597" }, { "first_name": "cheryl", "last_name": "Harvey", "country": "Indonesia", "phone": "62-(825)454-3810" }]


//Declare an array variable to store the column headers.
var col = [];
for (var i = 0; i < data.length; i++) 
{
	
	// Separate the header from the JSON data.
    for (var colHdr in data[i]) 
	{
        if (col.indexOf(colHdr) === -1) 
		{
        
			//Push the Header value into an array variable.
			col.push(colHdr);
        }
    }
}

// Creating a dynamic table for JSON Data. 
var tbl = document.createElement("table");

// Add a table row.
var tr = tbl.insertRow(-1);                   

// Loop to add the table Headers.
for (var i = 0; i < col.length; i++) 
{
		
	// Creating the header element for table.
	var th = document.createElement("th");      
    th.innerHTML = col[i];
    tr.appendChild(th);
}

// Loop to add JSON data into the table.
for (var i = 0; i < data.length; i++) 
{
	tr = tbl.insertRow(-1);
	for (var j = 0; j < col.length; j++) 
	{
		var tabCell = tr.insertCell(-1);
        tabCell.innerHTML = data[i][col[j]];
		var arr[i][j] = tabCell.innerHTML;
		
    }
}

// Add the table to the container.
var divCntr = document.getElementById("showData");
divCntr.innerHTML = "";
divCntr.appendChild(tbl);

Now i need to implement Sort for each column. So i need your help guys .

Thanks

You might just sort the data array before generating the table, like e.g.

var sorted = data.sort(function(a, b) {
  return a.last_name > b.last_name;
});

To make this reusable for arbitrary columns, you could write a small sorting function like

function sortData(data, key, desc) {
  return data.sort(function(a, b) {
    return desc
      ? a[key] < b[key]
      : a[key] > b[key];
  });
}

// Sort data by last name in ascending order
var sorted = sortData(data, 'last_name');

// Sort data by first name in descending order
var sorted = sortData(data, 'first_name', true);

If you want to re-sort the table, the easiest way would be to simply generate it anew. As you might guess, this is not particularly performant though and not really viable for larger amounts of data… but it depends on your requirements, I suppose.

2 Likes

Dear m3g4p0p

Thanks for your reply.

Can I contact via skype. so we can discuss the exact problem

Thanks
Sunil

Sorry @sunny4989, I don’t give private lessons. Why not discuss the exact problem here, so that anyone can join in and possible solutions are open to the public?

(Actually, why not post the exact problem from the first?) ;-)

Thank you M3g4p0p,

As you can see in the above code, I have generated the Html table using JSON Data. I have created th, tr, table in Javascript.

Problem statement:
I need to add a event click handler to every th of table so that it will sort rows by value.

Code for reference

// Declaring a variable to store JSON data.
var data = [{ "first_name": "Billy", "last_name": "Campbell", "phone": "62-(500)527-5325" }, { "first_name": "Jonathan", "last_name": "Black", "country": "Russia", "phone": "7-(729)811-4597" }, { "first_name": "cheryl", "last_name": "Harvey", "country": "Indonesia", "phone": "62-(825)454-3810" }]


//Declare an array variable to store the column headers.
var col = [];

for (var i = 0; i < data.length; i++) 
{
	
    // Separate the header from the JSON data.
    for (var colHdr in data[i]) 
	{
        if (col.indexOf(colHdr) === -1) 
		{
        
			//Push the Header value into an array variable.
			col.push(colHdr);
        }
    }
}

// Creating a dynamic table for JSON Data. 
var tbl = document.createElement("table");

// Add a table row.
var tr = tbl.insertRow(-1);                   

// Loop to add the table Headers.
for (var i = 0; i < col.length; i++) 
{
		
	// Creating the header element for table.
	var th = document.createElement("th");      
    th.innerHTML = col[i];
    tr.appendChild(th);
}

// Loop to add JSON data into the table.
for (var i = 0; i < data.length; i++) 
{
	tr = tbl.insertRow(-1);
	for (var j = 0; j < col.length; j++) 
	{
		var tabCell = tr.insertCell(-1);
        tabCell.innerHTML = data[i][col[j]];
		var arr[i][j] = tabCell.innerHTML;
		
    }
}

// Add the table to the container.
var divCntr = document.getElementById("showData");
divCntr.innerHTML = "";
divCntr.appendChild(tbl);

This exactly what many already written scripts do very well.
Some even allow drag-drop sorting.

I suppose if you have the time and wanted to “reinvent the wheel” as a learning exercise you could reverse engineer one of the many scripts.

An “on page load” sort is comparatively easy compared to a dynamic sort. So if you are having trouble with the easier I recommend you find and use code that has already been written by others and has been proven to work well instead of trying to RYO.

1 Like

I understood the code which m3g3p0p has written.

But i am facing problem in integrating it to my script.

A basic approach might be to set the key of each th as a data attribute, and bind an event listener to the thead – you might consider adding one ;-) – which sorts the data accordingly and then re-populates the table; like (modified from your above code)

var thead = document.createElement('thead');
var tbody = document.createElement('tbody');

// etc...

// Loop to add the table Headers.
for (var i = 0; i < col.length; i++) {

  // Creating the header element for table.
  var th = document.createElement("th");
  th.innerHTML = col[i];
  th.dataset.key = col[i];
  tr.appendChild(th);
}

thead.appendChild(tr);

thead.addEventListener(function(event) {
  var key = event.target.dataset.key;
  var sorted = data.sort(function(a, b) {

    // Just fixed an error from my 
    // above snippet here :-$
    return a[key] > b[key] ? 1 : -1;
  });

  // Re-populate the table -- ideally put that
  // in a dedicated function, like e.g.
  tbody.innerHTML = '';
  sorted.forEach(populate);
});

BTW, this line

var arr[i][j] = tabCell.innerHTML;

will throw an error – is it supposed to serve any special purpose? Otherwise I’d suggest to remove it. ;-)

Anyway, here’s a small module to generate such a sortable table; I’ve incorporated the above functionality, so if you get stuck, you might just have a glimpse there (and of course ask if something is unclear!).

1 Like

Thank you m3g4p0p.

_The code of yours solved my half problem. _

I need one more help
EX:

// Declare body section.
	var tbody = document.createElement('tbody');
	tbody.id = "taskBdy";

I have given a ID for tbody tag. How can i reterive the same Id inside the below function.

thead.addEventListener("click",function(event){
		var key = event.target.dataset.key;
		//i need the tbody id here
	});

Dear m3g4p0p,

I got the sorting solution.

But now i am facing new problem

var sorted = data.sort(function(a, b) {

    // Just fixed an error from my 
    // above snippet here :-$
    return a[key] > b[key] ? 1 : -1;
  });

Before Sort
Billy
cheryl
Jonathan
Robert

After Sort
Billy
Jonathan
Robert
cheryl

Expected After Sort
Billy
cheryl
Jonathan
Robert

Does something like

var id = tbody.id;

not work?

You might convert the characters to compare toUpperCase() (or lower case) to make the sort case-insensitive. Just make sure you are comparing strings, not numbers (like when sorting by ID, say). Like

sorted = data.sort(function(a, b) {
  if (typeof a[key] === 'string' && typeof b[key] === 'string') {
    return a[key].toUpperCase() < b[key].toUpperCase() ? -1 : 1;
  } else {
    return a[key] - b[key];
  }
});
1 Like

Thank you m3g4p0p.

But in JSON data even we have numbers as string

Ex:

"first_name": "Billy", "last_name": "Campbell", "phone": "62-(500)527-5325"

So how can i check it?

You can use the Number constructor for that – it will return NaN if the string can’t get converted to a number. Like

if (Number(value)) { /* value is a number */ }

or the other way round

if (isNaN(value)) { /* value is not a number */ }

Its not working```

   arr.sort(function (x, y) 
		{
			if (isNaN(x[key]) && isNaN(y[key]))
{
		    var a = String(x[key]).toUpperCase(); 
			var b = String(y[key]).toUpperCase(); 
			if (a > b) 
				return 1 
			if (a < b) 
				return -1 
			return 0;
			}
			else
			{
				
				return x[key] - y[key];
			}
        });

I have my solution please run it in you local system

HTML

<!DOCTYPE html>
<html>
	<head>
		<title>Generate a table from JSON Data</title>
		<style>
			table, th, td 
			{
				margin:10px 0;
				border:solid 1px #333;
				padding:2px 4px;
				font:15px Verdana;
			}
			th {
				font-weight:bold;
			}
		</style>
	</head>
	<body>
		
		<script src="Babu.js" type="text/javascript"> </script>
		<input type="button" onclick="tblGene()" value="Click Here to Generate Table" style="width:100% height:100%"/>
		<div id="showData"></div>
	</body>
</html>

js

// Global Variables.
var people, asc1 = 1;

// Function to generate HTML table from JSON data.
// Sort according to the column names.        
function tblGene(){
	
	// Declaring a variable to store JSON data.
	var data = [ { "company_name":"Medline Industries, Inc.", "product":"Benzalkonium Chloride", "price":"481.63" }, { "company_name":"PD-Rx Pharmaceuticals, Inc.", "product":"Alprazolam", "price":"167.62", "fda_date_approved":"02/12/2015" }, { "company_name":"L. Perrigo Company", "product":"Dextromethorphan Hydrobromide, Guaifenesin", "price":"73.09", "fda_date_approved":"03/02/2016" } ]
	
	// Creating a dynamic head section.
	var thead = document.createElement('thead');
	
	// Creating a dynamic body section.
	var tbody = document.createElement('tbody');
	
	// Assign the ID attribute of tbody.
	tbody.id = "people";
	
	// Creating a dynamic table for JSON Data. 
	var tbl = document.createElement("table");
	
	// Assign the ID attribute of table.
	tbl.id = "tblSample";
	
	//Declare an array variable to store the column headers.
	var col = [];
	for (var i = 0; i < data.length; i++) 
	{
		
		// Separate the header from the JSON data.
        for (var colHdr in data[i]) 
		{
            if (col.indexOf(colHdr) === -1) 
			{
            
				// Push the Header value into an array variable.
				col.push(colHdr);
            }
        }
    }
	
	// Add a table row.               
	var tr = tbl.insertRow(-1);  
	
	// Loop to add the table Headers.
	for (var i = 0; i < col.length; i++) 
	{
		
		// Creating the header element for table.
		var th = document.createElement("th");      
		th.innerHTML = col[i];
		
		// set the key for each column header.
		th.dataset.key = i;
        tr.appendChild(th);	 
    }
	
	// Append the table row to table header section. 
	thead.appendChild(tr);
	
	
	// Loop to add JSON data into the table.
    for (var i = 0; i < data.length; i++) 
	{
		
		tr = tbl.insertRow(-1);
		for (var j = 0; j < col.length; j++) 
		{
			
			// Creating the header element for table.
			var td = document.createElement("td");  
			var tabCell = tr.insertCell(-1);
            tabCell.innerHTML = data[i][col[j]];
        }
		
		// Append the table row to table body section.
		tbody.appendChild(tr);		
    }
	
	// Append head section to table.
	tbl.appendChild(thead);
	
	// Append body section to table.
	tbl.appendChild(tbody);
	
    // Add the table to the container.
	var divCntr = document.getElementById("showData");
	divCntr.innerHTML = "";
	divCntr.appendChild(tbl);
	
	// OnClick event for the header.
	thead.addEventListener("click",function(event)
	{
		
		// Variable stores the Key column that needs to be sorted.
		var key = event.target.dataset.key;
		
		// Fetching the table body information from the table.
		people = document.getElementById("people"); 
		
		// Function declaration to Sort HTML table.
		sort_tbl(people, key, asc1);
	});
	
	// Function definition to sort the table.
	function sort_tbl(tblSample, key, asc)
	{
		var rows = tblSample.rows,
        rlen = rows.length,
        arr = new Array();
		
        // fill the array with values from the table
        for (var i = 0; i < rlen; i++) 
		{
            var cells = rows[i].cells;
            var clen = cells.length;
            arr[i] = new Array();
            for (var j = 0; j < clen; j++) 
			{
                arr[i][j] = cells[j].innerHTML;
            }
        }
		
		// Sort functionality. 
		arr.sort(function (x, y) 
		{
			if (isNaN(x[key]) && isNaN(y[key])){
		    var a = String(x[key]).toUpperCase(); 
			var b = String(y[key]).toUpperCase(); 
			if (a > b) 
				return 1 
			if (a < b) 
				return -1 
			return 0;
			}
			else
			{
				return x[key] - y[key];
			}
        });
            
		// Replace existing rows with new rows created from the sorted array.
        for (i = 0; i < rlen; i++) 
		{
            rows[i].innerHTML = "<td>" + arr[i].join("</td><td>") + "</td>";
        }
	}
}