Connect button to display data in a html table using Javascript - javascript

I have a dynamically generated table that uses array of JS objects. I'm also adding a "View details" on each row. What I need is to be able to display data from the same array of objects in a different table.
I tried to add event listener to the buttons, but they either iterate through all of the rows or don't display anything
function drawTable(tbody) {
var tr, td;
tbody = document.getElementById(tbody);
for (var i = 0; i < products.length; i++) // loop through data source
{
tr = tbody.insertRow(tbody.rows.length);
td = tr.insertCell(tr.cells.length);
td.innerHTML = products[i].ProductName;
td = tr.insertCell(tr.cells.length);
td.innerHTML = products[i].UnitsInStock;
td = tr.insertCell(tr.cells.length);
// View Details button
td = tr.insertCell(tr.cells.length);
button = document.createElement('button');
button.textContent = ('View Details')
td.appendChild(button)
}
}
<div class="table-wrapper">
<table id="display-table" class="fl-table">
<thead>
<tr>
<th>Product Name</th>
<th>Units In Stock</th>
<th>View Details</th>
</tr>
</thead>
<tbody id="table-data">
</tbody>
</table>
</div>
<h2>Product Details</h2>
<div class="table-wrapper">
<table class="fl-table">
<thead>
<tr>
<th>Product Name</th>
<th>Product Category</th>
<th>Product Description</th>
</tr>
</thead>
<tbody id="table-details">
</tbody>
</table>
</div>

Below button.textContent = ('View Details') add
button.onclick = (n=> event=> {
console.log('click on', products[n]) // you handler here
})(i); // set current loop "i" as parameter "n" value
we wrap function event=>... in n=>... to pass current i value - without this the i would be set always to last iteration value.

Related

How to make first column's every row clickable to get data from that whole row? JavaScript

I'm trying to make a table's first column's each row (in this case order IDs) clickable so that I can display more info from this specific order ID in another container on my website. I looped through some JSON data to create the table like this:
function printData(jsonData) {
let myTable = document.getElementById("jsonTable")
for(let i=0; i < jsonData.length; i++) {
let row = `<tr>
<td>${jsonData[i].orderid}</td>
<td>${jsonData[i].customerid}</td>
<td>${jsonData[i].customer}</td>
<td>${jsonData[i].invaddr}</td>
<td>${jsonData[i].delivaddr}</td>
<td>${jsonData[i].deliverydate}</td>
<td>${jsonData[i].respsalesperson}</td></tr>`
jsonTable.innerHTML += row
}
}
And this is how my HTML file looks like:
<div class="datatable">
<div class="datatablecontent">
<table class="jsontable">
<tr id="jsontr">
<th>Order ID</th>
<th>Customer ID</th>
<th>Customer</th>
<th>InvAddr</th>
<th>Delivery Address</th>
<th>Delivery Date</th>
<th>Resp. For Sale </th>
<tbody id="jsonTable">
</tbody>
</tr>
</table>
</div>
</div>
While iterating over jsonData, you can declare a callback in an event listener.
Because you're using template literals, I'm keeping it concise and passing the row index. You can also pass the data itself by adding an event listener in JS, to do that you'll need to access the element.
function logRowData(index) {
console.log(jsonData[index])
}
let jsonData = [
{orderid: 0, customerid:14, customer: 'abc'},
{orderid: 1, customerid:25, customer: 'xyz'}
]
printData(jsonData)
function printData(jsonData) {
let myTable = document.getElementById("jsonTable")
for(let i=0; i < jsonData.length; i++) {
let row = `<tr>
<td onclick={logRowData(${i})}>${jsonData[i].orderid}</td>
<td>${jsonData[i].customerid}</td>
<td>${jsonData[i].customer}</td></tr>`
jsonTable.innerHTML += row
}
}
<div class="datatable">
<div class="datatablecontent">
<table class="jsontable">
<tr id="jsontr">
<th>Order ID</th>
<th>Customer ID</th>
<th>Customer</th>
<tbody id="jsonTable">
</tbody>
</tr>
</table>
</div>
</div>

Hide rows in a column with vanilla JavaScript according to text content

