I need t ogenerate an HTML table from a json file. The is loading OK, I can see the values in console.log, but I don't get how to pass these values in the other function (generate table function)
Here's my code:
<!DOCTYPE html>
<html lang="fr-CA" dir="ltr">
<head>
<meta charset="utf-8">
<title>Tableau de l'inventaire - API JSON</title>
</head>
<body>
<h2>Voitures en inventaire</h2>
<table id="myTable">
<thead>
<tr>
<th>No Stock</th>
<th>Marque</th>
<th>Modèle</th>
<th>Année</th>
</tr>
</thead>
</table>
<button type="button" onclick="loadTable()">Charge Content</button>
<script type="text/javascript">
// Loading json file = OK
function loadXMLDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// JSON.parse(this.responseText);
var i = JSON.parse(this.responseText);
// var x = document.getElementById("myTable").innerHTML = this.responseText
// console.log(jsonObj);
}
};
xhttp.open("GET", "voituresRecords.json", true);
xhttp.send();
}
// Generate table from json data = Not working
function loadTable(loadXMLDoc) {
var x = document.getElementById('myTable');
for(var i = 1; i < array.length; i++) {
var newRow = table.insertRow(table.length);
for(var j = 0; j < array[i].length; j++) {
var cell = newRow.insertCell(j);
cell.innerHTML = array[i][j];
}
}
}
</script>
</body>
</html>
And here's the json data from file:
[{"no_stock":"AC5678","marque":"Hyundai","modele":"Accent","annee":"2006"},
{"no_stock":"EL5320","marque":"Hyundai","modele":"Elantra","annee":"2018"},
{"no_stock":"KO4301","marque":"Hyundai","modele":"Kona","annee":"2018"},
{"no_stock":"TO4210","marque":"Hyundai","modele":"Tucson","annee":"2017"}]
Thanks for any help!
could be very more easy with a fetch : https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
Your code should that way
<h2>Voitures en inventaire</h2>
<table id="myTable">
<thead>
<tr>
<th>No Stock</th>
<th>Marque</th>
<th>Modèle</th>
<th>Année</th>
</tr>
</thead>
<tbody></tbody>
</table>
<button type="button" onclick="loadTable()">Charge Content</button>
const myTableBody = document.querySelector('#myTable tbody')
function loadTable() {
fetch('voituresRecords.json')
.then(resp => resp.json())
.then(data => {
data.forEach( info=>{
let newRow = myTableBody.insertRow()
newRow.insertCell().textContent = info.no_stock
newRow.insertCell().textContent = info.marque
newRow.insertCell().textContent = info.modele
newRow.insertCell().textContent = info.annee
})
})
.catch(error => console.error(error))
}
Related
I have a table (check screenshot) where I can generate rows and the second column will contain a number from a text field. I want to be able to grab that number from a generated cell and perform calculations with it. I am not entirely sure how to target the cell that gets generated given I can generate X amount of rows. The principle for this table is to generate numbers from a text field and then press a button and the third column will display a sum of all previous second column values. The execution will start after a button is pressed which I will add later
var counter = 1;
var pNum = 0;
var i;
//Target elements
let btnAdd = document.getElementById('btn');
let testBtn = document.getElementById('test');
let table = document.getElementById('table1');
let bTimeInput = document.querySelector('#bTime')
let bValue = document.querySelector('bCell');
//check for empty value
function checkForEmpty(input) {
if(input.value == null || input.value == undefined || input.value.length == 0) {
return true;
}
return false;
}
btnAdd.addEventListener('click', () => {
if(checkForEmpty(bTimeInput)) {
alert('Enter a number')
} else {
counter++;
pNum++;
let bTime = bTimeInput.value;
let wTime = 'dummyValue';
let taTime = 0;
let template = `
<tr>
<td>${pNum}</td>
<td>${bTime}</td>
<td>${wTime}</td>
</tr>`;
table.innerHTML += template;
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>FCFS CPU Scheduling Algorithm</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div id="data">
<input type="number" id="bTime" placeholder="enter burst time">
<button id="btn">Add process</button>
</div>
<table id="table1">
<tr>
<th>P#</th>
<th id="bCell">burst time</th>
<th>wait time</th>
<th>t/a time</th>
</tr>
</table>
</div>
<script src="algorithm.js"></script>
</body>
</html>
So I added some class and row pointers to help out. see what you think.
var counter = 0;
var pNum = 0;
var i;
//Target elements
let btnAdd = document.getElementById('btn');
let testBtn = document.getElementById('test');
let table = document.getElementById('table1');
let bTimeInput = document.querySelector('#bTime')
let bValue = document.querySelector('bCell');
//check for empty value
function checkForEmpty(input) {
if(input.value == null || input.value == undefined || input.value.length == 0) {
return true;
}
return false;
}
const getTotalTime = (bTime, counter) => {
if (counter === 1) return bTime;
const { innerText: pTime } = document.querySelector(`tr.row${counter-1} td.col4`);
return parseInt(bTime, 10) + parseInt(pTime, 10);
};
btnAdd.addEventListener('click', () => {
if(checkForEmpty(bTimeInput)) {
alert('Enter a number')
} else {
counter++;
pNum++;
let bTime = bTimeInput.value;
let wTime = 'dummyValue';
let taTime = 0;
let template = `
<tr class="row${counter}">
<td class="col1">${pNum}</td>
<td class="col2">${bTime}</td>
<td class="col3">${wTime}</td>
<td class="col4">${getTotalTime(bTime, counter)}</td>
</tr>`;
table.innerHTML += template;
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>FCFS CPU Scheduling Algorithm</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div id="data">
<input type="number" id="bTime" placeholder="enter burst time">
<button id="btn">Add process</button>
</div>
<table id="table1">
<tr>
<th>P#</th>
<th id="bCell">burst time</th>
<th>wait time</th>
<th>t/a time</th>
</tr>
</table>
</div>
<script src="algorithm.js"></script>
</body>
</html>
Here is a version that takes on board with Chris G mentions about seperation.
var counter = 0;
var pNum = 0;
var i;
const data = {
points: []
};
const headerTemplate = () => `
<tr>
<th>P#</th>
<th id="bCell">burst time</th>
<th>wait time</th>
<th>t/a time</th>
</tr>
`;
const rowTemplate = ({id, bTime, wTime, tTime}) => `
<tr>
<td>${id}</td>
<td>${bTime}</td>
<td>${wTime}</td>
<td>${tTime}</td>
</tr>
`;
//Target elements
let btnAdd = document.getElementById('btn');
let testBtn = document.getElementById('test');
let table = document.getElementById('table1');
let bTimeInput = document.querySelector('#bTime')
let bValue = document.querySelector('bCell');
//check for empty value
function checkForEmpty(input) {
if(input.value == null || input.value == undefined || input.value.length == 0) {
return true;
}
return false;
}
const getTotalTime = (bTime) => {
if (data.points.length === 0) return bTime;
return bTime + data.points[data.points.length-1].tTime;
};
const drawTable = () => data.points.map(point => rowTemplate(point)).join('');
btnAdd.addEventListener('click', () => {
if(checkForEmpty(bTimeInput)) {
alert('Enter a number')
} else {
counter ++;
const bTime = parseInt(bTimeInput.value);
const newDataPoint = {
id: counter,
bTime,
wTime: 'dummyValue',
tTime: getTotalTime(bTime)
};
data.points.push(newDataPoint);
table.innerHTML = headerTemplate() + drawTable(data);
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>FCFS CPU Scheduling Algorithm</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div id="data">
<input type="number" id="bTime" placeholder="enter burst time">
<button id="btn">Add process</button>
</div>
<table id="table1">
</table>
</div>
<script src="algorithm.js"></script>
</body>
</html>
The exact answer to your problem cannot be given without code snippets but here is an approach which I thought of:
You can use the
const cells=document.querySelectorAll('td')
to get a node list of all the elements and then target specific cells by indexing this list. Then you can extract value from those node elements by
cells[index].innerText
or
cells[index].innerHTML
and perform operations on it.
var counter = 1;
var pNum = 0;
var i;
//Target elements
let btnAdd = document.getElementById('btn');
let testBtn = document.getElementById('test');
let table = document.getElementById('table1');
let bTimeInput = document.querySelector('#bTime')
let bValue = document.querySelector('bCell');
//check for empty value
function checkForEmpty(input) {
if(input.value == null || input.value == undefined || input.value.length == 0) {
return true;
}
return false;
}
var x0=[]//array for saving
btnAdd.addEventListener('click', () => {
if(checkForEmpty(bTimeInput)) {
alert('Enter a number')
} else {
counter++;
pNum++;
let bTime = bTimeInput.value;
let wTime = 'dummyValue';
let taTime = 0;
//extremely long but successful traceable tags begin
var x1=document.createElement('tr')
table.appendChild(x1)//parent element in proper place
//now to create children
var x2=document.createElement('td')
var x3=document.createElement('td')
var x4=document.createElement('td')
//now to apply data to children
x2.innerText=pNum
x3.innerText=bTime
x4.innerText=wTime
//now to deploy the children
x1.appendChild(x2)
x1.appendChild(x3)
x1.appendChild(x4)
//extremely long but successful traceable tags end
//now to place in array
x0.push({x1:x1,x2:x2,x3:x3,x4:x4})
console.log(x0[x0.length-1])
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>FCFS CPU Scheduling Algorithm</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div id="data">
<input type="number" id="bTime" placeholder="enter burst time">
<button id="btn">Add process</button>
</div>
<table id="table1">
<tr>
<th>P#</th>
<th id="bCell">burst time</th>
<th>wait time</th>
<th>t/a time</th>
</tr>
</table>
</div>
<script src="algorithm.js"></script>
</body>
</html>
javascript beginner here, trying to code and learn.
I have a table filled with data (fetch from url) and that data is
{
"france": "paris",
"finland": "helsinki",
"sweden": "stockholm",
"tajikistan": "dushanbe",
"uzbekistan ": "toshkent",
"china": "peking",
"dole": {
"Key": "fhd699f"
}
}
and under the table I have a select box (the data of it also fetched from url) its data is this
[
{"nimi": "tili","id": "48385","somewhere": "nassau","somewhere2": "bamako","somewhere3": "rabat","somewhere4": "baku"},
{"nimi": "tili","id": "789642","somewhere": "windhoek","somewhere2": "podgorica","somewhere3": "niamey","somewhere4": "islamabad"}
]
i want to replace the table data with the selected data ( i mean everything) even table's <th> also, for example table's <th> is 'france' and value is 'paris' but after replace table's <th> should be 'nimi' and value 'tili' according to select box data.
here is my code (as you can see 'tajikistan','uzbekistan','china' for some reason not going to their places in table):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
<style>
</style>
</head>
<body>
<div class="container">
<table class="table ">
<thead>
<tr>
<th class="table-success">france</th>
<th class="table-success">finland</th>
<th class="table-success">sweden</th>
</tr>
</thead>
<tbody id="tiedot">
</tbody>
<thead>
<tr>
<th class="table-success">tajikistan</th>
<th class="table-success">uzbekistan</th>
<th class="table-success">china</th>
</tr>
</thead>
<tbody id="tiedot2">
</tbody>
</table>
<select id="valittu" name="name"></select>
</div>
<script>
fetch(
"https://tdejdjd***",
{
method: "GET",
headers: {
"x-api-key": "i****y"
}
}
)
.then((res) => {
res
.json()
.then((data) => {
tableupdating(data, ['france','finland','sweden','tajikistan','uzbekistan','china']);
})
.catch((err) => {
console.log("ERROR: " + err);
});
});
function tableupdating(data, values) {
const totable = document.getElementById("tiedot");
const totable2 = document.getElementById("tiedot2");
totable.innerHTML = "";
totable2.innerHTML = "";
var komb = "";
var komb2 = "";
komb += "<tr>";
komb2 += "<tr>";
values.forEach(value => {
komb += "<td>" + data[value] + "</td>";
})
values.forEach(value => {
komb2 += "<td>" + data[value] + "</td>";
})
totable.insertAdjacentHTML("beforeend", komb);
totable2.insertAdjacentHTML("beforeend", komb2);
}
let dataArray;
fetch(
"https://tdejdjd***",
{
method: "GET",
headers: {
"x-api-key": "i****y"
}
}
)
.then((res) => {
res.json().then((data) => {
dataArray = data;
updateSelect(data, ['nimi','id']);
});
});
function updateSelect(data, values) {
for (var i = 0; i < data.length; i++) {
var Valittu = document.getElementById("valittu");
var option = document.createElement("option");
values.forEach(value => {
option.textContent += data[i][value] + ' '
})
Valittu.appendChild(option);
}
}
document.getElementById("valittu").addEventListener("change", function (event) {
const chosenID = event.target.value.split(" ")[1];
const chosenData = dataArray.filter((data) => data.id === chosenID)[0];
tableupdating(chosenData, ['nimi', 'id', 'somewhere','somewhere2','somewhere3','somewhere4']);
});
</script>
</body>
</html>
as spoken in chat, here is new code, it is working but for some reason these three are in same line and not on their places : komb += "<td>"+tiedot.tajikistan+"</td>";
komb += "<td>"+tiedot.uzbekistan+"</td>";
komb += "<td>"+tiedot.china+"</td></tr>";
code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
<style>
</style>
</head>
<body onload="fillTheBox();">
<div class="container">
<table class="table" id="myTable">
<thead>
<tr>
<th class="table-success">france</th>
<th class="table-success">finland</th>
<th class="table-success">sweden</th>
</tr>
</thead>
<tbody id="tiedot">
</tbody>
<thead>
<tr>
<th class="table-success">tajikistan</th>
<th class="table-success">uzbekistan</th>
<th class="table-success">china</th>
</tr>
</thead>
</table>
<select id="valittu" name="name" onchange="changed()"></select>
</div>
<script>
fetch("https://qj",
{
method: "GET",
headers: {
"x-api-key": ""
}
}
).then(res =>{
res.json().then(tiedot => {
console.log(tiedot);
var komb ="";
komb +="<tr>";
komb += "<td>"+tiedot.france+"</td>";
komb += "<td>"+tiedot.finland+"</td>";
komb += "<td>"+tiedot.sweden+"</td>";
komb += "<td>"+tiedot.tajikistan+"</td>";
komb += "<td>"+tiedot.uzbekistan+"</td>";
komb += "<td>"+tiedot.china+"</td></tr>";
document.getElementById("tiedot").insertAdjacentHTML("beforeend", komb );
}
)
})
var dataArray = [
{ "nimi": "tili", "id": "48385", "somewhere": "nassau", "somewhere2": "bamako", "somewhere3": "rabat", "somewhere4": "baku" },
{ "nimi": "tili", "id": "789642", "somewhere": "windhoek", "somewhere2": "podgorica", "somewhere3": "niamey", "somewhere4": "islamabad" }
]
function fillTheBox() {
var selectBox = document.getElementById("valittu");
var option = document.createElement("option");
option.value = dataArray[0];
option.text = dataArray[0].nimi+' '+dataArray[0].id;
selectBox.add(option);
var option1 = document.createElement("option");
option1.value = dataArray[1];
option1.text = dataArray[1].id;
selectBox.add(option1);
}
function changed() {
var e = document.getElementById("valittu");
var selectedObjectID = e.options[e.selectedIndex].text;
chosenData = dataArray.filter((data) => data.id === selectedObjectID)[0];
var myTable = document.getElementById("myTable");
myTable.innerHTML = "";
generateTable(myTable, chosenData);
}
function generateTable(table, data) {
let row1 = table.insertRow();
row1.className = "table-success";
let row2 = table.insertRow();
let row3 = table.insertRow();
row3.className = "table-success";
let row4 = table.insertRow();
var counter = 1;
for (key in data) {
if (counter<=3) {
let cell = row1.insertCell();
let text = document.createTextNode(key);
cell.appendChild(text);
let cell2 = row2.insertCell();
let text2 = document.createTextNode(data[key]);
cell2.appendChild(text2);
} else {
let cell = row3.insertCell();
let text = document.createTextNode(key);
cell.appendChild(text);
let cell2 = row4.insertCell();
let text2 = document.createTextNode(data[key]);
cell2.appendChild(text2);
}
counter++;
}
}
</script>
</body>
</html>
I created a basic demo to show the logic. Firs of all give an id to your table. And create a onChange event for your select box. In your event function edit your table content with innerHTML property. Just focus on change() and generateTable() functions in my code
<body onload="fillTheBox();">
<div class="container">
<table class="table" id="myTable">
<thead>
<tr>
<th class="table-success">france</th>
<th class="table-success">finland</th>
<th class="table-success">sweden</th>
</tr>
</thead>
<tbody id="tiedot">
</tbody>
<thead>
<tr>
<th class="table-success">tajikistan</th>
<th class="table-success">uzbekistan</th>
<th class="table-success">china</th>
</tr>
</thead>
</table>
<select id="valittu" name="name" onchange="changed()"></select>
</div>
<script>
var dataArray = [
{ "nimi": "tili", "id": "48385", "somewhere": "nassau", "somewhere2": "bamako", "somewhere3": "rabat", "somewhere4": "baku" },
{ "nimi": "tili", "id": "789642", "somewhere": "windhoek", "somewhere2": "podgorica", "somewhere3": "niamey", "somewhere4": "islamabad" }
]
function fillTheBox() {
var selectBox = document.getElementById("valittu");
var option = document.createElement("option");
option.value = dataArray[0];
option.text = dataArray[0].id;
selectBox.add(option);
var option1 = document.createElement("option");
option1.value = dataArray[1];
option1.text = dataArray[1].id;
selectBox.add(option1);
}
function changed() {
var e = document.getElementById("valittu");
var selectedObjectID = e.options[e.selectedIndex].text;
chosenData = dataArray.filter((data) => data.id === selectedObjectID)[0];
var myTable = document.getElementById("myTable");
myTable.innerHTML = "";
generateTable(myTable, chosenData);
}
function generateTable(table, data) {
let row1 = table.insertRow();
row1.className = "table-success";
let row2 = table.insertRow();
row2.className = "table-success";
let row3 = table.insertRow();
row3.className = "table-success";
let row4 = table.insertRow();
row4.className = "table-success";
var counter = 1;
for (key in data) {
if (counter<=3) {
let cell = row1.insertCell();
let text = document.createTextNode(key);
cell.appendChild(text);
let cell2 = row2.insertCell();
let text2 = document.createTextNode(data[key]);
cell2.appendChild(text2);
} else {
let cell = row3.insertCell();
let text = document.createTextNode(key);
cell.appendChild(text);
let cell2 = row4.insertCell();
let text2 = document.createTextNode(data[key]);
cell2.appendChild(text2);
}
counter++;
}
}
</script>
</body>
</html>
UPDATE:
To separate the fields mentioned in question add a <tr> element between them.
komb +="<tr>";
komb += "<td>"+tiedot.france+"</td>";
komb += "<td>"+tiedot.finland+"</td>";
komb += "<td>"+tiedot.sweden+"</td>";
komb +="</tr><tr>";
komb += "<td>"+tiedot.tajikistan+"</td>";
komb += "<td>"+tiedot.uzbekistan+"</td>";
komb += "<td>"+tiedot.china+"</td></tr>";
Currently, I have a script that searches column 1 of a locally-stored table, and returns the result from column 2 from the same row. Based on that result, it logs something to the console.
Here it is action. It searches the table for "dragon" in column 1, returns "2" from Column 2, then the script logs "The result is two." to the console.
var username = 'dragon'
const searchDataSetByKey = (dataSet, key) => {
return dataSet.find((data) => data[0] === key)
}
document.addEventListener('DOMContentLoaded', () => {
var tableToArray = Array
.from(document.querySelectorAll('tr'))
.reduce((_tableToArray, tableRow, tableRowIndex) => {
if(tableRowIndex !== 0) {
var tableData = tableRow.querySelectorAll('td')
var key = tableData.item(0).innerText
var value = tableData.item(1).innerText
_tableToArray.push([key, value])
}
return _tableToArray
}, [])
var searchString = searchDataSetByKey(tableToArray,username).toString()
var oneSearch = searchString.indexOf("1")
var twoSearch = searchString.indexOf("2")
var threeSearch = searchString.indexOf("3")
if (oneSearch >= 0) {
console.log('The result is one!');}
else if (twoSearch >= 0) {
console.log('This result is two.');}
else if (threeSearch >= 0) {
console.log('The answer is three! :)');}
})
<html>
<script src="script.js"></script>
<body>
<table>
<tr>
<th>Username</th>
<th>1/2/3</th>
</tr>
<tr>
<td>wisp</td>
<td>1</td>
</tr>
<tr>
<td>husky</td>
<td>2</td>
</tr>
<tr>
<td>dragon</td>
<td>2</td>
</tr>
<tr>
<td>woop</td>
<td>3</td>
</tr>
<tr>
<td>e6</td>
<td>1</td>
</tr>
</table>
</body>
</html>
This is great for locally-stored tables. The issue is, I'd like to get the same result from a Google Sheet. I've found a way to store the info from a Google Sheet into a HTML table using AJAX. The code for this can be seen here:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
var spData = null;
function doData(json) {
spData = json.feed.entry;
}
function drawCell(tr, val) {
var td = $("<td/>");
tr.append(td);
td.append(val);
return td;
}
function drawRow(table, rowData) {
if (rowData == null) return null;
if (rowData.length == 0) return null;
var tr = $("<tr/>");
table.append(tr);
for(var c=0; c<rowData.length; c++) {
drawCell(tr, rowData[c]);
}
return tr;
}
function drawTable(parent) {
var table = $("<table/>");
parent.append(table);
return table;
}
function readData(parent) {
var data = spData;
var table = drawTable(parent);
var rowData = [];
for(var r=0; r<data.length; r++) {
var cell = data[r]["gs$cell"];
var val = cell["$t"];
if (cell.col == 1) {
drawRow(table, rowData);
rowData = [];
}
rowData.push(val);
}
drawRow(table, rowData);
}
$(document).ready(function(){
readData($("#data"));
});
</script>
<script src="https://spreadsheets.google.com/feeds/cells/1P9DhWOHcl14Y7-P5wCxTm-sUceckGquPoOobO75XhvM/1/public/values?alt=json-in-script&callback=doData"></script>
<style type="text/css" media="print">
form {display: none;}
</style>
</head>
<body>
<div id="data"/>
</body>
</html>
I was wondering if there was any way of achieving what was done in the local HTML table, with this AJAX imported HTML table?
Thanks!
It's exactly the same work that you need to do, albeit at a different time - i.e in response to a different event. Do it straight after you've loaded the table, instead of straight after you've received the DOMContentLoaded event from the document. Here's an alternate way to go looking.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
var spData = null;
function doData(json) {
spData = json.feed.entry;
}
function drawCell(tr, val) {
var td = $("<td/>");
tr.append(td);
td.append(val);
return td;
}
function drawRow(table, rowData) {
if (rowData == null) return null;
if (rowData.length == 0) return null;
var tr = $("<tr/>");
table.append(tr);
for(var c=0; c<rowData.length; c++) {
drawCell(tr, rowData[c]);
}
return tr;
}
function drawTable(parent) {
var table = $("<table/>");
parent.append(table);
return table;
}
function readData(parent) {
var data = spData;
var table = drawTable(parent);
var rowData = [];
for(var r=0; r<data.length; r++) {
var cell = data[r]["gs$cell"];
var val = cell["$t"];
if (cell.col == 1) {
drawRow(table, rowData);
rowData = [];
}
rowData.push(val);
}
drawRow(table, rowData);
}
$(document).ready(function(){
readData($("#data"));
searchTable( 'dragon', document.querySelector('table') );
});
function searchTable(searchStr, target)
{
let rows = Array.from( target.querySelectorAll('tr') );
rows.forEach( (row,idx,col) => {
let firstCell = row.querySelector('td').textContent;
if (firstCell == searchStr)
{
let cell2 = row.querySelectorAll('td')[1].textContent;
console.log(`${searchStr} found in row ${idx}`);
console.log(`col 2 of row #${idx} is: ${cell2}`);
}
}
);
}
</script>
<script src="https://spreadsheets.google.com/feeds/cells/1P9DhWOHcl14Y7-P5wCxTm-sUceckGquPoOobO75XhvM/1/public/values?alt=json-in-script&callback=doData"></script>
<style type="text/css" media="print">
form {display: none;}
</style>
</head>
<body>
<div id="data"/>
</body>
</html>
I'v copied the child elements directly into my emp.json file and im able to list out the elements, but i don know how to run three nested loop to fetch the child elements.
I want Name, Limit & tax-type from details`
I'v tried with the child array...
index.html file
<body>
<ul id= "details"></ul>
<script>
` var dat = new XMLHttpRequest();`
`dat.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = JSON.parse(dat.responseText);
var details = response.details;
var output = ' ';`
`for(var i=0;i<details.length; i++){
output = output+'<li>' +details[i].name+ '</li>';
output = output+'<li>' +details[i].limit+ '</li>';
output = output+'<li>' +details[i].tax_type+ '</li>';
}
document.getElementById('details').innerHTML= output;
}
};
dat.open("GET", "emp.json", true);
dat.send();
</script>
</body>
</html>
It will be helpful if we can list these elements into table.
var responseData = `{
"status":"success",
"message":"Manage Tax Lists",
"data":[
{
"_id":{
"parent_sec_no":"form_vi_a",
"parent_name":"Chapter VI A",
"parent_order":1
},
"detail":[
{
"sec_no":"80C",
"sec_name":"Part-II Investment U/s Sec 80C can be made upto Rs. 1.5 Lac together",
"details":[
{
"id":11,
"name":"Housing. Loan [Principal Repayment]",
"limit":150000,
"tax_type":11
}
]
}
]
}
]
}`;
function getDetails(textData) {
var jsonData = JSON.parse(textData);
var data = jsonData.data;
for (i = 0; i < data.length; i++)
for (j = 0; j < data[i].detail.length; j++)
for (k = 0; k < data[i].detail[j].details.length; k++) {
console.log('name:' + data[i].detail[j].details[k].name + ' - limit:' + data[i].detail[j].details[k].limit + ' - tax_Type:' + data[i].detail[j].details[k].tax_type);
}
}
getDetails(responseData);
Use the below code write the json to a table
<body>
<table>
<thead>
<tr>
<th>name</th>
<th>limit</th>
<th>tax-type</th>
</tr>
</thead>
<tbody id="details">
</tbody>
</table>
<script>
var dat = new XMLHttpRequest();
dat.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var data = jsonData.data;
var response = JSON.parse(dat.responseText);
var data= response.data;
var output = ''
data.forEach(a=>{
a.detail.forEach(b=>{
b.details.forReach(val =>{
ouptut += `<tr><td>${val.name}</td><td>${val.limit}</td><td>${val.tax_type}</td></tr>`;
)}
})
})
document.getElementById('details').innerHTML= output;
}
};
dat.open("GET", "emp.json", true);
dat.send();
</script>
</body>
</html>
I've been messing with manipulating HTML tables for the past few weeks and I've come across a problem I am not sure how to fix. So the collection of rows for a table can be iterated over like an array, but if you've switched out the rows a lot, won't the IDs be mixed and doesn't the browser rely on the IDs as the way to iterate over the row objects? I'm running into a problem (probably due to a lack of understanding) where the rows eventually stop moving or one row gets duplicated on top of another. Should I somehow be updating the row's ID each time it is moved? Here is my source so far for this function.
function swap(rOne, rTwo, tblID) {
tblID.rows[rOne].setAttribute('style', 'background-color:#FFFFFF');
var tBody = tblID.children[0];
var rowOne;
var rowTwo;
if (rOne > rTwo) {
rowOne = rOne;
rowTwo = rTwo;
}
else {
rowOne = rTwo;
rowTwo = rOne;
}
var swapTempOne = tblID.rows[rowOne].cloneNode(true);
var swapTempTwo = tblID.rows[rowTwo].cloneNode(true);
hiddenTable.appendChild(swapTempOne);
hiddenTable.appendChild(swapTempTwo);
tblID.deleteRow(rowOne);
var rowOneInsert = tblID.insertRow(rowOne);
var rowOneCellZero = rowOneInsert.insertCell(0);
var rowOneCellOne = rowOneInsert.insertCell(1);
var rowOneCellTwo = rowOneInsert.insertCell(2);
var rowOneCellThree = rowOneInsert.insertCell(3);
rowOneCellZero.innerHTML = hiddenTable.rows[2].cells[0].innerHTML;
rowOneCellOne.innerHTML = hiddenTable.rows[2].cells[1].innerHTML;
rowOneCellTwo.innerHTML = hiddenTable.rows[2].cells[2].innerHTML;
rowOneCellThree.innerHTML = hiddenTable.rows[2].cells[3].innerHTML;
tblID.deleteRow(rowTwo);
var rowTwoInsert = tblID.insertRow(rowTwo);
var rowTwoCellZero = rowTwoInsert.insertCell(0);
var rowTwoCellOne = rowTwoInsert.insertCell(1);
var rowTwoCellTwo = rowTwoInsert.insertCell(2);
var rowTwoCellThree = rowTwoInsert.insertCell(3);
rowTwoCellZero.innerHTML = hiddenTable.rows[1].cells[0].innerHTML;
rowTwoCellOne.innerHTML = hiddenTable.rows[1].cells[1].innerHTML;
rowTwoCellTwo.innerHTML = hiddenTable.rows[1].cells[2].innerHTML;
rowTwoCellThree.innerHTML = hiddenTable.rows[1].cells[3].innerHTML;
tblID.rows[rowOne].setAttribute('onclick', 'chkThis(event, this)');
tblID.rows[rowTwo].setAttribute('onclick', 'chkThis(event, this)');
for (iHiddenDelete = 2; iHiddenDelete >= 1; iHiddenDelete--) {
hiddenTable.deleteRow(iHiddenDelete);
}
}
EDIT: Adding HTML for page and the function for moving between tables which I suspect is causing the issue.
<body>
<form>
<input value="0" type="text" id="cubesum" size="5"/>
<input value="0" type="text" id="wgtsum" size="5"/>
</form>
<form>
<table id="tblSource">
<thead>
<tr>
<th> </th>
<th>Order</th>
<th>Cube</th>
<th>Weight</th>
<th>Move</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<button type="button" onclick="move('tblSource','tblTarget')" style="width: 58px">To Trucks (Down)</button>
<button type="button" onclick="move('tblTarget', 'tblSource')" style="width: 58px">To Orders (Up)</button>
</form>
<form>
<table id="tblTarget">
<thead>
<tr>
<th> </th>
<th>Order</th>
<th>Cube</th>
<th>Weight</th>
<th>Move</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</form>
<table id="hiddenTable" style="display: none"> <!--this table is hidden! -->
<thead>
<tr>
<th> </th>
<th>Order</th>
<th>Cube</th>
<th>Weight</th>
<th>Move</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
</html>
FUNCTION STARTS HERE
function move(from, to) {
var frTbl = document.getElementById(from);
var toTbl = document.getElementById(to);
chkArray.length = 0;
cbsMove = frTbl.getElementsByTagName('input');
for (var oChk = 0; oChk < cbsMove.length; oChk++) {
if (cbsMove[oChk].type == 'checkbox') {
if (cbsMove[oChk].checked == true) {
var prntRow = cbsMove[oChk].parentNode.parentNode;
var prntRowIdx = prntRow.rowIndex;
chkArray.push(prntRowIdx);
cbsMove[oChk].checked = false;
}
}
}
for (iMove = chkArray.length -1; iMove >= 0; iMove--) {
var num = chkArray[iMove];
var row = frTbl.rows[num];
var cln = row.cloneNode(true);
toTbl.appendChild(cln);
frTbl.deleteRow(num);
}
sum();
}
So it turns out that my row cloning for moving between tables was causing malformed HTML where the rows would not longer be inside the table body tags. In addition, not trusting the browser to keep track of the button IDs and using the button IDs to setAttributes to the button also caused button ID overlap eventually. So, I got rid of the node cloning and did the row moving between tables the manual way and used innerHTML to add the function call inside the buttons. Upon further reflection, I've come to learn that some people actually make functions that handle ALL button clicks without calling them inside the button and route them to the proper function depending on the ID or other factors such as parent nodes of the button. Perhaps that is best. The main trick here is to STICK TO ONE METHOD. I was all over the place in how I manipulated the tables and it broke things. Here is the working source for those looking to do similar things.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<style type="text/css">
#selectSource {
width: 320px;
}
#selectTarget {
width: 320px;
}
table, th, td
{
border: 1px solid black;
}
</style>
<title>Loader</title>
<script>
var chkArray = [];
var data = [];
var tmpArray = [];
var iChk = 0;
var swap;
window.onload = function () {
var load = document.getElementById('selectSource')
loadFromAJAX();
}
function loadFromAJAX()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var rawData = xmlhttp.responseText;
data = JSON.parse(rawData);
for (iData = 0; iData < data.length; iData++) {
newRow = document.getElementById('tblSource').insertRow(iData + 1);
var dn = "dn" + (iData + 1);
var up = "up" + (iData + 1);
cel0 = newRow.insertCell(0);
cel1 = newRow.insertCell(1);
cel2 = newRow.insertCell(2);
cel3 = newRow.insertCell(3);
cel4 = newRow.insertCell(4);
cel0.innerHTML = "<input type='checkbox' name='chkbox'>";
cel1.innerHTML = data[iData].num;
cel2.innerHTML = data[iData].cube;
cel3.innerHTML = data[iData].wgt;
cel4.innerHTML = "<button type='button' onclick=moveUp(this)>up</button><button type='button' onclick=moveDn(this)>down</button>";
}
}
}
xmlhttp.open("POST","http://192.168.3.2/cgi-bin/rims50.cgi/json.p",true);
xmlhttp.send();
}
function moveUp(mvThisRow) {
var mvThisRowRow = mvThisRow.parentNode.parentNode;
var mvThisRowTbl = mvThisRowRow.parentNode.parentNode;
var mvThisRowIndex = mvThisRowRow.rowIndex;
var mvThisRowTblLngth = mvThisRowTbl.rows.length;
var mvFrRow = mvThisRowTbl.rows[mvThisRowIndex];
var mvToRow = mvThisRowIndex - 1;
var mvThisDn = "dn" + (mvToRow) + mvThisRowTbl;
var mvThisUp = "up" + (mvToRow) + mvThisRowTbl;
if (mvThisRowIndex - 1 !== 0) {
moveToRow = mvThisRowTbl.insertRow(mvToRow);
mvRowCel0 = moveToRow.insertCell(0);
mvRowCel1 = moveToRow.insertCell(1);
mvRowCel2 = moveToRow.insertCell(2);
mvRowCel3 = moveToRow.insertCell(3);
mvRowCel4 = moveToRow.insertCell(4);
mvRowCel0.innerHTML = "<input type='checkbox' name='chkbox'>";
mvRowCel1.innerHTML = mvFrRow.cells[1].innerHTML;
mvRowCel2.innerHTML = mvFrRow.cells[2].innerHTML;
mvRowCel3.innerHTML = mvFrRow.cells[3].innerHTML;
mvRowCel4.innerHTML = "<button type='button' onclick=moveUp(this)>up</button><button type='button' onclick=moveDn(this)>down</button>";
mvThisRowTbl.deleteRow(mvThisRowIndex +1);
}
else {
alert("You can't move the top row 'up' try moving it 'down'.");
}
}
function moveDn(mvThisRow) {
var mvThisRowRow = mvThisRow.parentNode.parentNode;
var mvThisRowTbl = mvThisRowRow.parentNode.parentNode;
var mvThisRowTblLngth = mvThisRowTbl.rows.length;
var mvThisRowIndex = mvThisRowRow.rowIndex;
if (mvThisRowIndex + 1 !== mvThisRowTblLngth) {
var mvFrRow = mvThisRowTbl.rows[mvThisRowIndex];
var mvToRow = mvThisRowIndex + 2;
var moveToRow = mvThisRowTbl.insertRow(mvToRow);
var dn = "dn" + (mvToRow) + mvThisRowTbl;
var up = "up" + (mvToRow) + mvThisRowTbl;
mvRowCel0 = moveToRow.insertCell(0);
mvRowCel1 = moveToRow.insertCell(1);
mvRowCel2 = moveToRow.insertCell(2);
mvRowCel3 = moveToRow.insertCell(3);
mvRowCel4 = moveToRow.insertCell(4);
mvRowCel0.innerHTML = "<input type='checkbox' name='chkbox'>";
mvRowCel1.innerHTML = mvFrRow.cells[1].innerHTML;
mvRowCel2.innerHTML = mvFrRow.cells[2].innerHTML;
mvRowCel3.innerHTML = mvFrRow.cells[3].innerHTML;
mvRowCel4.innerHTML = "<button type='button' onclick=moveUp(this)>up</button><button type='button' onclick=moveDn(this)>down</button>";
mvThisRowTbl.deleteRow(mvThisRowIndex);
}
else {
alert("You can't move the bottom row 'down' try moving it 'up'.");
}
}
function sum() {
var trgTbl = document.getElementById('tblTarget');
var tblLength = trgTbl.rows.length;
var sumAddCube = 0;
var sumAddWgt = 0;
document.getElementById("cubesum").setAttribute("value", sumAddCube);
document.getElementById("wgtsum").setAttribute("value", sumAddWgt);
for (iSum = 1; iSum < tblLength; iSum++) {
celCubeNum = trgTbl.rows[iSum].cells[2].innerHTML;
celWgtNum = trgTbl.rows[iSum].cells[3].innerHTML;
sumAddCube = parseInt(sumAddCube) + parseInt(celCubeNum);
sumAddWgt = parseInt(sumAddWgt) + parseInt(celWgtNum);
}
document.getElementById("cubesum").setAttribute("value", sumAddCube);
document.getElementById("wgtsum").setAttribute("value", sumAddWgt);
}
function move(from, to) {
var frTbl = document.getElementById(from);
var toTbl = document.getElementById(to);
chkArray.length = 0;
cbsMove = frTbl.getElementsByTagName('input');
for (var oChk = 0; oChk < cbsMove.length; oChk++) {
if (cbsMove[oChk].type == 'checkbox') {
if (cbsMove[oChk].checked == true) {
var prntRow = cbsMove[oChk].parentNode.parentNode;
var prntRowIdx = prntRow.rowIndex;
chkArray.push(prntRowIdx);
cbsMove[oChk].checked = false;
}
}
}
for (iMove = chkArray.length -1; iMove >= 0; iMove--) {
var num = chkArray[iMove];
var row = frTbl.rows[num];
var toRow = toTbl.rows.length
moveRow = toTbl.insertRow(toRow);
var dn = "dn" + (toRow) + toTbl;
var up = "up" + (toRow) + toTbl;
mvCel0 = moveRow.insertCell(0);
mvCel1 = moveRow.insertCell(1);
mvCel2 = moveRow.insertCell(2);
mvCel3 = moveRow.insertCell(3);
mvCel4 = moveRow.insertCell(4);
mvCel0.innerHTML = "<input type='checkbox' name='chkbox'>";
mvCel1.innerHTML = row.cells[1].innerHTML;
mvCel2.innerHTML = row.cells[2].innerHTML;
mvCel3.innerHTML = row.cells[3].innerHTML;
mvCel4.innerHTML = "<button type='button' onclick=moveUp(this)>up</button><button type='button' onclick=moveDn(this)>down</button>";
frTbl.deleteRow(num);
}
sum();
}
</script>
</head>
<body>
<form>
<input value="0" type="text" id="cubesum" size="5"/>
<input value="0" type="text" id="wgtsum" size="5"/>
</form>
<form>
<table id="tblSource">
<thead>
<tr>
<th> </th>
<th>Order</th>
<th>Cube</th>
<th>Weight</th>
<th>Move</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<button type="button" onclick="move('tblSource','tblTarget')" style="width: 58px">To Trucks (Down)</button>
<button type="button" onclick="move('tblTarget', 'tblSource')" style="width: 58px">To Orders (Up)</button>
</form>
<form>
<table id="tblTarget">
<thead>
<tr>
<th> </th>
<th>Order</th>
<th>Cube</th>
<th>Weight</th>
<th>Move</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</form>
<table id="hiddenTable" style="display: none"> <!--this table is hidden! -->
<thead>
<tr>
<th> </th>
<th>Order</th>
<th>Cube</th>
<th>Weight</th>
<th>Move</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
</html>