Why is my insertRow method adding blank cells to my table? - javascript

I am trying to add the results from a fetch request into a new row in a table. However, When I run the function to do that, the first click adds a blank row instead of adding my desired data. Additionally, the data that I would have liked to add gets added the next time the function is ran. I have no idea what is wrong and I have tried so many things. I believe this problem is causing my other function called "total()" to return an error as the first cell is undefined instead of containing a value.
Here is my javascript:
document.getElementById('getFood').addEventListener('click', getFood);
document.getElementById('getFood').addEventListener('click', total);
/*function getText() {
$.ajax({
method: 'GET',
url:
'https://api.api-ninjas.com/v1/nutrition?query=' +
document.getElementById('foodInput'),
headers: { 'X-Api-Key': 'vrtwcc/pVgAr2o/a4dEyYA==hR1m7lLVdU4ho4hW' },
contentType: 'application/json',
success: function (result) {
console.log(result);
},
error: function ajaxError(jqXHR) {
console.error('Error: ', jqXHR.responseText);
},
});
}*/
/*function getFood(foodName) {
let xhr = new XMLHttpRequest();
xhr.open(
'get',
'https://api.api-ninjas.com/v1/nutrition?query=' + foodName,
true
);
xhr.send();
xhr.addEventListener('load', function () {
console.log(xhr.responseText);
});
}
getFood('fries');*/
function getFood() {
fetch(
'https://api.api-ninjas.com/v1/nutrition?query=' +
`${document.getElementById('foodInput').value}`,
{
method: 'GET',
headers: { 'X-Api-Key': 'vrtwcc/pVgAr2o/a4dEyYA==hR1m7lLVdU4ho4hW' },
contentType: 'application/json',
}
)
.then((res) => res.json())
.then((data) => {
foodQuery = data[0].name;
calorieQuery = `${data[0].calories} calories`;
});
let table = document
.getElementById('foodTable')
.getElementsByTagName('tbody')[0];
let row = table.insertRow(0);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
cell1.innerHTML = foodQuery;
cell2.innerHTML = calorieQuery;
// row.insertCell(0).innerHTML = foodQuery;
// row.insertCell(1).innerHTML = calorieQuery;
//document.getElementById('foodInput').value = '';
}
function total() {
let table = document.getElementById('foodTable');
let total = 0;
for (let i = 1; i < table.rows.length; i++) {
total += Number(table.rows[i].cells[2].innerText);
}
document.getElementById('tableTotal').value = total;
}
and here is my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script
src="https://code.jquery.com/jquery-3.6.3.js"
integrity="sha256-nQLuAZGRRcILA+6dMBOvcRh5Pe310sBpanc6+QBmyVM="
crossorigin="anonymous"
></script>
<link
rel="stylesheet"
href="node_modules/bootstrap/dist/css/bootstrap.css"
/>
<link rel="stylesheet" href="style.css" />
<title>Document</title>
</head>
<body>
<div class="container-fluid border border-primary">
<strong>Jason's Calorie Counter </strong><br />
<form>
<div class="form-group" id="">
<label>Food Selection</label>
<input
class="form-control"
id="foodInput"
placeholder="Enter food here"
/>
<small id="foodHelp" class="form-text text-muted"
>Nutrition data for each food item is scaled to 100g unless a
quantity is specified
</small>
<br />
<button type="button" class="btn btn-primary" id="getFood">
Get Food
</button>
</div>
</form>
</div>
<table class="table table-bordered" id="foodTable">
<thead>
<tr>
<th scope="col">Food</th>
<th scope="col">Calories</th>
</tr>
</thead>
<tbody>
<tr id="rows1">
<td colspan="2" id="tableTotal">Total</td>
</tr>
</tbody>
</table>
<script
src="https://cdn.jsdelivr.net/npm/popper.js#1.14.7/dist/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"
></script>
<script src="script.js"></script>
</body>
</html>
One more important detail: The new row gets added correctly when just adding a string, so it may have to do with the variable or the fetch request. Thank you very much for your time and if there is more information that is missing, please tell me and I will do my best to add it.
I have tried changing the type of data being added, adding them to different parts of the table, changing syntax, etc..