I have a table like this:
<table id="mytable" class="table">
<tr>
<th>Author</th>
<th>Title</th>
<th>Year</th>
<th>Digitised</th>
</tr>
</table
I'd like to have a button which, when clicked, hides or shows the rows which contain a 'Yes' (or a check, or a specific element) in the 'Digitised' column.
This is the JavaScript I've come up so far
let table, tr, td, i, t;
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for(t=0; t<tds.length; t1++) {
let td = tds[t][3];
if (td) {
if (td.innerHTML.indexOf('Yes') > -1) {
tr[i].style.display = 'none';
}
}
}
}
This doesn't work. How can I achieve what I want?
You have the wrong id in your Javascript, the table id is "mytable" (in lower case) but your js code is trying to find "myTable" which is camel case,
Anyways here is a sample of code that do what you need:
var areRowsDisplayed = true
function toggleRows() {
const rows = document.querySelectorAll('#mytable > tbody > tr')
Array.prototype.slice.call(rows).forEach(row => {
let dataField = row.querySelectorAll('td')[3]
if(dataField.innerText.toLowerCase() == 'yes') {
row.style.display = !areRowsDisplayed ? '': 'none'
}
})
areRowsDisplayed = !areRowsDisplayed
}
document.querySelector('#toggleRows').addEventListener('click',e => toggleRows())
<button id='toggleRows'>Hide/Show</button>
<table id="mytable" class="table">
<thead>
<tr>
<th>Author</th>
<th>Title</th>
<th>Year</th>
<th>Digitised</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pin Pon</td>
<td>The new song</td>
<td>1991</td>
<td>No</td>
</tr>
<tr>
<td>Cloudies</td>
<td>Fly with me</td>
<td>1986</td>
<td>Yes</td>
</tr>
</tbody>
</table>
This basically has a button that run a javascript function, and within that function we loop into each table row and hide/show the rows that meet certain criteria
I have added a global variable to check what is the current status (if the rows are hidden already) only for this sample purposes, you must be storing that in some context depending on the framework you are using

Button to remove row of table is not working using Javascript

This is the table in which I have used button to remove of table.
<table>
<tr>
<th>First Name</th>
<th>Middle Name</th>
<th>Last Name</th>
<th>User Name</th>
<th>Email</th>
<th>Remove</th>
</tr>
<tr>
<td>Sujan6</td>
<td>Bikram5</td>
<td>Thapa</td>
<td>Sujan6</td>
<td>Sujan#gmail5</td>
<td><button class="button button3">Remove</button></td>
</tr>
<tr>
<td>Sujan7</td>
<td>Bikram6</td>
<td>Thapa</td>
<td>Sujan7</td>
<td>Sujan#gmail5</td>
<td><button class="button button3">Remove</button></td>
</tr>
</table>
This is the Javascript code with which I am trying to remove row of table. This code show error of:
"TypeError: Cannot read property 'parentNode' of undefined" at the line of " var tr = td.target.parentElement;"
var deleteRecord = document.getElementsByClassName('button button3');
for (var i = 0; i < deleteRecord.length; i++) {
deleteRecord[i].addEventListener('click', removeItem);
}
function removeItem(e) {
event.preventDefault();
if (confirm('Are You Sure')) {
var td = e.target.parentElement;
var tr = td.target.parentElement;
tr.parentElement.removeChild('tr');
}
}
td is not an event, so it doesn't have a target. Accessing this will cause the error you are seeing. Access the parentElement directly on td.
You also need to remove the quotes around tr when removing the element.
function removeItem(e) {
event.preventDefault();
if (confirm('Are You Sure')) {
var td = e.target.parentElement;
var tr = td.parentElement;
tr.parentElement.removeChild(tr);
}
}

Appending a tr element to the tbody element on the click of a button

