There were two static field column in your table billtype and average which needed to be appended before looping the json data
var outletCount = 0; //global variable to get the no of outlets
var data = [{
"outlet": "JAYANAGAR",
"cancelled": 126544,
"duplicate": 1
},
{
"outlet": "MALLESHWARAM",
"cancelled": 31826,
"duplicate": 31
},
{
"outlet": "KOLAR",
"cancelled": 10374,
"duplicate": 10
},
{
"outlet": "New Test",
"cancelled": 154,
"duplicate": 20
}
];
let formatData = function(data) { //outlets is unique thats why formating it to loop forward in my code
let outlets = [];
data.forEach(element => {
if (outlets.indexOf(element.outlet) == -1) {
outlets.push(element.outlet);
}
});
outletCount = outlets.length //calculating outlet count
return {
data: data,
outlets: outlets,
};
};
let renderTable = function(data) {
outlets = data.outlets;
data = data.data;
let tbl = document.getElementById("tblOlSalesSummary");
let table = document.createElement("table");
let thead = document.createElement("thead");
let headerRow = document.createElement("tr");
let th = document.createElement("th");
th.innerHTML = "Bill Type"; //header
th.classList.add("text-center");
headerRow.appendChild(th);
th = document.createElement("th");
th.innerHTML = "Average"; //header
th.classList.add("text-center");
headerRow.appendChild(th);
outlets.forEach(element => {
th = document.createElement("th");
th.innerHTML = element; //this one is populating outlet as header
th.classList.add("text-center");
headerRow.appendChild(th);
});
thead.appendChild(headerRow);
table.appendChild(thead);
let tbody = document.createElement("tbody"); // from here onwards i don't know what to do
let row = document.createElement("tr");
let total = 0;
// static field insertion for Cancelled bill
let el = 'Cancelled bill';
td = document.createElement("td");
td.innerHTML = el.toLocaleString('en-in');
td.classList.add("text-right");
row.appendChild(td);
// Logic start to find the average cancelled amount
var total_cancel =0;
total_can_count = 0;
outlets.forEach(outlet => {
data.forEach(d => {
if (d.outlet == outlet) {
total_cancel += parseInt(d.cancelled);
total_can_count++;
}
});
});
let el_avg = ( total_cancel / (total_can_count) );
td = document.createElement("td");
td.innerHTML = el_avg.toLocaleString('en-in');
td.classList.add("text-right");
row.appendChild(td);
// Logic End to find the average cancelled amount
outlets.forEach(outlet => {
let el = 0;
data.forEach(d => {
if (d.outlet == outlet) {
total += parseInt(d.cancelled);
el = d.cancelled;
}
});
td = document.createElement("td");
td.innerHTML = el.toLocaleString('en-in');
td.classList.add("text-right");
row.appendChild(td);
});
/* console.log("row is : " , row.children ) */
tbody.appendChild(row);
let row_duplicate = document.createElement("tr");
let total_dup = 0;
// static field insertion for duplicate bill
let el_2 = 'Duplicate bill';
td = document.createElement("td");
td.innerHTML = el_2.toLocaleString('en-in');
td.classList.add("text-right");
row_duplicate.appendChild(td);
// Logic start to find the Duplicate average
total_dup_count = 0;
outlets.forEach(outlet => {
data.forEach(d => {
if (d.outlet == outlet) {
total_dup += parseInt(d.duplicate);
total_dup_count++;
}
});
});
let el_avg_2 = ( total_dup / (total_dup_count) );
td = document.createElement("td");
td.innerHTML = el_avg_2.toLocaleString('en-in');
td.classList.add("text-right");
row_duplicate.appendChild(td);
// Logic End to find the Duplicate average
outlets.forEach(outlet => { //i am trying to loop through outlets but getting somthing else
let el = 0;
data.forEach(d => {
if (d.outlet == outlet) {
total += parseInt(d.duplicate);
el = d.duplicate;
}
});
td = document.createElement("td");
td.innerHTML = el.toLocaleString('en-in');
td.classList.add("text-right");
row_duplicate.appendChild(td);
});
/* console.log("row is : " , row.children ) */
tbody.appendChild(row);
tbody.appendChild(row_duplicate);
table.appendChild(tbody);
tbl.innerHTML = "";
tbl.appendChild(table);
table.classList.add("table");
table.classList.add("table-striped");
table.classList.add("table-bordered");
table.classList.add("table-hover");
}
let formatedData = formatData(data);
renderTable(formatedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<div align="center" class="table table-responsive">
<table id="tblOlSalesSummary"></table>
</div>
I've written the code in this JSFiddle. Take a look. It uses JQuery.
HTML:
<table id="dataTable">
</table>
JavaScript:
var data = [{
"outlet": "JAYANAGAR",
"cancelled": 126544,
"duplicate": 1
},
{
"outlet": "MALLESHWARAM",
"cancelled": 31826,
"duplicate": 31
},
{
"outlet": "KOLAR",
"cancelled": 10374,
"duplicate": 10
}
];
function draw() {
var avgCancelled = 0;
var avgDuplicate = 0;
var totalCancelled = 0;
var totalDuplicate = 0;
for (var i = 0; i < data.length; i++) {
totalCancelled += data[i].cancelled;
totalDuplicate += data[i].duplicate;
}
avgCancelled = totalCancelled / data.length;
avgDuplicate = totalDuplicate / data.length;
drawTableHead()
drawTableRows(avgCancelled, avgDuplicate)
}
function drawTableHead() {
var row = $("<tr />");
$("#dataTable").append(row);
row.append("<th>" + "BILLTYPE" + "</th>")
row.append("<th>" + "AVERAGE" + "</th>")
for (var i = 0; i < data.length; i++) {
row.append("<th>" + data[i].outlet + "</th>")
}
}
function drawTableRows(avgCancelled, avgDuplicate) {
var firstRow = $("<tr />");
$("#dataTable").append(firstRow);
firstRow.append("<td>" + "CANCELLED BILL" + "</td>")
firstRow.append("<td>" + avgCancelled + "</td>")
for (var i = 0; i < data.length; i++) {
firstRow.append("<td>" + data[i].cancelled + "</td>")
}
var secondRow = $("<tr />");
$("#dataTable").append(secondRow);
secondRow.append("<td>" + "DUPLICATE BILL" + "</td>")
secondRow.append("<td>" + avgDuplicate + "</td>")
for (var i = 0; i < data.length; i++) {
secondRow.append("<td>" + data[i].duplicate + "</td>")
}
}
draw();
Get rid of the '#' in getElementById()
let output = document.getElementById("stats-output");
I think one thing you're missing is to parse the JSON data so it's properly readable and iterable in javascript. Use JSON.parse(json data you pulled).
Here is the code bit I think will demonstrate:
var data = `[{
"Position": "ST",
"Name": "Ronaldo",
"Apperiences": "50",
"Assists": "11",
"Clean_Sheets": "10"
}, {
"Position": "ST",
"Name": "Messi",
"Apperiences": "50",
"Assists": "11",
"Clean_Sheets": "10"
}, {
"Position": "ST",
"Name": "Pele",
"Apperiences": "50",
"Assists": "11",
"Clean_Sheets": "10"
}]`;
var parsed_data = JSON.parse(data)
console.log(parsed_data)
parsed_data.forEach( json_data_set =>{
var tr = document.createElement("tr")
Object.keys(json_data_set).forEach( key =>{
var td = document.createElement("td")
td.innerText = json_data_set[key]
tr.appendChild(td)
})
document.querySelector("tbody").appendChild(tr)
})
Hope this helps.
This is an example on how to accept an array of arbitrary objects and just render them on a table by inspecting all of their properties.
Maybe this is an answer trying to address a problem bigger than what was strictly asked anyway it could be interesting to inspect this option.
The main issue with this solution is that, since there's no guarantee on the fact that all objects in the array will be consistent with their properties, the very first step is navigating the whole array collecting a set of unique property names found and use it to build the table header.
Such array of unique property names will be used also later to build the table rows. Since the list of objects doesn't hold the order of the property names, they will be listed randomly in the output table.
The way header and rows get built from the propertyNames and data goes like this:
const header = buildTableHeader(uniquePropertyNames);
const rows = buildTableBody(uniquePropertyNames, data);
The order of items in the uniquePropertyNames will rule how they will be rendered on the output table.
The entry point is just:
renderObjectsToTable(data, '#target');
Where '#target' is the selector to fetch the target table to render the data inside.
Edit:
I corrected a mistake I did using the variable data inside a function and I added the demo option to pass a list of html elements to the rendering procedure. Just to draw a bigger picture.
const data = [
{
"name": "value1",
"email": "[email protected]"
},
{
"id": "123",
"name": "value2",
},
{
"name": "value3",
"email": "[email protected]",
"messsage": "lorem ipsum"
},
{
"name": "value4",
"email": "[email protected]"
}
];
renderObjectsToTable(data, '#target');
function renderObjectsToTable(objects, target){
const uniquePropertyNames = [];
objects.forEach(obj => {
for (const prop in obj) {
if(!uniquePropertyNames.includes(prop))
uniquePropertyNames.push(prop);
}
});
const header = buildTableHeader(uniquePropertyNames);
const rows = buildTableBody(uniquePropertyNames, objects);
const table = document.querySelector(target);
table.querySelector('thead').append(header);
table.querySelector('tbody').append(...rows);
}
function buildTableHeader(propertyNames){
const headerRow = document.createElement('tr');
propertyNames.forEach( prop => {
const headerCell = document.createElement('th');
headerCell.innerText = prop;
headerRow.append(headerCell);
});
return headerRow;
}
function buildTableBody(propertyNames, objects){
const tableRows = [];
objects.forEach(obj => {
debugger;
const currentRow = document.createElement('tr');
propertyNames.forEach(prop => {
const tableCell = document.createElement('td');
debugger;
const value = (obj[prop] === undefined) ? '' : obj[prop];
tableCell.innerText = value;
currentRow.append(tableCell);
});
tableRows.push(currentRow);
});
return tableRows;
}
function goWild(){
document.querySelector('#target thead').innerHTML = '';
document.querySelector('#target tbody').innerHTML = '';
const nodes = document.getElementById('wildList').childNodes;
renderObjectsToTable(nodes, '#target');
}
#target{
border-collapse: collapse;
}
#target th,
#target td
{
border: solid 1px;
padding: .2em;
}
.hidden{
display: none;
}
#gowild{
padding: .5em 2em;
margin-top: 1em;
cursor: pointer;
}
<table id="target">
<thead></thead>
<tbody></tbody>
</table>
<button id="gowild" onclick="goWild();">GO WILD</button>
<ul id="wildList" class="hidden">
<li data-wild="very">Wild List Item #1</li>
<li data-wild="toomuch">Wild List Item #2</li>
</ul>
const data = [{
"name": "value1",
"email": "[email protected]"
},
{
"id": "123",
"name": "value2",
},
{
"name": "value3",
"email": "[email protected]",
"messsage": "lorem ipsum"
},
{
"name": "value4",
"email": "[email protected]"
}
];
const tableBody = document.querySelector("tbody");
data.forEach(d => {
tableBody.innerHTML += `<tr>
<td>${d.id || ""}</td>
<td>${d.name || ""}</td>
<td>${d.email || ""}</td>
<td>${d.messsage || ""}</td>
</tr>`;
})
table {
border-collapse: collapse;
}
table :where(tr, th, td) {
border: 1px solid gray;
}
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>email</th>
<th>message</th>
</tr>
</thead>
<tbody></tbody>
</table>