total() is probably called before the number is populated. You should have it execute after the cell is populated and not on click.

Related

Get data from a table html with click

Good afternoon, I'm a beginner, I'm having trouble getting information from a table that consumes data from an api.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="main.js"></script>
<title>Document</title>
</head>
<body onload="apendeOnClick()">
<table id="tablerow">
<caption>Alien football stars</caption>
<thead>
<tr>
<th>DATA</th>
<th>TELEFONE</th>
<th>RAMAL</th>
<th>DESCRIÇÃO</th>
<th>ACÕES</th>
</tr>
</thead>
<tbody id="table_body">
</tbody>
</table>
<script>
</script>
</body>
</html>
My code is this, it feeds the table normally, but I would like when the person clicks on the row button to display the information in the alert.
main.js
fetch("https://my-json-server.typicode.com/lfnoleto/api-fake/contact").then((data) => {
return data.json()
}).then((Objectdata) => {
//console.log(Objectdata[0].data)
let tabelaData = ""
Objectdata.map((values)=>{
tabelaData += `<tr>
<td>${values.data}</td>
<td>${values.tefone}</td>
<td>${values.ramal}</td>
<td>${values.descricao}</td>
<td><button id="butao" class="btn btn-success" ><i class="fa fa-phone"></button></td>
</tr>`
})
document.getElementById("table_body").innerHTML = tabelaData
innerHTML = tabelaData
})
function apendeOnClick(){
const table = document.getElementById("tablerow")
console.log(table)
if (table) {
for (var i = 0; i < table.rows.length; i++) {
table.rows[i].childNodes[5].childNodes[1].onclick = function() {
tableText(this);
};
}
}
}
function tableText(tableRow) {
let telefone = tableRow.childNodes[1].innerHTML;
let ramal = tableRow.childNodes[2].innerHTML;
let obj = {'telefone': telefone, 'ramal': ramal};
console.log(obj);
}
I hope that when the person clicks on the telephone icon, he displays the extension and telephone information
you can use data attribute to store extension info or other information.
<button id="butao" data-extension="123" class="btn btn-success" >
in javascript :
const button = document.querySelector('button');
button.dataset.extention // "123"
a good references:
https://www.w3schools.com/tags/att_data-.asp
https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes

fetch json to table (endpoint)

i'm beginner on javascript trying to learn everyday, here i'm trying to fetch json data from url with endpoints, for some reason data is not coming to 'table' i can see it in console.log but not on table.
my json data looks like this :
{
"id": "145127236",
"mygoals": "success",
"future": "high",
"dole": {
"Key": "fhd699f"
}
}
and my code like this :
<!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">
<style>
</style>
</head>
<body>
<div class="container">
<table class="table table-stripped">
<thead>
<tr>
<th> emp id</th>
<th> emp mygoals</th>
<th> emp future</th>
</tr>
</thead>
<tbody id="data" >
</tbody>
</table
</div>
<script>
fetch("https://sp*****.com/get/henkilot/98765432/sijoitus",
{
method: "GET",
headers: {
"x-api-key": "p*****w"
}
}
).then(res =>{
res.json().then(
data=> {
console.log(data);
if(data.length > 0){
var temp ="";
data.forEach((u) =>{
temp +="<tr>";
temp += "<td>"+u.id+"</td>";
temp += "<td>"+u.mygoals+"</td>";
temp += "<td>"+u.future+"</td></tr>";
})
document.getElementById("data").innerHTML = temp
}
}
)
}
)
.catch(err => {
console.log("ERROR: " + err);
});
</script>
</body>
</html>
It seems the JSON data that you wrote in the question is not an array, therefore there is no need to iterate over the data. One option is to remove the forEach or fix the endpoint response if you have access to it.
This is the code that considers that the endpoint does not respond with an array:
<!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">
<style>
</style>
</head>
<body>
<div class="container">
<table class="table table-stripped">
<thead>
<tr>
<th> emp id</th>
<th> emp mygoals</th>
<th> emp future</th>
</tr>
</thead>
<tbody id="data" >
</tbody>
</table>
</div>
<script>
fetch("https://asdasd.free.beeceptor.com/a",
{
method: "GET",
headers: {
"x-api-key": "p*****w"
}
}
).then(res =>{
res.json().then(
data=> {
console.log(data);
var temp ="";
temp +="<tr>";
temp += "<td>"+data.id+"</td>";
temp += "<td>"+data.mygoals+"</td>";
temp += "<td>"+data.future+"</td></tr>";
document.getElementById("data").innerHTML = temp
}
)
}
)
.catch(err => {
console.log("ERROR: " + err);
});
</script>
</body>
</html>
Your braces are insane
try that:
<!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">
</head>
<body>
<div class="container">
<table class="table table-stripped">
<thead>
<tr>
<th> emp id </th>
<th> emp mygoals </th>
<th> emp future </th>
</tr>
</thead>
<tbody id="data"></tbody>
</table>
</div>
<script>
const tableData = document.getElementById("data")
;
fetch("https://sp*****.com/get/henkilot/98765432/sijoitus",
{ method: "GET"
, headers: { "x-api-key": "p*****w" }
})
.then(res=>res.json())
.then(data=>
{
console.log(data)
data.forEach(u=>
{
let newRow = tableData.insertRow()
newRow.insertCell().textContent = u.id
newRow.insertCell().textContent = u.mygoals
newRow.insertCell().textContent = u.future
})
})
.catch(err => console.log("ERROR: " + err) );
</script>
</body>
</html>