I'm trying to create button event listener that will add the contents of a <tr> element to the <tbody> element. Ive tried multiple methods such as insertRow() and adjacentHtml() and none seem to work. What am I doing wrong? also i am using typescript, could that be the issue as well?
html
<table class="table table-striped table-dark invoice-table">
<thead>
<tr class="head-contents">
<th scope="col">#</th>
<th scope="col-3">Description</th>
<th scope="col">Quanity</th>
<th scope="col">item number</th>
<th scope="col">item price</th>
<th scope="col">total price</th>
</tr>
</thead>
<tbody id="table-contents">
<tr id="item-info">
<th scope="row">1</th>
<td><input type="text"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><span></span></td>
</tr>
</tbody>
</table>
<!-- add item button -->
<button type="button" class="btn btn-primary" id="addItem">Add Item</button>
<!-- delete item button -->
<button type="button" class="btn btn-warning" id="deleteItem">Delete Item</button>
javascript
// event listener to add an item
let addedItem = document.getElementById("addItem").addEventListener("click", () => {
let table = document.getElementById("invoice-table");
let row = document.getElementById("item-info");
});;
<table class="table table-striped table-dark invoice-table">
<thead>
<tr class="head-contents">
<th scope="col">#</th>
<th scope="col-3">Description</th>
<th scope="col">Quanity</th>
<th scope="col">item number</th>
<th scope="col">item price</th>
<th scope="col">total price</th>
</tr>
</thead>
<tbody id="table-contents">
<tr id="item-info">
<th scope="row">1</th>
<td><input type="text"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><span></span></td>
</tr>
</tbody>
</table>
<button id="addItem">Add Item</button>
<script>
document.getElementById('addItem').addEventListener('click', () => {
let body = document.getElementById("table-contents");
let row = document.getElementById("item-info");
var para = document.createElement("tr")
para.innerHTML = `
<th scope="row">1</th>
<td><input type="text"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><input type="number"></td>
<td><span></span></td>
`;
body.appendChild(para);
})
</script>
You need to create a template and then append to it every time you click on the button.
let addedItem = document.getElementById("addItem").addEventListener("click", () => {
let item = document.getElementById("table-contents");
item.insertAdjacentHTML('beforeend', "<tr id='item-info'> <th scope='row'>1</th> <td><input type='text'></td> <td><input type='number'></td> <td><input type='number'></td> <td><input type='number'></td> <td><span></span></td></tr>");
});;
Don't forget the button within your HTML:
<button id="addItem">Add New Row</button>
This worked for me, let me know if you have more questions.
Check out the code snippet. This code worked for me. Depending on what actually you want to archive you can/ should tweak this to your needs. Like adding an id that actually increments with each row, and making an additional function to calculate your Total columns.
But since that wasn't included in the answer, I leave that up to you :)
// ARRAY FOR HEADER.
const arrHead = ['#', 'One', 'Two', 'Three'];
// SIMPLY ADD OR REMOVE VALUES IN THE ARRAY FOR TABLE HEADERS.
// FIRST CREATE A TABLE STRUCTURE BY ADDING A FEW HEADERS AND
// ADD THE TABLE TO YOUR WEB PAGE.
function createTable() {
var empTable = document.createElement('table');
empTable.setAttribute('id', 'empTable'); // SET THE TABLE ID.
var tr = empTable.insertRow(-1);
for (var h = 0; h < arrHead.length; h++) {
var th = document.createElement('th'); // TABLE HEADER.
th.innerHTML = arrHead[h];
tr.appendChild(th);
}
var div = document.getElementById('cont');
div.appendChild(empTable); // ADD THE TABLE TO YOUR WEB PAGE.
}
// ADD A NEW ROW TO THE TABLE
function addRow() {
var empTab = document.getElementById('empTable');
var rowCnt = empTab.rows.length; // GET TABLE ROW COUNT.
var tr = empTab.insertRow(rowCnt); // TABLE ROW.
tr = empTab.insertRow(rowCnt);
for (var c = 0; c < arrHead.length; c++) {
var td = document.createElement('td'); // TABLE DEFINITION.
td = tr.insertCell(c);
if (c == 0) { // FIRST COLUMN.
// ADD A BUTTON.
var button = document.createElement('input');
// SET INPUT ATTRIBUTE.
button.setAttribute('type', 'button');
button.setAttribute('value', 'Remove');
// ADD THE BUTTON's 'onclick' EVENT.
button.setAttribute('onclick', 'removeRow(this)');
td.appendChild(button);
}
else {
// CREATE AND ADD TEXTBOX IN EACH CELL.
var ele = document.createElement('input');
ele.setAttribute('type', 'text');
ele.setAttribute('value', '');
td.appendChild(ele);
}
}
}
// DELETE TABLE ROW.
function removeRow(oButton) {
var empTab = document.getElementById('empTable');
empTab.deleteRow(oButton.parentNode.parentNode.rowIndex); // BUTTON -> TD -> TR.
}
// EXTRACT AND SUBMIT TABLE DATA.
function sumbit() {
var myTab = document.getElementById('empTable');
var values = new Array();
// LOOP THROUGH EACH ROW OF THE TABLE.
for (row = 1; row < myTab.rows.length - 1; row++) {
for (c = 0; c < myTab.rows[row].cells.length; c++) { // EACH CELL IN A ROW.
var element = myTab.rows.item(row).cells[c];
if (element.childNodes[0].getAttribute('type') == 'text') {
values.push(element.childNodes[0].value);
}
}
}
console.log(values);
}
table
{
width: 70%;
font: 17px Calibri;
}
table, th, td
{
border: solid 1px #DDD;
border-collapse: collapse;
padding: 2px 3px;
text-align: center;
color: green;
}
<body onload="createTable()">
<input type="button" id="addRow" value="Add New Row" onclick="addRow()" />
</p>
<!--THE CONTAINER WHERE WE'll ADD THE DYNAMIC TABLE-->
<div id="cont"></div>
<p><input type="button" id="bt" value="Sumbit Data" onclick="sumbit()" /></p>
</body>

