Table not appending cells from array - javascript

I am trying to append these cells to a dynamic table, and fill the child Labels with text from an array.
I am not getting any errors. Only one cell with the oldest data is displayed.
for (i=0; i < response.array.length; i++) {
console.log(response.array[i].Sender)
$('.name').html(response.array[i].Sender);
$('.date').html(response.array[i].Date);
$('.subject').html(response.array[i].Subject);
cell.append(name);
cell.append(date);
cell.append(subject);
$('#table').append(cell);
}
EDIT:
I have tried this method, but I can't move the Labels inside the cell
for (i=0; i < response.array.length; i++) {
trHTML += '<tr><td>' + response.array[i].Sender + '<td><td>' + response.array[i].Date +'<td><td>' + response.array[i].Subject + '<td><tr>'
}
EDIT 2:
I have tried this, and the first cell is display correctly but the other data is display as [object Object][object Object][object Object][object Object]
trHTML += $('.name').html(response.array[i].Sender) + $('.date').html(response.array[i].Date) + $('.subject').html(response.array[i].Subject);

In this line...
trHTML += '<tr><td>' + response.array[i].Sender + '<td><td>' + response.array[i].Date +'<td><td>' + response.array[i].Subject + '<td><tr>'
...you don't have any closing tags (like </td>after the cell contents and </tr> at the end of the row), only opening tags, which leads to invalid HTML and creates code that makes no sense for the browser.

The JSON posted in the comments was F.U.B.A.R.ed. There are 2 problems that make it inconsumable.
#
Description
⓵
There are a lot of smart quotes: “ and ”, I believe the only valid quotes used in JSON are double quotes ".
⓶
The last quote is missing and it's not because of a cut & paste job, because there's 2 objects and an array right side brackets placed properly.
So take that mess to a validator.
{“ // ⓵
dataarray”: [{“
Subject”: ”Delivery”,
”Date ":"
2022 - 06 - 02 17: 49: 36 ", "
Sender”: ”John”,
”user_id ":67890, "
Message”: ”This is the confirmation of your order”
}, {“
Subject”: ”Delivery”,
”Date ":"
2022 - 06 - 07 07: 31: 25 ", "
Sender”: ”James”,
”user_id ":67890, "
Message”: ”This is the confirmation of your order // ⓶
}]
}
After you fix that JSON or the endpoint or whatever. Do a simple test and past the url in the browser addressbar. If it works you'll see it displayed on an unstyled page. If you still can't get it going I noticed that in OP this is used:
response.array[i]
Normally the response is the entire JSON and whatever is connected to it is a property of said response so .array[i] is an Array called "array", but the only array in the JSON is called "dataarray"?
Details commented in example below
// Pass JSON
const buildTable = data => {
// Reference <tbody>
const table = document.querySelector('tbody');
/*
Loop to generate htmlString for each <tr>
filled with data fro JSON
*/
for (let i = 0; i < data.length; i++) {
let row = `<tr>
<td>${data[i].Sender}</td>
<td>${data[i].Date}</td>
<td>${data[i].Subject}</td>
</tr>`;
table.insertAdjacentHTML('beforeEnd', row);
}
};
// Pass endpoint of API
const getData = async(url) => {
// await fetch()
const response = await fetch(url);
// await JSON
const json = await response.json();
/*
Invoke buildTable to the first ten rows
*/
return buildTable(json);
};
// Runs at pageload
getData('https://my.api.mockaroo.com/misc.json?key=3634fcf0');
// Button bound to click event
document.querySelector('button').onclick = function() {
const url = 'https://my.api.mockaroo.com/misc.json?key=3634fcf0';
getData(url);
}
html {
font: 300 2ch/1 'Segoe UI'
}
table {
width: 90vw;
table-layout: fixed;
border-collapse: collapse;
}
th {
width: 30vw;
}
td {
border: 0.5px ridge grey;
padding: 5px;
}
button {
font: inherit;
float: right;
margin-top: 5px;
cursor: pointer;
}
<table>
<thead>
<tr>
<th>Sender</th>
<th>Date</th>
<th>Subject</th>
</tr>
</thead>
<tbody></tbody>
</table>
<button>GET 10 More</button>

