JSON object with arrays converted to HTML table - javascript

the below code is the JSON response i recieve from an API. unfortunately i cannot change the way this response is sent, i can only use this response as is within the scope of Javascript/jQuery.
My goal is to transform this into a HTML table.
I have attempted to do this already myself;
function CreateTableView(objArray, theme, enableHeader) {
// set optional theme parameter
if (theme === undefined) {
theme = 'mediumTable'; //default theme
}
if (enableHeader === undefined) {
enableHeader = true; //default enable headers
}
// If the returned data is an object do nothing, else try to parse
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '<table id="res" class="' + theme + '">';
// table head
if (enableHeader) {
str += '<thead><tr>';
for (var index in array[0]) {
str += '<th scope="col">' + index.toUpperCase() + '</th>';
}
str += '</tr></thead>';
}
// table body
str += '<tbody>';
for (var i = 0; i < array.length; i++) {
str += (i % 2 == 0) ? '<tr class="alt" id="' + array[i]['id'] + '">' : '<tr id="' + array[i]['id'] + '">';
for (var index in array[i]) {
str += '<td style="width:15%;">' + htmlspecialchars_decode(array[i][index]) + '</td>';
}
str += '<td>Edit</td><td>Delete</td></tr>';
}
str += '</tbody>'
str += '</table>';
return str;
}
However I am only able to get the headers to show... But it works well if the JSON response has only one array ie one row returned.
the code above was adapted from several other questions like this on Stackoverflow, I have spent days on this and cannot get these results to show in a table... This is just one example of many other that are returned just like this example and i will need to reuse this solution many times making it very important to me.
"ItemArray":{
"id":"14"
,"0":
{"id":"1","username":"guest","fname":"Guest","lname":"User","email":"example#domain.com","group":"member","active":"0","url":null,"last_activity":null}
,"1":
{"id":"2","username":"system","fname":"Internal","lname":"System","email":"example#domain.com","group":"member","active":"0","url":null,"last_activity":null}
,"2":
{"id":"3","username":"master","fname":"Super","lname":"Admin","email":"example#domain.com","group":"member","active":"0","url":null,"last_activity":null}
,"3":
{"id":"14","username":"apitest","fname":"API","lname":"Test","email":"user#domain.com","group":"member","active":"0","url":null,"last_activity":"2012-10-29 02:48:43"}
}

You can't use array.length for Object, so you need:
for (var o in array) if (array.hasOwnProperty(o)) {
var row = array[o];
}

Ok... The problem is the your item array is parsed into an object. Not an array.
If you log this:
typeof array.length
The result is undefined. So your loops doesn't get run.

Related

Read CSV rows into array to display individual rows in different areas of page

I have been able to successfully read in a CSV file from a URL, parse through it, and write it out to a table. Simple to most but a Herculean effort for me. There is a header row, and each row contains 4 values (the first will be disregarded).
What I need to do is to be able to write each row to a different place on my page at will. I assume to do this I'd need to load each row into a slot in an array, where I can then call them specifically. For example if I want the 3rd entry, and also be able to access each value to build my text string, it would have to look something like:
document.getElementById("snow").innerHTML = 'Trail Status: ' + trail[2].status + 'Report Date: ' + trail[2].reportDate;
I know that the above code probably is flawed, but it was more illustrative than anything.
What I don't know how to do is setup an array to hold each row (so they can be accessed individually), define each value so it can be a accessed (trail, reportDate,etc), and read the CSV properly into that array.
I'm currently using jQuery and the code below to read, parse, and create the table.
$.ajax({
url: 'https://data.import.io/extractor/...',
dataType: 'text',
}).done(successFunction);
function successFunction(data) {
var allRows = data.split(/\r?\n|\r/);
var table = '<table>';
for (var singleRow = 0; singleRow < allRows.length; singleRow++) {
if (singleRow === 0) {
table += '<thead>';
table += '<tr>';
} else {
table += '<tr>';
}
var rowCells = allRows[singleRow].split(',');
for (var rowCell = 0; rowCell < rowCells.length; rowCell++) {
if (singleRow === 0) {
table += '<th>';
table += rowCells[rowCell];
table += '</th>';
} else {
table += '<td>';
table += rowCells[rowCell];
table += '</td>';
}
}
if (singleRow === 0) {
table += '</tr>';
table += '</thead>';
table += '<tbody>';
} else {
table += '</tr>';
}
}
table += '</tbody>';
table += '</table>';
$('body').append(table);
}
Any direction to reaching my end state would be greatly appreciated. Ultimately I'm building a dashboard that will show the Trail Conditions (from the CSV) and 10-day weather forecast (from Wunderground) to help plan Snowmobile Trips for local Michigan snowmobilers.
Thanks!
Marc
Create a multidimensional array - with 2 dimensions. The first index will access each row. The second index will access each cell within a row.
This reference may help: https://trans4mind.com/personal_development/JavaScript/Array2D.htm
This is an example using your current for loops.
function successFunction(data) {
var parsedData = [];
var allRows = data.split(/\r?\n|\r/);
for (var singleRow = 0; singleRow < allRows.length; singleRow++) {
var rowCells = allRows[singleRow].split(',');
for (var rowCell = 0; rowCell < rowCells.length; rowCell++) {
parsedData[singleRow][rowCell] = rowCells[rowCell];
}
}
}
Thanks for the input, i found that PapaParse was the way to go! The data was easy to get at and I had no problems!