How to Get InnerHTML for Table Cell instead of an object or NaN

I am attempting to create a string that contains all of the data within an HTML table using JavaScript (open to changing to JQuery). By using this method below, I receive an NaN value, instead of the data (numbers).
function Ard() {
var table = document.getElementById("tblData");
var dataStr = "";
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
var toAdd = col;
dataStr += toAdd;
}
}
};
I have also tried a jQuery method but it only returned an HTML object. It should be noted that when printing the 'col' value to the console, the data is collected properly (actual values).
The table I'm using is editable by the user, but it saves as a standard HTML table. Here is the basic code for the table below if it helps solve the problem.
<table id="tblData" class="table table-hover">
<thead>
<tr>
<th>Date</th>
<th>Time</th>
<th>Treatment Number</th>
<th>Cell Number</th>
<th>Waste Container Number</th>
</tr>
</thead>
<tbody></tbody>
</table>
Any ideas towards how to get the innerHTML and add it properly to the string?
I would also like to do this with a row by column loop (set of two for or each loops maybe?) so that I know what column I'm grabbing from.
Since you are OK to use jquery,
var dataStr = "";
$('#tblData > tbody').each(function(e) {
dataStr += $(this).text();
});
console.log(dataStr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="tblData" class="table table-hover">
<thead>
<tr>
<th>Date</th>
<th>Time</th>
<th>Treatment Number</th>
<th>Cell Number</th>
<th>Waste Container Number</th>
</tr>
</thead>
<tbody>
<tr>
<td>10101</td>
<td>20202</td>
<td>30303</td>
<td>40404</td>
<td>50505</td>
</tr>
<tr>
<td>wowowo</td>
<td>sksksk</td>
<td>alalal</td>
<td>qpqpqp</td>
<td>zmzmzm</td>
</tr>
</tbody>
</table>
If you want the dataStr to have the <td> tags also, you should use,
dataStr += $(this).html()
EDIT
If you also want to access the current column index, you can use this. But here, the dataStr would finally contain a single line string concatenating all the texts inside <td> tags.
$('#tblData > tbody > tr > td').each(function(e) {
var currentColNo = $(this).index();
dataStr += $(this).html();
});
With jQuery you could select all rows and the iterate over them and get the text:
var str = "", values = [];
$("#tblData").find('tbody').find('tr').each(function() {
//You can concatenate a string or push the values to an array
str += $(this).text();
values.push($(this).text());
});
console.log(str, values);
You can do it with pure js:
function Ard() {
var table = document.querySelectorAll("#tblData tr th");
var dataStr = "";
for (var i = 0; i < table.length; i++) {
dataStr += table[i].innerHTML;
}
};
JSFiddle Demo
This will get you all text from the table <td>s and post it into a textarea (just for demonstration purposes):
$('#out').val($('#tblData td').text())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tblData" class="table table-hover">
<thead>
<tr>
<th>Date</th>
<th>Time</th>
<th>Treatment Number</th>
<th>Cell Number</th>
<th>Waste Container Number</th>
</tr>
</thead>
<tbody>
<tr>
<td>some</td><td>extra</td><td>data</td>
</tr>
</tbody>
</table>
<textarea id="out" rows=10 cols=60></textarea>
Update:
If you "just" want to put the <td> contents into a single variable you could do:
var str=$('#tblData td').text()
I extended your example so you will actually get a result.

Categories

Resources