Convert JSON file to sorted table using pure JavaScript

I have a cats.json JSON file.

[{ "breed" : "Abyssinian", "country" : "Ethiopia", "coffeePreference" : "espresso", "picture" : "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9b/Gustav_chocolate.jpg/100px-Gustav_chocolate.jpg" }, { "breed" : "Aegean", "country" : "Greece", "coffeePreference" : "medium roast, cream and sugar", "picture" : "https://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Aegean_cat.jpg/100px-Aegean_cat.jpg" }] 

The above is a brief snippet. I am trying to load this JSON file using getJson and format it in a sortable table. I can display the table on the screen, but I can’t get the job sort of. I know that the sorting function works in a regular HTML table, and I think it has something to do with my general approach, as I am new to the interface. The code is as follows:

 <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html;charset=Windows-1252"> <style type="text/css"> table { border-collapse: collapse; border: none; } th, td { border: 1px solid black; padding: 4px 16px; font-family: Times New Roman; font-size: 24px; text-align: left; } th { background-color: #C8C8C8; cursor: pointer; } </style> </head> <body> <div id="catTable"></div> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script> var cats, asc1 = 1, asc2 = 1, asc3 = 1; window.onload = function () { cats = document.getElementById("cats"); } function sort_table(tbody, col, asc) { var rows = tbody.rows, rlen = rows.length, arr = new Array(), i, j, cells, clen; // fill the array with values from the table for (i = 0; i < rlen; i++) { cells = rows[i].cells; clen = cells.length; arr[i] = new Array(); for (j = 0; j < clen; j++) { arr[i][j] = cells[j].innerHTML; } } // sort the array by the specified column number (col) and order (asc) arr.sort(function (a, b) { return (a[col] == b[col]) ? 0 : ((a[col] > b[col]) ? asc : -1 * asc); }); // 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>"; } } $.getJSON('cats.json', function(cats) { var output="<table>"; output+="<thead>" output+="<tr>"; output+="<th> HeadShot </th>"; output+= '<th onclick="sort_table(cats, 0, asc1); asc1 *= -1; asc2 = 1; asc3 = 1;">Breed</th>'; output+= '<th onclick="sort_table(cats, 1, asc2); asc2 *= -1; asc3 = 1; asc1 = 1;">Country</th>'; output+= '<th onclick="sort_table(cats, 2, asc3); asc3 *= -1; asc1 = 1; asc2 = 1;">CoffeePreference</th>'; output+="</tr>"; output+="</thead>"; for (var i in cats) { output+="<tbody id = 'cats'>"; output+="<tr>"; output+="<td><img src='" + cats[i].picture+"' alt='cat picture'> </td>"; output+="<td>" + cats[i].breed + "</td>"; output+="<td>" + cats[i].country + "</td>"; output+="<td>" + cats[i].coffeePreference + "</td>"; output+="</tr>"; output+="</tbody>"; } output+="</table>"; document.getElementById("catTable").innerHTML=output; }); </script> </body> </html> 

Any help or direction. will be greatly appreciated.

+4
source share
2 answers

https://www.datatables.net/

This will automatically create a table for you from JSON and sort it in place. A good starting point for your specific setup is this:

https://www.datatables.net/examples/server_side/object_data.html

You can use it without "processing" and "serverSide" and replace the "ajax" part with your JSON file.

Edit

Here is the basic implementation with your dataset: http://jsbin.com/kajina/1/edit?html,js,output

Edit 2

To use a remote data source, you need to replace the {data: cats} property with {ajax: "cats.json"}. This will cause DataTables to run the $ .getJSON () function for you and retrieve the data from the server.

Several types of data sources are available here https://www.datatables.net/examples/data_sources/

Also, for a large JSON file, I recommend considering pagination (the server filters the data and sends you only one page of items at a time). See here: https://www.datatables.net/examples/server_side/simple.html

+5
source

May help you get started:

The idea is to create an array of row objects, where each object has a property for each table header, and this property has an associated data point for that row.

Then an array of row objects can be sorted (using the sortByKey function) based on a specific header.

The resulting array of sorted row objects can then be returned to the existing table in sorted order.

If possible, it might be easier to save the object representing the table for sorting and visualization, rather than for capturing data from the table.

Unverified, but can cause the ball to roll. Good luck

  /** *Sort a table element based on a header value *@param {object} table The table containing data to be sorted *@param {string|number} The column used to sort the rows *@param {boolean|null} Determines if the sort should be in reverse order */ var sortTable = function sortTable (table, sortColumn, reverse) { var tArr = []; var tHeaders = table.tHead.getElementsByTagName('th'); var tRows = table.tBody.getElementsByTagName('tr'); var sArr; //Create an array of header titles for the table //In the order they appear in the header row var headers = table.tHead.getElementsByTagName('th'); //Convert to actual array headers = [].slice.call(headers); //Replace objects with text headers = headers.map(function getHeaderText(header) { return header.innerText || header.textContent; }); //Create a row object for each row of data in the table //having a property for each column of the table and //a corresponding value for that column tRows.forEach(function applyRows(row) { var col_ct = headers.length - 1; var rowObj = {}; //Create an array of data values in the order they appear //in the row var data = row.getElementsByTagName('td'); data = [].slice.call(data); data = data.map(function getDataText(data) { return data.innerText || data.textContent; }); //The number of headers should match the number //of data points in the row if (headers.length !== data.length) { alert('Column mismatch'); } //Set header property value to associated data for this row while (col_ct) { rowObj[headers[col_ct]] = data[col_ct]; col_ct--; } //Add the row to the table array tArr.push(rowObj); }); //Now tArr contains all rows of your table //use sortObjs to sort rows based on particular property sArr = tArr.sort(sortByKey(sortColumn, reverse)); //Then unfold the sorted object to rebuild the table sArr.forEach(function buildTableRow(rowObj) { //Some function that builds table rows and renders them //Rows will then be rendered in sorted order }); }; /** *Sort an array of objects based on a key *@param {string|number} field The property to sort by *@param {boolean} reverse The direction of sort *@return {object} Params for sort */ var sortByKey = function sortByKey(key, reverse) { /** *Return the value of a given key *@param {object} o The object to sort *@return {string|number|object} The value of the key */ var value = function (o) { return o[key]; }; var reverse = (reverse) ? -1 : 1; return function (a, b) { return a = value(a), b = value(b), reverse * ((a > b) - (b > a)); }; }; 
+1
source

All Articles