How to sort a multidimensional array using items in Javascript [duplicate]

This question already has answers here:
Sort array of objects by string property value
(57 answers)
Closed 7 years ago.
Basically all I want is to sort this array based on each item that is shown below, with the exception of the "Action' and 'Thumb Image' ones. So the way I have it set up is that the header for each of rows is a link, and when that link is clicked the list will be sorted based on what was clicked. So for example, if Title is clicked, then I want to have a "titleSort()" function that will sort based on title. I have no idea how to accomplish this, so any help is much appreciated. I was hoping that VideoList.sort(Title) would work, for example.
Thanks,
JS
for(var i = 0; i<VideoList.length; i++) {
content += "<tr>";
content += "<td width='20%'><a href='https://www.youtube.com/watch?v=" + VideoList[i].VideoID + "'onclick='playVideo("+i+")'>" + "<img src ='https://i.ytimg.com/vi/" + VideoList[i].VideoID + "/hqdefault.jpg' width=175 height=130></a></td>";
content += "<td>" + VideoList[i].Title + "</td>";
content += "<td>" + VideoList[i].VideoID + "</td>";
content += "<td>" + VideoList[i].DateUploaded + "</td>";
content += "<td>" + VideoList[i].Category+ "</td>";
content += "<td>" + VideoList[i].Time+ "</td>";
content += "<td width='20%'>" + VideoList[i].Action + "</td>";
content += "</tr>";
You can use sort to sort VideoList according to title this code may work for you
VideoList.sort(function(a,b){
return a.Title > b.Title;
});
I agree with #manishrw about lodash. AND any number of libraries would make this easier - like jQuery and Angular. There are a ton of table-specific libraries out there that have sort function built in. However, I built it to show how you could do it, including re-building the table once it's sorted. To do that I had to create the array with mock data. Here's a jsfiddle:
https://jsfiddle.net/mckinleymedia/c02nqdbz/
And here's the code:
<div id="target"></div>
<script>
var VideoList = [],
content,
fields = ["Title", "VideoID", "DateUploaded", "Category", "Time", "Action"],
num = 10,
sortField = "Title",
sortDirection = 1,
compare = function(a, b) {
if (a[sortField] < b[sortField]) return -1 * sortDirection;
if (a[sortField] > b[sortField]) return 1 * sortDirection;
return 0;
},
sortArray = function(field) {
if( sortField === field ) sortDirection = -1 * sortDirection;
sortField = field;
VideoList.sort(compare);
buildTable();
},
creatVideos = function() {
for (var x = 0; x < num; x++) {
var video = {},
z = Math.floor(Math.random() * 200);
for (var i in fields) {
if(fields[i]==='VideoID') {
video[fields[i]] = z;
} else {
video[fields[i]] = fields[i] + "-" + z;
}
}
VideoList.push(video);
}
},
buildTable = function() {
content = "<table>";
content += "<tr>";
content += "<th>image</th>";
for (var x in fields) {
content += "<th class='field field-" + fields[x] + "' onclick='sortArray(\"" + fields[x] + "\")'>" + fields[x] + "</th>";
}
content += "</tr>";
for (var i in VideoList) {
content += "<tr>";
content += "<td width='20%'><a href='https://www.youtube.com/watch?v=" + VideoList[i].VideoID + "'onclick='playVideo(" + i + ")'>" + "<img src ='https://i.ytimg.com/vi/" + VideoList[i].VideoID + "/hqdefault.jpg' width=175 height=130></a></td>";
for (var x in fields) {
content += "<td>" + VideoList[i][fields[x]] + "</td>";
}
content += "</tr>";
}
content += "</table>";
document.getElementById('target').innerHTML = content;
};
creatVideos();
buildTable();
</script>
Here's a generic function for you
function sortBy(list, field) {
return list.sort(function(a,b) {
return a[field] < b[field];
});
}
sortBy(VideoList, 'Title');
Warning: sortBy will mutate the list input
You could also make it take a comparator so you control the 'direction' of the sort
// you you need to return -1, 0, or 1 for the sort to work reliably
// thanks, #torazaburo
function compareAsc(a,b) {
if (a < b) return -1;
else if (a > b) return 1;
else return 0;
}
function compareDesc(a,b) {
return compareAsc(a,b) * -1;
}
function sortBy(list, field, comparator) {
return list.sort(function(a,b) {
if (comparator instanceof Function)
return comparator(a[field], b[field]);
else
return compareAsc(a[field], b[field]);
});
}
// default sort ascending
sortBy(VideoList, 'Title');
// sort descending
sortBy(VideoList, 'Title', compareDesc);
Use Lodash library. It's easy to use and efficient in run-time. It has a function sortBy, which can be used to sort a collection based on they key you provide.
P.S. Lodash is my goto Library for any operation to be performed on any collection.

Dynamically add bootstrap rows using modulo

I a trying to dynamically add rows and populate them with 3 col-sm-4 using a modulo against the number of objects in a returned object from a function.
Code:
function formatSeriesCard(series) {
var card = "";
console.log(countProperties(series));
for (var i=0; i < countProperties(series); i++) {
if (i % 3 == 0 ) {
card += "<div class=\"row\">";
}
card += "<div class='col-sm-4' data-id="+i+">";
card += "<div class='action-box'>";
card += "<h4>" + '"' + series.name + '"' + "</h4>";
card += "<p>";
Instead I'm getting each row nested within the previous. Thinking I need to test for the first one and last one. Thanks.
Here is something like what you want
Bootply : http://www.bootply.com/2xnJBpyVsS
JS :
var wantedcol=14;
var mycol='<div class="col-xs-4">mycol</div>';
var startRowLabel="<div class='row'>";
var endRowLabel="</div>";
var start = "";
var end="";
var toAppend="";
for(var i=0; i<wantedcol; i++){
start="";
if(i%3==0 || i==0){
start=startRowLabel;
}
end="";
if(i!=0 && (i%3==2 || i==wantedcol-1)){
end=endRowLabel;
}
console.log(start+mycol+end);
toAppend+=start+mycol+end;
}
$('.container').append(toAppend);
HTML:
<div class="container"></div>
Comment :
You just have to take care about when you have to insert the div.row opening and closing tags

Sorting &Pagination for html table

Am using this Json to Html table and am getting the values also. All I need to do is implement sorting for this. Can someone help me out?
where in the objArray am passing my Json data.
All I need to do is implement Sorting and pagination. Please help me out.
function CreateTableViewX(objArray, theme, enableHeader) {
// set optional theme parameter
if (theme === undefined) {
theme = 'mediumTable'; //default theme
}
if (enableHeader === undefined) {
enableHeader = true; //default enable headers
}
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '<table class="' + theme + '">';
// table head
if (enableHeader) {
str += '<thead><tr>';
for (var index in array[0]) {
str += '<th scope="col">' + index + '</th>';
}
str += '</tr></thead>';
}
// table body
str += '<tbody>';
for (var i = 0; i < array.length; i++) {
str += (i % 2 == 0) ? '<tr class="alt">' : '<tr>';
for (var index in array[i]) {
str += '<td>' + array[i][index] + '</td>';
}
str += '</tr>';
}
str += '</tbody>'
str += '</table>';
return str;
}
Try Jquery datatable
All you need is to refer Jquery and datables Script files in your solution, select your html table using an Id or class name and Initialize it like this. Datatable will then take care of sorting and pagination for you.
$(document).ready(function(){
$('#tableID').dataTable();
});

Find the value of html table cell by passing column name for a particular row

I am dynamically creating a table using JSON so i dont know in advance how many column and/or rows will be generated.
I add a clicked event for the row that get selected.
Now my every table will have a column name ID
I want to find the value of ID for the selected row.
How can i achieve this?
I have googled a find a lot of sample which select the cell be index but not by column name.
My table is something like:
My table is generated like:
function CreateTableView(objArray, theme, enableHeader) {
// set optional theme parameter
if (theme === undefined) {
theme = 'mediumTable'; //default theme
}
if (enableHeader === undefined) {
enableHeader = true; //default enable headers
}
// If the returned data is an object do nothing, else try to parse
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '<table class="' + theme + '">';
// table head
if (enableHeader) {
str += '<thead><tr>';
for (var index in array[0]) {
str += '<th scope="col">' + index + '</th>';
}
str += '</tr></thead>';
}
// table body
str += '<tbody>';
for (var i = 0; i < array.length; i++) {
str += (i % 2 == 0) ? '<tr class="alt">' : '<tr>';
for (var index in array[i]) {
str += '<td>' + val(array[i][index]) + '</td>';
}
str += '</tr>';
}
str += '</tbody>'
str += '</table>';
return str;
}
Any help is appreciated
I hope i understood you correctly but this should do it.
It alerts the content of the td with the name ID of the clicked tr.
$('tr').live('click',function(){
alert( $(this).find('td[name="ID"]').html() );
});
To find the td via the th with text ID you could do this:
var index = $('yourtable th:contains("ID")').index();
alert( $('.selectedRow td:eq('+index+')').html() );
What I would do though is to save the ID in the TR's data object so you won't have to pull it out the td but can access it directly, like this:
[...]
<tr data-id="26"><td>.....</td></tr>
[...]
then you can access it like that:
$('.selectedRow').data('id');

Categories