I want to create an HTML table using json data. The json data will change over time. When convert this json data to an HTML table, the table looks like this with consistent. It means the alignment of values and the width of the table. How can I convert the json data into an HTML table?
[
{
"1": [{
"Time": "01:35 AM",
"Location": "dhaka bangladesh",
"BUS Detail": {
"air_Logo": "logo goes here",
"air_Name": "Airbus"
},
"busNo": "AK119",
"arrTime": "05:40 AM",
"arrival Loc": "barisal"
}]
}
]`// Extract value from table header.
let col = [];
for (let i = 0; i < myBooks.length; i++) {
for (let key in myBooks[i]) {
if (col.indexOf(key) == -1) {
col.push(key);
}
}
}
// Create a table.
const table = document.createElement("table");
// Create table header row using the extracted headers above.
let tr = table.insertRow(-1); // table row.
for (let i = 0; i < col.length; i++) {
let th = document.createElement("th"); // table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
// add json data to the table as rows.
for (let i = 0; i < myBooks.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
const tabcel = tr.insertCell(-1);
if (typeof myBooks[i][col[j]] === 'object') {
tabcel.setAttribute('rowspan','2');
tabcel.innerHTML = `<table><td>${myBooks[i][col[j]].air_Name}</td> <td> ${myBooks[i][col[j]].air_Logo}</td> </table>`;
} else {
tabcel.innerHTML = myBooks[i][col[j]];
}
}
// for (let j = 0; j < col.length; j++) {
// let tabCell = tr.insertCell(-1);
// tabCell.innerHTML = myBooks[i][col[j]];
// }
}
// Now, add the newly created table with json data, to a container.
const divShowData = document.getElementById('showData');
divShowData.innerHTML = "";
divShowData.appendChild(table);`
Since your object is not flat, you cannot truly render it all to table. You have to make a decision about the nested objects. Below I am simply using json.stringify to show those objects in a table cell. You should of course handle this according to your needs.
const data = [
{
"1": [
{
Time: "01:35 AM",
Location: "dhaka bangladesh",
"BUS Detail": {
air_Logo: "logo goes here",
air_Name: "Airbus"
},
busNo: "AK119",
arrTime: "05:40 AM",
"arrival Loc": "barisal"
}
]
}
];
const base = data[0]["1"];
const table = document.createElement("table");
const thead = table.createTHead();
const tbody = document.createElement("tbody");
table.append(tbody)
const headRow = thead.insertRow();
const headers = Object.keys(base[0]).forEach((head) => {
let cell = headRow.insertCell();
cell.textContent = head;
});
base.forEach((obj) => {
const row = tbody.insertRow();
const vals = Object.values(obj);
vals.forEach((v) => {
const cell = row.insertCell();
if (typeof(v) !== 'string') {
return cell.textContent = JSON.stringify(v);
}
cell.textContent = v
});
});
document.body.append(table)
Related
I am trying to add edit and delete button inside the column but the HTML table was created from JSON file and it is using for loop to print out the content. I don't know how to add extra button inside the column (green zone).
The button that plan to add will be replace in the 'undefined' col.
JSON code:
[
{
"userId":"ravjy",
"jobTitleName":"Developer",
"firstName":"Ran",
"lastName":"Vijay",
"preferredFullName":"Ran Vijay",
"employeeCode":"H9",
"region":"DL",
"phoneNumber":"34567689",
"emailAddress":"ranvijay.k.ran#gmail.com"
},
{
"userId":"mrvjy",
"jobTitleName":"Developer",
"firstName":"Murli",
"lastName":"Vijay",
"preferredFullName":"Murli Vijay",
"employeeCode":"A2","region":"MU",
"phoneNumber":"6543565",
"emailAddress":"murli#vijay.com"
}
]
<script>
fetch('employees.json')
.then(function (response) {
// The JSON data will arrive here
return response.json();
})
.then(function (data) {
appendData(data);
})
.catch(function (err) {
// If an error occured, you will catch it here
});
function appendData(data) {
//Extract Value for HTML HEADER.
var col=[];
for (var i = 0; i<data.length;i++){
for (var key in data[i]){
if (col.indexOf(key) === -1){
col.push(key);
}
}
}
//Add edit and delete header
col.push("Edit","Delete");
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < data.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = data[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("myData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
</script>
[1]: https://i.stack.imgur.com/YpoDi.png
[2]: https://i.stack.imgur.com/pu7SB.png
Solution
Javascript map will help to get that working
const data = [
{
userId: "ravjy",
jobTitleName: "Developer",
firstName: "Ran",
lastName: "Vijay",
preferredFullName: "Ran Vijay",
employeeCode: "H9",
region: "DL",
phoneNumber: "34567689",
emailAddress: "ranvijay.k.ran#gmail.com",
},
{
userId: "mrvjy",
jobTitleName: "Developer",
firstName: "Murli",
lastName: "Vijay",
preferredFullName: "Murli Vijay",
employeeCode: "A2",
region: "MU",
phoneNumber: "6543565",
emailAddress: "murli#vijay.com",
},
];
function test(type, id) {
alert(type + " " + id);
}
function appendData(data) {
//Extract Value for HTML HEADER.
data = data.map((item) => {
item.Edit_Delete = `<Button type="button" onclick="test('Edit', '${item.userId}')">${item.userId}</Button>
<Button type="button" onclick="test('Delete', '${item.userId}')">${item.userId}</Button>`;
return item;
});
const col = [];
for (let i = 0; i < data.length; i++) {
for (let key in data[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
//Add edit and delete header
// col.push("Edit","Delete");
// CREATE DYNAMIC TABLE.
const table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
let tr = table.insertRow(-1); // TABLE ROW.
for (let i = 0; i < col.length; i++) {
const th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (let i = 0; i < data.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
const tabCell = tr.insertCell(-1);
tabCell.innerHTML = data[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
const divContainer = document.getElementById("myData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
appendData(data);
<!DOCTYPE html>
<html>
<body>
<div id ="myData"></div>
</body>
</html>
I am building a dynamic table from an array of objects. Each row corresponds to one object, and each cell in that row corresponds to the value of one property for the object. All the objects have the same list of properties.
What I want to do is to add the keys as classes to the generated table cells, in order to add a switch to hide/show columns to toggle VAT.
Here is what my array looks like
let array = [
{
category: "Category",
product: "Product",
withVAT: "Price including VAT",
withoutVAT: "Price excluding VAT",
},
{
category: "Rouges",
product: "Chevigny Vaucluse",
withVAT: "4,40 €",
withoutVAT: "3,64 €",
},
{
category: "Rouges",
product: "Terra Quantum C.Rhône 2018 BIO",
withVAT: "9,30 €",
withoutVAT: "7,69 €",
},
...
]
And here is my dynamically generated table in JS :
document.onload(generateDynamicTable());
function generateDynamicTable() {
if (array.length > 0) {
// Table style
let table = document.createElement("table");
// Retrieve column header
let columns = [];
for (i = 0; i < array.length; i++) {
for (key in array[i]) {
if (columns.indexOf(key) === -1) {
columns.push(key);
}
}
}
// TABLE HEAD
// Create table head
let tableHead = document.createElement("thead");
// Create row for table head
let tableHeadRow = document.createElement("tr");
// Create cells for table head
for (i = 0; i < columns.length; i++) {
let tableHeadCell = document.createElement("th");
tableHeadCell if (array.length > 0.innerHTML = columns[i];
tableHeadRow.appendChild(tableHeadCell);
}
// TABLE BODY
// Create table body
let tableBody = document.createElement("tbody");
// Create rows for each object in the array
for (i = 0; i < array.length; i++) {
let tableRow = document.createElement("tr");
// Create cells for each row
for (j = 0; j < columns.length; j++) {
let tableCell = document.createElement("td");
tableCell.innerHTML = array[i][columns[j]];
tableRow.appendChild(tableCell);
}
tableBody.appendChild(tableRow);
}
table.appendChild(tableBody);
// Add table to a container
document.getElementById("dynamicTable").innerHTML = "";
document.getElementById("dynamicTable").appendChild(table);
}
}
These 2 lines worked :
// create an array with the keys of the properties for the object "array[i]"
let keys = Object.keys(array[i]);
// add the property key to the table cell's classes
tableCell.classList.add(keys[j]);
They have to be added here :
// Create cells for each row
for (j = 0; j < columns.length; j++) {
let tableCell = document.createElement("td");
tableCell.innerHTML = array[i][columns[j]];
let keys = Object.keys(array[i]);
tableCell.classList.add(keys[j]);
tableRow.appendChild(tableCell);
}
Create a div in html
<div id="DynamicTable"></div>
Pass the List of Objects u have in this function.
let yourList = [{....}];
this.createtable(yourList,"DynamicTable");
createtable(list: any,id:any) {
let headers = Object.keys(list[0])
let table = '<table><thead><tr>'
headers.forEach((header:any)=>{
table = table+ `<th>${header}</th>`
})
table = table + `</tr></thead>`;
table = table + `<tbody>`;
list.forEach((data:any) => {
table = table + `<tr>`
headers.forEach((header:any)=>{
table = table + `<td>${data[header]}</td>`;
})
table = table + `</tr>`
});
table = table + `</tbody></table>`
let DynamicTable: any = document.getElementById(id)
DynamicTable.innerHTML = table;
}
For keys as Class name
table = table + `<td class="${header}">${data[header]}</td>`;
So I'm using https://calendarific.com api and am trying to make an "app" where you can click on your country and it returns the holidays based on the current month. It kinda works except when I click on one country and then another the previous countries result stays on the top and the new country's holidays get put to the bottom of the page.
How can I remove previous results when a new one is made?
Javascript (sorry if it's a bit messy):
countrySelect.addEventListener('click', function() {
// Api url
let url = `https://calendarific.com/api/v2/holidays?&api_key=a7167178ffb6d2d7d8d9c1e05d98eab926f595e9&country=${buttonValue}&year=2020`;
fetch(url)
.then(res => res.json())
.then(data => {
// Filters holiday's to the current month
var currentMonthHolidays = data.response.holidays.filter(holiday => {
var holidayDate = new Date(holiday.date.iso);
var holidayMonth = holidayDate.getMonth();
var date = new Date();
var currentMonth = date.getMonth();
return currentMonth === holidayMonth;
})
// Build holiday table
function buildTable(data){
let table = document.getElementById('resultTable');
let col = [];
// Get the index of the api titles
for (let i = 0; i < currentMonthHolidays.length; i++) {
for (let key in currentMonthHolidays[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
console.log(col)
}
//Create table header row using the extracted headers above.
let tr = table.insertRow(-1); // table row.
for (let i = 0; i < col.length; i++) {
let th = document.createElement("th"); // table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
// add json data to the table as rows.
for (let i = 0; i < currentMonthHolidays.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
let tabCell = tr.insertCell(-1);
tabCell.innerHTML = currentMonthHolidays[i][col[j]];
}
}
}
buildTable(currentMonthHolidays);
console.log(currentMonthHolidays);
//handles error
}, networkError => {
alert(networkError)
})
})
If you are only concerned about just getting new data on top,
in your code just add :
table.removeChild(table.tBodies[0]);
which becomes :-
countrySelect.addEventListener('click', function() {
// Api url
let url = `https://calendarific.com/api/v2/holidays?&api_key=a7167178ffb6d2d7d8d9c1e05d98eab926f595e9&country=${buttonValue}&year=2020`;
fetch(url)
.then(res => res.json())
.then(data => {
// Filters holiday's to the current month
var currentMonthHolidays = data.response.holidays.filter(holiday => {
var holidayDate = new Date(holiday.date.iso);
var holidayMonth = holidayDate.getMonth();
var date = new Date();
var currentMonth = date.getMonth();
return currentMonth === holidayMonth;
})
// Build holiday table
function buildTable(data){
let table = document.getElementById('resultTable');
let col = [];
// Get the index of the api titles
for (let i = 0; i < currentMonthHolidays.length; i++) {
for (let key in currentMonthHolidays[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
console.log(col)
}
//Create table header row using the extracted headers above.
let tr = table.insertRow(-1); // table row.
for (let i = 0; i < col.length; i++) {
let th = document.createElement("th"); // table header.
th.innerHTML = col[i];
tr.appendChild(th);
}
/*
since all <tr> are wrapped inside <tbody>, so just remove the old one and you are good to go
*/
table.removeChild(table.tBodies[0]);
// add json data to the table as rows.
for (let i = 0; i < currentMonthHolidays.length; i++) {
tr = table.insertRow(-1);
for (let j = 0; j < col.length; j++) {
let tabCell = tr.insertCell(-1);
tabCell.innerHTML = currentMonthHolidays[i][col[j]];
}
}
}
buildTable(currentMonthHolidays);
console.log(currentMonthHolidays);
//handles error
}, networkError => {
alert(networkError)
})
})
I am currently using:
function searchNotes() {
const url = "http://localhost:2609/api/notes"
$.ajax({
url: url,
type: 'GET',
success: function (notesList) {
console.log(notesList)
// EXTRACT VALUE FOR HTML HEADER.
var col = [];
for (var i = 0; i < notesList.length; i++) {
for (var key in notesList[i]) {
if (col.indexOf(key) === -1 && (key === 'title' || key === 'content' || key == 'category' || key == 'categoryId')) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < notesList.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = notesList[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("listNotes");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
});
}
to create a html table using jquery. The table looks like this:
I want to filter the table by categoryId, as chosen in the dropdown at the top, then I want to remove the categoryId column. Any ideas how I could achieve this?
You need to use .sort() on the notesList object, something like this:
notesList.sort(function(a, b) {
return a.categoryId - b.categoryId;
});
Put it before appending the values to the html.
To 'remove' the categoryId column is very simple: Just remove the followingen bit from the if statement:
|| key == 'categoryId'
So your end result is something like this:
function searchNotes() {
const url = "http://localhost:2609/api/notes"
$.ajax({
url: url,
type: 'GET',
success: function (notesList) {
notesList.sort(function(a, b) {
return a.categoryId - b.categoryId;
});
// EXTRACT VALUE FOR HTML HEADER.
var col = [];
for (var i = 0; i < notesList.length; i++) {
for (var key in notesList[i]) {
if (col.indexOf(key) === -1 && (key === 'title' || key === 'content' || key == 'category')) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < notesList.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = notesList[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("listNotes");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
});
}
i have table like this
there are textboxes in table cell
im trying to convert this table to json object using
var InvoiceData = {};
InvoiceData = $('#invoiceDetailTbl').tableToJSON();
but values in text boxes not added to json object
function tableToJson(table) {
var data = [];
// first row needs to be headers
var headers = [];
for (var i=0; i<table.rows[0].cells.length; i++) {
headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
}
// go through cells
for (var i=1; i<table.rows.length; i++) {
var tableRow = table.rows[i];
var rowData = {};
for (var j=0; j<tableRow.cells.length; j++) {
rowData[ headers[j] ] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
return data;
}
i have found the solution, i'll done it manually
var table = document.getElementById('invoiceDetailTbl');
var tableRowCount = $("#invoiceDetailTbl > tbody > tr").length;
for (var i = 1; i <= tableRowCount; i++) {
var obj = {
Inv_Date: table.rows.item(i).cells[0].innerText,
Bill_No: table.rows.item(i).cells[1].innerText,
Net_Amt: table.rows.item(i).cells[2].innerText,
Paid_Amt: table.rows.item(i).cells[3].innerText,
Pay_Dis: $(table.rows.item(i).cells[4]).find('input').val(),
Paying_Amt: $(table.rows.item(i).cells[5]).find('input').val(),
Balance: table.rows.item(i).cells[6].innerText,
};
InvoiceData.push(obj);
}