How to get particular JSON Data into a table

I'm a total beginner, so I've been kinda of banging my head against a wall trying to figure this out.
Basically, the code below displays json data from a url and displays it in a table. At the moment all 12 keys in the object are being displayed in the table.
What I would like to know is how would I go about displaying just some of the keys in the table. For example, how would I build a table that just has short, long, price and volume being displayed.
I hope this makes sense, thanks in advance
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Using Coincap.io API</title>
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.css'>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container-fluid fill-page">
<div class="row justify-content-center align-items-center">
<div class="col-10">
<div class="waitingDiv text-center">loading...</div>
<table class="table table-striped table-bordered table-hover table-sm">
<thead class="thead-dark"></thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/js/bootstrap.min.js'></script>
<script src="js/index.js"></script>
</body>
</html>
<script>
$(document).ready(function() {
$.ajax({
url: "https://coincap.io/front",
type: "GET",
dataType: "json"
}).done(function(data, textStatus, jqxhr) {
//only look at first 25 results...
data = data.slice(0, 10);
$.each(data, function(index, value) {
if (index == 0) {
$("thead").append("<tr id='tr-header'> ");
$.each(Object.keys(data[index]), function(propertyName, value){
$("#tr-header").append("<th>" + value + "</th>");
});
$("thead").append("</tr>");
}
$("tbody").append("<tr id='tr-" + index + "'> ");
$.each(data[index], function(propertyPosition, value){
$("#tr-" + index).append(
"<td>" + data[index][propertyPosition] + "</td>"
);
});
$("tbody").append("</tr>");
});
$('.waitingDiv').hide();
}).fail(function(jqxhr, textStatus, errorThrown){
console.log("failed");
});
});
<script>
You can check for if propertyName is in an array of keys that you want to show.
var keys_to_show = ["short", "long", "price", "volume"];
$.each(Object.keys(data[index]), function(propertyName, value) {
if (keys_to_show.includes(propertyName)) {
$("#tr-header").append("<th>" + value + "</th>");
}
});

How to insert row in HTML tablesorter table body in javascript/node.js?