I tried to work on this requirement and came up with the below working Demo :
let tableString = "<table>";
const response = {
array: [{
Sender: 'alpha',
Date: 'Date 1',
Subject: 'Subject 1'
}, {
Sender: 'Beta',
Date: 'Date 2',
Subject: 'Subject 2'
}, {
Sender: 'Gamma',
Date: 'Date 2',
Subject: 'Subject 2'
}]
}
tableString += `<tr>
<th>Sender</th>
<th>Date</th>
<th>Subject</th>
</tr>`;
for (i=0; i < response.array.length; i++) {
tableString += '<tr><td>' + response.array[i].Sender + '</td><td>' + response.array[i].Date +'</td><td>' + response.array[i].Subject + '</td></tr>'
}
tableString += "</table>";
$('#table').html(tableString);
table, th, td {
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table"></div>
Here is a compact version with dynamic property binding.
const response = {
array: [{
Sender: 'alpha',
Date: 'Date 1',
Subject: 'Subject 1'
}, {
Sender: 'Beta',
Date: 'Date 2',
Subject: 'Subject 2'
}, {
Sender: 'Gamma',
Date: 'Date 2',
Subject: 'Subject 2'
}]
}
let tableContainer = $('#table'),
table = $('<table>');
table.append('<tr><th>Sender</th><th>Date</th><th>Subject</th></tr>');
response.array.forEach(obj => {
const tr = $('<tr>');
['Sender', 'Date', 'Subject'].forEach(attr => {
tr.append('<td>' + obj[attr] + '</td>');
});
table.append(tr);
});
tableContainer.append(table);
table, th, td {
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table"></div>

Related

I'm having trouble centering a cell of an HTML table

I'm generating an HTML table from an array of objects. If the signature is on the left, I need to put it in the middle. In case I have two signatures, I need to leave them centralized, as they already are.
My current code:
var result = [
{name: "John",
jobPosition: "President"
},
{name: "Marc",
jobPosition: "Director"
},
{name: "Paul",
jobPosition: "Director"
},
{name: "Mary",
jobPosition: "Director"
},
{name: "Carl",
jobPosition: "Geral Secretary"
},
];
var table = '<table style=" height: 94px;" border="0" width="100%" cellspacing="0" cellpadding="0"><tbody>';
result.forEach(function(item, index) {
if (index % 2 == 0) {
table += '<tr style="height: 35px;">';
}
table += '<td style="width: 50%; height: 150px; text-align: center; font-family: arial; font-size: 12pt;" valign="top"><p>_____________________________</p><p>' + item.name + '</p><p>' + item.jobPosition + '</p></td>';
if (index % 2 == 1 || index == (result.length - 1)) {
table += '</tr>';
}
});
table += '</tbody></table>';
gs.info(table);
In this example,Carl's signature needs to come in the middle.
Example
Thanks in advance.
excuse me sir. now i found out your desire.
you should add colspan attribute to te last td if index % 2 == 1
and set the amount of this colspan to 2

html onclick not happening when parameter has special characters like $ or [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a code in which I have three rows with three parameters $COKE, COKE, COKE.
Every row has a sublist which opens when I click the parameters. It works fine when parameter doesnt have any special characters i.e.
For case when $COKE is parameter it doesn't open sublist onclick. ($ dollar sign)
For case when COKE is parameter it opens sublist onclick.
For case when COKE. is parameter it doesn't open sublist onclick. (. dot sign)
data[i].parameter="$COKE"
document.getElementById("results").innerHTML += "<tr id="+data[i].parameter+" onclick='showSublist(this.id)'>
data[i].paramater can have values as shown below $COKE, COKE.,COKE as an example.
Image shown as reference, where only case 2 opens but case 1 and case 3 doesn't open when I click them.
Cases Image
By not escaping special characters you are creating invalid HTML code, that's why onclick doesn't work.
Here is example how browser handles special characters:
function escape(a) {
return "&#" + a.charCodeAt(0) + ";";
}
function escapeText(text) {
return text.replace(/["'&<>]/g, escape);
}
function showSublist(id) {
alert(id);
}
var data = [{
parameter: "test"
},
{
parameter: "$test"
},
{
parameter: "<test"
},
{
parameter: "test>"
},
{
parameter: "<test>"
},
{
parameter: '"test'
},
{
parameter: 'test"'
},
{
parameter: '"test"'
},
{
parameter: "test."
},
{
parameter: '&test'
},
{
parameter: '&test;'
},
{
parameter: "test${test}"
},
];
for (let i = 0, tr = document.createElement("tr"); i < data.length; i++) {
tr = tr.cloneNode(false);
tr.innerHTML = '<td class="n">' + i + '</td>';
/* original, incorrect structure */
tr.innerHTML += "<td id=" + data[i].parameter + " onclick='showSublist(this.id)'>" + data[i].parameter + '</td>';
tr.innerHTML += '<td class="n">' + i + '</td>';
/* correct structure, no filter */
tr.innerHTML += '<td id="' + data[i].parameter + '" onclick="showSublist(this.id)">' + data[i].parameter + '</td>';
tr.innerHTML += '<td class="n">' + i + '</td>';
/* correct structure, filter */
tr.innerHTML += '<td id="' + escapeText(data[i].parameter) + '" onclick="showSublist(this.id)">' + escapeText(data[i].parameter) + '</td>';
tr.onmouseover = mouseOver;
document.getElementById("results").appendChild(tr);
};
var div = document.getElementById("html");
function mouseOver(e) {
html.textContent = e.target.className == "n" ? e.target.nextSibling.outerHTML : e.target.outerHTML;
}
th {
text-align: start;
}
td:nth-child(even) {
border-right: 1em solid transparent;
}
td:hover {
background-color: rgba(0, 0, 0, 0.1);
cursor: pointer;
}
div {
background-color: white;
color: black;
position: fixed;
bottom: 0;
margin-top: 1em;
padding: 0.5em;
border: 1px solid black;
}
table {
margin-bottom: 3em;
}
<table id="results">
<tr>
<th colspan="2">
Original, no quotes
</th>
<th colspan="2">
Unescaped
</th>
<th colspan="2">
Escaped
</th>
</tr>
</table>
<div id="html"></div>

key is not sorted in JSON array using javascript

In this I am trying to sort the data by partNo and it is perfectly sorted with this, but my problem is that the first column of the table does not sort with the rest of the columns. sr No has to be sorted with all other columns
here sr No is a key which is not sorted with other columns
let productDetails = {
"10": [{
id: "1",
partNo: "100",
productName: "bag",
size: "30",
color: ["Blue"],
description: "sky bags ",
}],
"20": [{
id: "2",
partNo: "15",
productName: "bottle",
size: "10",
color: ["Green", "Orange"],
description: "plastic and still",
}]
,
"30": [{
id: "4",
partNo: "25",
productName: "lunchbox",
size: "20",
color: ["Blue", "Red"],
description: "fresh food",
}],
"40": [{
id: "3",
partNo: "45",
productName: "pen",
size: "10",
color: ["Red", "Blue"],
description: "gel pen ",
}]
};
/**
* This function displays the data in the table
*/
function displayData() {
objectArray = Object.values(productDetails);
display(objectArray);
}
function display(productStore) {
messageTable(" ");
let table = "<table border = 1 cellpadding = 10 ><th colspan=7 >Product Details</th><tr><th>sr No</th><th>Product Id</th><th>Part No</th><th>Name</th><th>Size</th><th>Color</th><th>Description</th></tr>";
for (var key in productDetails) {
for (var weight in productDetails[key]) {
table += "<tr><td>" + key + "</td>";
table += "<td>" + productDetails[key][weight].id + "</td>";
table += "<td>" + productDetails[key][weight].partNo + "</td>";
table += "<td>" + productDetails[key][weight].productName + "</td>";
table += "<td>" + productDetails[key][weight].size + "</td>";
table += "<td>" + productDetails[key][weight].color + "</td>";
table += "<td>" + productDetails[key][weight].description + "</td>";
}
} messageTable(table);
}
/**
* function to sort an array by part No
*/
function sortByPartNo() {
let arr = [];
item = Object.keys(productDetails)
console.log(item)
item.forEach(function (index) {
productDetails[index].forEach(function (indexA) {
arr.push(indexA);
});
})
arr.sort(function (first, second) {
return parseFloat(first.partNo) - parseFloat(second.partNo);
});
console.log(arr)
printArray(arr, item)
}
/**
* function to print array in the table
*/
function printArray(arr, item) {
messageTable(" ");
let table = "<table border = 1 cellpadding = 10 ><th colspan=7 >Product Details</th><tr><th>sr No</th><th>Product Id</th><th>Part No</th><th>Name</th><th>Size</th><th>Color</th><th>Description</th></tr>";
for (let key in arr) {
table += "<tr><td>" + item[key] + "</td>";
table += "<td>" + arr[key].id + "</td>";
table += "<td>" + arr[key].partNo + "</td>";
table += "<td>" + arr[key].productName + "</td>";
table += "<td>" + arr[key].size + "</td>";
table += "<td>" + arr[key].color + "</td>";
table += "<td>" + arr[key].description + "</td>";
} messageTable(table);
}
/**
* function is to print the table
*/
function messageTable(data) {
document.getElementById("messageTableA").innerHTML = data;
}
/**
* this function is to print the message
*/
function message(message) {
document.getElementById("demo").innerHTML = message;
}
<!DOCTYPE html>
<html>
<head>
<style>
th,
td,
p,
input {
font-family: Arial, Helvetica, sans-serif;
}
table,
th,
td {
border: solid 1px #DDD;
border-collapse: collapse;
padding: 10px 10px;
text-align: center;
}
th {
font-weight: bold;
}
</style>
</head>
<body onload="displayData()">
<h2>Product Details:</h2>
<form action="">
<input type="button" value="sortByPartNo" onclick="sortByPartNo();">
<p id="result"></p>
<p id="demo"></p>
<p id="messageTableA"></p>
</form>
</body>
</html>
There's a couple ways to go about this, but the simplest would be to just construct a new objects from the original one that contains both the keys and values.
i.e. turn this:
{
"10": [{
"partNo": "100",
"size": "30",
// etc
}],
// ...
}
into this
[
{
"key": "10",
"partNo": "100",
"size": "30",
// etc
},
// ...
]
or alternatively, something like this works too. A similar approach is used in the concrete code example below.
[
{
"key": "10",
"value": {
"partNo": "100",
"size": "30",
// etc
},
},
// ...
]
Basically, we just need to bundle all the related information together before we do a sort(). After we sort, we can pass the bundled data as-is to your display functions, or we can separate them back into two lists, however you prefer.
A practical simplified example:
const data = {
1: {
color: 'blue',
size: 10,
},
2: {
color: 'green',
size: 50,
},
3: {
color: 'yellow',
size: 5,
},
}
// Object.entries() will reshape the data in a way that keeps keys and values together
// then we .sort() based on size
const sorted = (
Object.entries(data)
.sort((x, y) => x[1].size - y[1].size)
)
console.log('sorted keys and values', sorted)
// If you want, you can then split them back out into two separate array, like you had it:
console.log('sorted keys', sorted.map(x => x[0]))
console.log('sorted values', sorted.map(x => x[1]))
See this to learn about Object.entries, used in this particular example.
Scotty Jamison responded first and gave you a good description of options and alternatives. I urge you to accept his answer.
However, I figured I minus well provide my work that I had developed in response to your original question incorrectly marked as a duplicate (as you mention in the comments to your question here). It is a more fully worked out version of Scotty's first proposal, which places the outer key as a property inside the array entry.
// Just a convenience for building productDetails
let pdVal = (id,no,name,size,colors,desc) => ({
id: id,
partNo: no,
productName: name,
size: size,
color: colors,
description: desc
})
let productDetails = {
"10": [pdVal("1","100","bag","30",["Blue"],"sky bags ")],
"20": [pdVal("2","15","bottle","10",["Green", "Orange"],"plastic and still")],
"30": [pdVal("4","25","lunchbox","20",["Blue", "Red"],"fresh food")],
"40": [pdVal("3","45","pen","10",["Red", "Blue"],"gel pen ")]
};
function sortByPartNo() {
let arr = [];
for (let key of Object.keys(productDetails)) {
let obj = productDetails[key][0];
arr.push(Object.assign({}, obj, {key}));
}
arr.sort((a,b) => parseFloat(a.partNo) - parseFloat(b.partNo))
printArray(arr);
}
function printArray(arr) {
messageTable(" ");
let table = `
<table border = 1 cellpadding = 10 >
<th colspan=7 >Product Details</th>
<tr>
<th>sr No</th>
<th>Product Id</th>
<th>Part No</th>
<th>Name</th>
<th>Size</th>
<th>Color</th>
<th>Description</th>
</tr>
`;
for (let item of arr) {
console.log({arr})
table += "<tr><td>" + item.key + "</td>";
table += "<td>" + item.id + "</td>";
table += "<td>" + item.partNo + "</td>";
table += "<td>" + item.productName + "</td>";
table += "<td>" + item.size + "</td>";
table += "<td>" + item.color + "</td>";
table += "<td>" + item.description + "</td>";
}
messageTable(table);
}
function messageTable(data) {
document.getElementById("messageTableA").innerHTML = data;
}
<input type="button" value="sortByPartNo" onclick="sortByPartNo();">
<p id="result"></p>
<p id="demo"></p>
<p id="messageTableA"></p>

Need to add copy button to each cell of a column in html

I am trying to use ngx-clipboard module in my angular application.
The data in the table is coming from a service and i am using jsonToTable() to insert a dynamic table.
component.ts
generateOverrideCode(){
try {
document.getElementById('tableGoesHere').innerHTML = this.jsonToTable(data, 'table table-sm table-dark');
}
catch (ex) {
console.log('--generate override code', ex);
}
}
capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
jsonToTable(json, classes){
var cols = Object.keys(json[0]);
var headerRow = '';
var bodyRows = '';
classes = classes || '';
cols.map((col)=>{
headerRow += '<th>' + this.capitalizeFirstLetter(col) + '</th>';
});
json.map((row)=> {
bodyRows += '<tr>';
cols.map((colName)=> {
if(colName != 'population')
bodyRows += '<td>' + row[colName] + '</td>';
else
bodyRows += '<td id="colName+row">' + row[colName] + '<button></button>' + '</td>'; //I want to add a dynamic id to the button added to each cell of this row, so that i can use the id to target the text of that cell.
});
bodyRows += '</tr>';
});
return '<table class="' +
classes +
'"><thead><tr>' +
headerRow +
'</tr></thead><tbody>' +
bodyRows +
'</tbody></table>';
}
}
var data = [
{ country: 'China', population: 1379510000 },
{ country: 'India', population: 1330780000 },
{ country: 'United States', population: 324788000 },
{ country: 'Indonesia', population: 260581000 },
{ country: 'Brazil', population: 206855000 },
];
component.html
<div class="row">
<div class="col-sm-12">
<button (click)="generateOverrideCode()">Generate</button>
</div>
</div>
<div id="tableGoesHere"></div>
What i am trying to achieve is adding a copy button next to the each cell in the third column.
I also want each cell to have a unique id so i can target it using ngx-clipboard directive. Follow link for example
https://maxisam.github.io/ngx-clipboard/
I have created a stackblitz example as well.
https://stackblitz.com/edit/angular-s5g1b5
Please help me with adding unique id to each cell then i will move to adding ngx-clipboard.(i have added comments in stackblitz where i attempted to add unique id)

Table Not Populating as I expected using Jquery

I am trying to populate a table using a JSON file. When I run this through the browser, my first row populates. However the other rows do not. Can someone please point out to me what I am doing wrong? Am I not looping this correctly? Thank you in advance.
$(document).ready(function() {
$.getJSON( "data.json", function(data) {
var htmlToRender= [];
var item;
for (var i = 0; i < data.length; i++) {
item = data[i];
console.log(data[i]);
htmlToRender = '<tr><td>' + item.name + '</td>'
'<td>' + item.description + '</td>'
console.log(item.description)
'<td>Open In Google Mapspwd</td></tr>';
console.log(item.location);
$('#hot-spots').append(htmlToRender);
console.log(htmlToRender);
};
});
});
The lines following htmlToRender = '<tr><td>' + item.name + '</td>' look a bit suspicious--you're missing a + sign to concatenate these additional strings, and sprinkled console.logs amidst the string build isn't helping the cause.
I recommend using a string template:
const item = {
name: "hello",
description: "world",
location: "somewhere"
};
const htmlToRender = `
<tr>
<td>${item.name}</td>
<td>${item.description}</td>
<td>
Open In Google Maps
</td>
</tr>
`;
$('#hot-spots').append(htmlToRender);
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
padding: 0.5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="hot-spots"></table>

Categories

Resources