I have made a function test tool for my company app using html/css/javascript/node.js/express/tablesorter.
My test tool is successfully performed the function tests.
My table style is from opensource 'Tablesorter'.
This is edit screen. The file is .ejs format. So, Node.js server render the file to html dynamically.
But, I wonder how to insert the row additionally in this table. So, I searched to solve the problem and got some solution like below.
for (var i in rList) {
var table = document.getElementById("ID_Table");
var row = table.insertRow(-1);
var cell1 = row.insertCell(-1);
var cell2 = row.insertCell(-1);
var list = rList[i].split(" ");
cell1.innerHTML = list[0];
cell2.innerHTML = list[1];
}
But, this way is incomplete. The result is like this.
The 'tablesorter' style is not applied to additional rows. I don't know how to solve this.
<!DOCTYPE html>
<html>
<head>
<!-- Character Set -->
<meta charset="utf-8">
<!-- Title -->
<title><%= title %></title>
<!-- Style -->
<link rel='stylesheet' href='/stylesheets/style.css'/>
<!-- JS -->
<script src="/javascripts/indexCore.js"></script>
<!-- jQuery -->
<script src="/opensources/tablesorter/docs/js/jquery-latest.min.js"></script>
<script src="/opensources/tablesorter/docs/js/jquery-ui.min.js"></script>
<!-- Tablesorter: theme -->
<link class="theme default" rel="stylesheet" href="/opensources/tablesorter/css/theme.default.css">
<link class="theme blue" rel="stylesheet" href="/opensources/tablesorter/css/theme.blue.css">
<link class="theme green" rel="stylesheet" href="/opensources/tablesorter/css/theme.green.css">
<link class="theme grey" rel="stylesheet" href="/opensources/tablesorter/css/theme.grey.css">
<link class="theme ice" rel="stylesheet" href="/opensources/tablesorter/css/theme.ice.css">
<link class="theme black-ice" rel="stylesheet" href="/opensources/tablesorter/css/theme.black-ice.css">
<link class="theme dark" rel="stylesheet" href="/opensources/tablesorter/css/theme.dark.css">
<link class="theme dropbox" rel="stylesheet" href="/opensources/tablesorter/css/theme.dropbox.css">
<link class="theme metro-dark" rel="stylesheet" href="/opensources/tablesorter/css/theme.metro-dark.css">
<!-- Tablesorter script: required -->
<script src="/opensources/tablesorter/js/jquery.tablesorter.js"></script>
<script src="/opensources/tablesorter/js/widgets/widget-filter.js"></script>
<script src="/opensources/tablesorter/js/widgets/widget-stickyHeaders.js"></script>
<script id="js">
$(function(){
/* make second table scroll within its wrapper */
$('#ID_Table').tablesorter({
widthFixed : true,
headerTemplate : '{content} {icon}', // Add icon for various themes
widgets: [ 'zebra', 'stickyHeaders', 'filter' ],
widgetOptions: {
// jQuery selector or object to attach sticky header to
stickyHeaders_attachTo : '.wrapper' // or $('.wrapper')
}
});
$("#ID_Table tbody").click(function () {
//$(this).addClass('selected').siblings().removeClass('selected');
//alert('a');
});
});
</script>
<script>
$(function() { //이 부분은 렌더링 되자마자 실행되는 부분
window.includeCaption = true;
$('.caption').on('click', function(){
includeCaption = !includeCaption;
$(this).html( '' + includeCaption );
$('#ID_Table').each(function(){
if (this.config) {
this.config.widgetOptions.stickyHeaders_includeCaption = includeCaption;
this.config.widgetOptions.$sticky.children('caption').toggle(includeCaption);
}
});
});
// removed jQuery UI theme because of the accordion!
$('link.theme').each(function(){ this.disabled = true; });
var themes = 'dropbox blue green grey ice black-ice dark default metro-dark', //테마 순서
i, o = '', t = themes.split(' ');
for (i = 0; i < t.length; i++) {
o += '<option value="' + t[i] + '">' + t[i] + '</option>';
}
$('select:first')
.append(o)
.change(function(){
var theme = $(this).val().toLowerCase(),
// ui-theme is added by the themeswitcher
files = $('link.theme').each(function(){
this.disabled = true;
})
files.filter('.' + theme).each(function(){
this.disabled = false;
});
$('table')
.removeClass('tablesorter-' + t.join(' tablesorter-'))
.addClass('tablesorter-' + (theme === 'black-ice' ? 'blackice' : theme) );
}).change();
});
</script>
</head>
<body>
<div id="header">
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
Main
Edit
Blank
<hr/>
</div>
<div id="wrap">
<div id="Main_Screen">
<input type="button" value="로딩" id="btn" onclick="dynamicLoadScript_Main('/temps/MainScript.js', '/temps/WrapScript.js')"></input>
<input type="button" value="수행" id="btn1" onclick="Automation()"></input>
<button type="button">결과 리스트 출력</button>
</div>
<div id="List_Screen" class="narrow-block wrapper">
Theme: <select></select>
<table id="ID_Table" class="tablesorter" border="0" cellpadding="0" cellspacing="1">
<thead>
<tr>
<th>Function</th>
<th>Result</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
This is my .ejs File.
And, this is printResult Function in indexCore.js.
function printResult(){
var rList = resultList.split('\n');
for (var i in rList) {
var table = document.getElementById("ID_Table");
var row = table.insertRow(-1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var list = rList[i].split(" ");
cell1.innerHTML = list[0];
cell2.innerHTML = list[1];
}
}
You can edit and apply your logic at the .ejs file directly at your backend as your client side solution seems to be run after table being initialized by Tablesorter. You can also try to implement your client side solution adding the rows to table first then initialize Tablesorter. Good Luck!

Form Submit not working jquery

When ever I click submit button, page just get refreshed. However this code works everywhere.
The form id is #pager. Code that is note working as expected is
$("#pager").submit(function(e){
console.log("Hi!!!")
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.css">
<style>
</style>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.js"></script>
<script>
// The Edit and
function actionFormatter(value, row, index) {
return [
'<a class="edit ml10" href="javascript:void(0)" title="Edit">',
'<i class="glyphicon glyphicon-edit"></i>',
'</a>',
'<a class="remove ml10" href="javascript:void(0)" title="Remove">',
'<i class="glyphicon glyphicon-remove"></i>',
'</a>'
].join(' ');
}
$.ajax({
type:"GET",
crossDomain: true,
beforeSend: function (request)
{
request.setRequestHeader("Content-Type", "application/json");
},
url: "http://localhost:5000/api/members/",
processData: false,
success: function(msg) {
console.log(msg);
$('#memberTable').bootstrapTable({
data: msg
});
}
});
$(function () {
$('#memberTable').on('all.bs.table', function (e, name, args) {
console.log(args);
})
.on('check.bs.table', function (e, row) {
console.log(row);
})
});
window.actionEvents = {
'click .edit': function (e, value, row, index) {
console.log(row);
},
'click .remove': function (e, value, row, index) {
console.log(row);
}
};
$("#pager").submit(function(e){
console.log("Hi!!!")
});
</script>
<div class="container">
<div class="row">
<div class="col-sm-12">
<h2>Member Data</h2>
<p>
<br>
<table id="memberTable" data-search="true"
>
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th data-field="name" data-sortable="true" >Name</th>
<th data-field="phone">Phone</th>
<th data-field="date" data-sortable="true">Date</th>
<th data-field="action" data-formatter="actionFormatter" data-events="actionEvents">Action</th>
</tr>
</thead>
</table>
</p>
<br>
</div></div>
<div class="row">
<div class="col-sm-12">
<form id = "pager">
<textarea class="form-control" rows="3" id="textArea"></textarea>
<span class="help-block"></span>
<button type="submit" id="sendButton" class="form-control btn btn-primary">Send</button>
</form>
</div>
</div></div>
</body>
</html>
Looks like there are two problems here. The first is that you need to prevent the default form behavior so that the page doesn't redirect.
The second is that you need to instantiate your listener after the document is ready. At the moment your listener gets added before the DOM is ready so it's never actually running. This should solve both problems.
$(function() {
$("#pager").submit(function(e) {
e.preventDefault();
console.log("Hi!!!")
});
// You should probably put the rest of your Javascript in here too, so it doesn't run until the DOM is fully ready.
});
You can read more about event.preventDefault here. And document.ready here.

Categories

Resources