Button not rendering where expected - javascript

I am clicking a button in my HTML and expecting a table to be created with X amount of rows depending on the for loop and then at the end of each row a button.
I am expecting the output to look like this:
<table>
<tr>
<td> first element </td>
<button> </button>
</tr>
<tr>
<td> first element </td>
<button> </button>
</tr>
</table>
However for some reason the button does not render on the first row:
<table>
<tr>
<td> first element </td>
</tr>
<tr>
<td> first element </td>
<button> </button>
</tr>
</table>
This is the code I am using:
function makeHTMLMatchesTable(array){
var table = document.createElement('table');
var button = document.createElement('button');
button.setAttribute("id", "unMatchButton");
console.log(array.length, 'ARRAY');
for (var i = 0; i < array.length; i++) {
console.log(array[i], 'ai');
var row = document.createElement('tr');
var cell = document.createElement('td');
cell.textContent = array[i];
row.appendChild(cell);
row.appendChild(button);
table.appendChild(row);
}
return table;
}

I am expecting the output to look like this
The structure you quote is invalid. You can't have button as a direct child of tr. From the spec for tr, the only things that can be in a tr element are td, th, or script-supporting elements.
However for some reason the button does not render on the first row:
Because you've only created one button element, and then appended it to two separate rows. Appending it doesn't clone it, it moves it from its old parent (if any) to a new one.
To fix it:
Create a new button each time you want a new button (with a new id; id values must be unique in a document).
Append the button to a td, not to a tr.
Example:
function makeHTMLMatchesTable(array) {
var table = document.createElement('table');
for (var i = 0; i < array.length; i++) {
var row = document.createElement('tr');
var cell = document.createElement('td');
cell.textContent = array[i];
row.appendChild(cell);
cell = document.createElement('td'); // Second td
var button = document.createElement('button'); // New button for each
button.setAttribute("id", "unMatchButton" + i); // Unique id
cell.appendChild(button); // Button in cell
row.appendChild(cell); // Add second cell
table.appendChild(row);
}
return table;
}
document.body.appendChild(
makeHTMLMatchesTable(["one", "two", "three"])
);

you need to create a new button for each row
function makeHTMLMatchesTable(array){
var table = document.createElement('table');
console.log(array.length, 'ARRAY');
for (var i = 0; i < array.length; i++) {
console.log(array[i], 'ai');
var row = document.createElement('tr');
var cell = document.createElement('td');
cell.textContent = array[i];
var button = document.createElement('button');
button.setAttribute("id", "unMatchButton");
row.appendChild(cell);
row.appendChild(button);
table.appendChild(row);
}
return table;
}

Related

Preserve HTML table location after dynamic update

When I update an HTML table using appendChild(), the entire table is moved to the bottom of the document. How do I preserve the location of the table in the DOM?
My example is also posted on JSFiddle.
<!--I want the existing table below to stay fixed in place after new rows are added.-->
<table id="table">
<tr>
<td> Table Cell 1</td>
<td> Table Cell 2</td>
</tr>
</table>
<!--The following button will add rows, but also move the table. How do I stop the move?-->
<input type="button" value="ADD NEW ROWS." onclick="generate_table()">
<script>
// This function just creates new rows for the table
function generate_table() {
var body = document.getElementsByTagName("body")[0];
var tbl = document.getElementById("table");
var tblBody = document.createElement("tbody");
for (var i = 0; i < 2; i++) {
var row = document.createElement("tr");
for (var j = 0; j < 2; j++) {
var cell = document.createElement("td");
var cellText = document.createTextNode("cell " + i + ", column " + j);
cell.appendChild(cellText);
row.appendChild(cell);
}
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
body.appendChild(tbl);
}
</script>
<style>
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
</style>
Remove the following line, you don't need it.
body.appendChild(tbl);
The table node is already a part of the Document Object Model, you don't need to add it again. By appending the element to body, you are moving it from the current position to the end of the body node.
As a rule of thumb, you need to use appendChild, only if the element was created dynamically using createElement.

How can i add pagination on table using jquery?

I have a table having data in JSON form fetch from local-disk, i read all the data using getJSON method and put into table on the other hand i store the json data into local-storage for edit and delete operations , i just want to add pagination so that i see limited records on my page. I have no idea how to make a pagination on table How can i do this through jquery?
Javascript
$.getJSON("2-fedtest.json", function(data) {
if (localStorage.getItem("2_fedtest_json_file") == undefined) {
trans = data.listing_data;
localStorage.setItem('2_fedtest_json_file', JSON.stringify(trans));
} else {
trans = JSON.parse(localStorage.getItem("2_fedtest_json_file"));
}
response(trans);
});
function response(e) {
let table = document.getElementById("transaction_table");
let row, cell, button;
for (let i = 0; i < e.length; i++) {
row = table.insertRow();
cell = row.insertCell();
cell.textContent = e[i].document_first_name;
cell = row.insertCell();
cell.textContent = e[i].email;
cell = row.insertCell();
cell.textContent = e[i].document_dob;
cell = row.insertCell();
cell.textContent = e[i].used_services_in_request;
cell = row.insertCell();
const detailbutton = document.createElement("button");
////////////// Detail Button///////////
detailbutton.id = i;
detailbutton.innerHTML = 'Detail';
$(detailbutton).click(function(e) {
var button_click_id = detailbutton.id;
});
cell.appendChild(detailbutton);
////////// Edit Button///////////////
cell = row.insertCell();
const editebutton = document.createElement("button");
editebutton.id = i;
editebutton.innerHTML = 'Edit'; 
$(editebutton).click(function(e) {
var button_click_id = detailbutton.id;
});
cell.appendChild(editebutton);
////////End Edit Button//////////////
//
///////Delete Button////////
cell = row.insertCell();
const deletebutton = document.createElement("button");
deletebutton.style.color = "#fff";
deletebutton.id = i;
deletebutton.style.background = "red";
deletebutton.innerHTML = 'Delete';
$(deletebutton).click(function(e) {
});
cell.appendChild(deletebutton);
}
});
Html
<table id="transaction_table" class="pagination">
<tr>
<th id="detail">Detail</th>
<th id="detail">Edit</th>
<th id="detail">Delete</th>
<tr>
</table>
If you have all the data already available to your program, then I’d imagine all you really need to do is hide all the elements except the first n, where n is the page size. Then add in a “next” button with an event listener that will hide the current n items while displaying the next n whenever clicked. A simple variable as a page number counter that increments when next is pressed and is used to index the relevant rows to show would work fine there. You can also add a “previous” button to do the opposite of the above.

Add table header for dynamic table in javascript

I'm trying to create a table in javascript and put a header on it. I tried to incorporate the answer from this SO question but perhaps I didn't include it in the right place. The body of the table works perfectly, but the header appends as a bunch of text to the top instead of a nicely formatted header. Here is the code:
function generate_table() {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
//var header = document.createElement("header");
var header = '<tr><th>Country</th><th>City</th></tr>';
//var header = "<th>Header</th>";
var tblBody = document.createElement("tbody");
// creating all cells
for (var i = 0; i < results.weak_sent.length; i++) {
// creates a table row
var row = document.createElement("tr");
for (var j = 0; j < 2; j++) {
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var cell = document.createElement("td");
if (j == 0) {
var cellText = document.createTextNode(results.weak_sent_num[i]);
} else {
var cellText = document.createTextNode(results.weak_sent[i]);
}
cell.appendChild(cellText);
row.appendChild(cell);
}
// add the row to the end of the table body
tblBody.appendChild(row);
}
tbl.append(header)
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}
It prints the rows and the columns correctly, but instead of interpreting the <tr><th> as HTML tags it just prints them out as text. I've also noticed that if the table text contains any HTML tags, like <strong> or <b>, they are returned as plain text as well. How can I make them be read as HTML. I have a CSS page as well but there's no reset or anything (intentionally) affecting the use of bold or tables. Here's my result
<tr><th>Country</th><th>City</th></tr>
1 Row 1 text
2 Row <b>2</b> text
Solution1
The way you are appending tbody rows, you can insert the heading as well. So instead of tbl.append(header) and defining the header string, you can use something like below:
results = {
weak_sent: [
"row 1 data",
"row 2 data"
],
weak_sent_num: [1,2]
}
function generate_table() {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
//var header = document.createElement("header");
// var header = '<tr><th>Country</th><th>City</th></tr>';
var header= document.createElement('thead')
var headingRow = document.createElement('tr')
var headingCell1 = document.createElement('td')
var headingText1 = document.createTextNode('country')
headingCell1.appendChild(headingText1)
headingRow.appendChild(headingCell1)
var headingCell2 = document.createElement('td')
var headingText2 = document.createTextNode('City')
headingCell2.appendChild(headingText2)
headingRow.appendChild(headingCell2)
header.appendChild(headingRow)
tbl.appendChild(header)
//var header = "<th>Header</th>";
var tblBody = document.createElement("tbody");
// creating all cells
for (var i = 0; i < results.weak_sent.length; i++) {
// creates a table row
var row = document.createElement("tr");
for (var j = 0; j < 2; j++) {
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var cell = document.createElement("td");
if (j == 0) {
var cellText = document.createTextNode(results.weak_sent_num[i]);
} else {
var cellText = document.createTextNode(results.weak_sent[i]);
}
cell.appendChild(cellText);
row.appendChild(cell);
}
// add the row to the end of the table body
tblBody.appendChild(row);
}
// This is for the quick solution
// tbl.innerHTML = header
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}
generate_table()
Solution2
As a quick solution you can use innerHTML property, as shown below.
results = {
weak_sent: [
"row 1 data",
"row 2 data"
],
weak_sent_num: [1,2]
}
function generate_table() {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
//var header = document.createElement("header");
var header = '<tr><th>Country</th><th>City</th></tr>';
//var header = "<th>Header</th>";
var tblBody = document.createElement("tbody");
// creating all cells
for (var i = 0; i < results.weak_sent.length; i++) {
// creates a table row
var row = document.createElement("tr");
for (var j = 0; j < 2; j++) {
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var cell = document.createElement("td");
if (j == 0) {
var cellText = document.createTextNode(results.weak_sent_num[i]);
} else {
var cellText = document.createTextNode(results.weak_sent[i]);
}
cell.appendChild(cellText);
row.appendChild(cell);
}
// add the row to the end of the table body
tblBody.appendChild(row);
}
// This is for the quick solution
tbl.innerHTML = header
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}
generate_table()

Click event for dynamically created button

I have a function (seen at the very bottom) that creates a HTML table and depending on the contents of an array it will populate it with X number of rows. each row has 2 cells, the value of the array in that position and a button next to it.
I want to be able to click these buttons and delete the particular row from the table.
However, I cant use a standard on click event:
function unMatchButtonClicked(){
var button = document.getElementById('unmatch').onclick;
}
Because it will throw an error that the id does not exist AND because I have potentially X number of rows, I'll need some sort of for loop.
My psuedo attempt is:
for (var i=0; i < table.length; i++){
var button = document.getElementById('unmatch')
if (button.clicked){
remove row}
}
I can't quite vision how to do it though.
Only pure JS solutions as well please, no Jquery.
EDIT :
function makeHTMLMatchesTable(array){
var table = document.createElement('table');
for (var i = 0; i < array.length; i++) {
var row = document.createElement('tr');
var cell = document.createElement('td');
cell.textContent = array[i];
row.appendChild(cell);
cell = document.createElement('td');
var button = document.createElement('button');
button.setAttribute("id", "unMatchButton" +i);
cell.appendChild(button);
row.appendChild(cell);
table.appendChild(row);
}
return table;
}
Add event when you create elements using addEventListener() :
...
var button = document.createElement('button');
button.setAttribute("id", "unMatchButton" +i);
button.addEventListener("click", clickEventFunction, false);
...
Hope this helps.
function makeHTMLMatchesTable(array) {
var table = document.createElement('table');
table.setAttribute("border", 1);
for (var i = 0; i < array.length; i++) {
var row = document.createElement('tr');
var cell = document.createElement('td');
cell.textContent = array[i];
row.appendChild(cell);
cell = document.createElement('td');
var button = document.createElement('button');
button.setAttribute("id", "unMatchButton" + i);
button.textContent = "Delete";
//click Event
button.addEventListener("click", delete_row, false);
cell.appendChild(button);
row.appendChild(cell);
table.appendChild(row);
}
return table;
}
function delete_row() {
this.parentNode.parentNode.remove();
}
document.body.appendChild(makeHTMLMatchesTable(['Cell 1','Cell 2','Cell 3','Cell 4']));
Add a click handler on the <table>. You can then check the event.target if the click has been triggered by a <button>. If yes travel up the DOM until you reach the surrounding <tr> element and call .remove() on it.
function makeHTMLMatchesTable(array) {
var table = document.createElement('table');
for (var i = 0; i < array.length; i++) {
var row = document.createElement('tr');
var cell = document.createElement('td');
cell.textContent = array[i];
row.appendChild(cell);
cell = document.createElement('td');
var button = document.createElement('button');
button.setAttribute("id", "unMatchButton" + i);
button.textContent = "Remove";
cell.appendChild(button);
row.appendChild(cell);
table.appendChild(row);
}
table.addEventListener("click", removeRow, false);
return table;
}
function removeRow(evt) {
if (evt.target.nodeName.toLowerCase() === "button") {
evt.target.parentNode.parentNode.remove(); // .parentNode.parentNode == <tr>
}
}
document.body.appendChild(makeHTMLMatchesTable([1, 2, 3, 4]));
The details are commented within the source. There's a PLUNKER available as well.
<!DOCTYPE html>
<html>
<head>
<style>
table,
td {
border: 1px solid red;
}
button {
height: 24px;
width: 24px;
}
</style>
</head>
<body>
<script>
var array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function makeHTMLMatchesTable(array) {
var table = document.createElement('table');
for (var i = 0; i < array.length; i++) {
var row = document.createElement('tr');
var cell = document.createElement('td');
cell.textContent = array[i];
row.appendChild(cell);
cell = document.createElement('td');
var button = document.createElement('button');
button.setAttribute("id", "unMatchButton" + i);
cell.appendChild(button);
row.appendChild(cell);
table.appendChild(row);
}
// This is added to comlete this function
return document.body.appendChild(table);
}
makeHTMLMatchesTable(array1);
// Reference table
var table = document.querySelector('table');
/*
| - Add an eventListener for ckick events to the table
| - if event.target (element clicked; i.e. button)
| is NOT the event.currentTarget (element that
| is listening for the click; i.e. table)...
| - ...then assign a variable to event.target's
| id (i.e. #unMatchButton+i)
| - Next extract the last char from the id (i.e. from
| #unMatchButton+i, get the 'i')
| - Then convert it into a real number.
| - Determine the row to which the button (i.e. event
| .target) belongs to by using the old rows method.
| - while row still has children elements...
| - ...remove the first child. Repeat until there are
| no longer any children.
| - if the parent of row exists (i.e. table which it
| does of course)...
| - ...then remove row from it's parents
*/
table.addEventListener('click', function(event) {
if (event.target !== event.currentTarget) {
var clicked = event.target.id;
var i = clicked.substr(-1);
var idx = Number(i);
var row = this.rows[idx];
while (row.children > 0) {
row.removeChild(row.firstChild);
}
if (row.parentNode) {
row.parentNode.removeChild(row);
}
return false
}
}, false);
</script>
</body>
</html>

Get selected row value using javascript

I have dynamically add the table on html button click. Add the teamname,teamid,radio button.
HTML attributes:
<input type="button" value="Generate a table." onclick="generate_table()">
Javascript function :
function generate_table()
{
var body = document.getElementsByTagName("body")[0];
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
var teamrecord = "test";
for (var i = 0; i < teamrecord.length; i++) {
var row = document.createElement("tr");
var cell = document.createElement("td");
var cell1 = document.createElement("td");
var cell2 = document.createElement("td");
var cellText = document.createTextNode("teamrecord");
var cellId = document.createTextNode("teamid");
var radio = document.createElement("INPUT");
radio.setAttribute("type", "radio");
radio.setAttribute("name", "radio");
cell.appendChild(cellText);
cell1.appendChild(cellId);
cell2.appendChild(radio);
row.appendChild(cell);
row.appendChild(cell1);
row.appendChild(cell2);
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
body.appendChild(tbl);
}
4 rows with 3 columns will generate on the button click , Now i need to get the details on the radio button click.
If i select the radio button from the first row i need to show the teamid in alert box? how can I achieve this in javascript?
try this code below should alert teamid cell's innerText
<input type="button" value="Generate a table." onclick="generate_table()">
function generate_table()
{
var body = document.getElementsByTagName("body")[0];
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
var teamrecord = "test";
for (var i = 0; i < teamrecord.length; i++) {
var row = document.createElement("tr");
var cell = document.createElement("td");
var cell1 = document.createElement("td");
var cell2 = document.createElement("td");
var cellText = document.createTextNode("teamrecord");
var cellId = document.createTextNode("teamid");
var radio = document.createElement("INPUT");
radio.setAttribute("type", "radio");
radio.setAttribute("name", "radio");
//here we set value of radio button based on element index and we set a classname for teamid cell
radio.setAttribute("value", i);
cell1.setAttribute("class", "selected_teamid");
//here we add click event
radio.setAttribute("onclick", "getteamid("+i+")");
cell.appendChild(cellText);
cell1.appendChild(cellId);
cell2.appendChild(radio);
row.appendChild(cell);
row.appendChild(cell1);
row.appendChild(cell2);
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
body.appendChild(tbl);
}
function getteamid(i){
alert(document.getElementsByClassName("selected_teamid")[i].innerText);
}
<input type="button" value="Generate a table." onclick="generate_table()">
just add this line, before appending the radio element:
radio.onclick = function(){alert(this.value};
You just need to add an event handler to the radio button when you create it:
...
radio.addEventListener('click', radioButtonClick, false);
...
function radioButtonClick() {
alert(this.getAttribute('value'));
}
This requires that you set the value of the radio button to your team id, or store it on the radio button (which will be the this inside the event handler) in some other way.
You aren't passing a teamid anywhere, so I assumed the teamid is the index of the looped array.
var generate_table = function()
{
var body = document.getElementsByTagName("body")[0];
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
var teamrecord = "test";
for (var i = 0; i < teamrecord.length; i++) {
var row = document.createElement("tr");
var cell = document.createElement("td");
var cell1 = document.createElement("td");
var cell2 = document.createElement("td");
var cellText = document.createTextNode("teamrecord");
var cellId = document.createTextNode("teamid");
var radio = document.createElement("INPUT");
radio.setAttribute("type", "radio");
radio.setAttribute("name", "radio");
radio.setAttribute('data-team', i); // passing the team id
cell.appendChild(cellText);
cell1.appendChild(cellId);
cell2.appendChild(radio);
row.appendChild(cell);
row.appendChild(cell1);
row.appendChild(cell2);
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
body.appendChild(tbl);
}
// add an event listener on a dynamic element, and alert the team id
document.addEventListener('click', function(e) {
if(e.target && e.target.hasAttribute('data-team')) {
alert(e.target.getAttribute('data-team'));
}
});
You have several way to achieve that:
The easiest way I think is to add an attribute 'teamid' to the radio button. Then just listen for click event and get this value back.
radio.setAttribute('teamid', teamid);
radio.addEventListener('click', onRadioClick);
function onRadioClick(domEvent){
console.log(domEvent.target.getAttribute('teamid'));
}
For me it is not the best way because you need to put some information in the DOM... In my opinion, it would be better to separate the presentation and the data :
var tableData = [
{teamId: 'someId0', title:'title0', someData:'...' },
{teamId: 'someId1', title:'title1', someData:'...' },
{teamId: 'someId2', title:'title2', someData:'...' }
];
for (var i = 0, n = tableData.length ; i < n ; i++){
var rowData = tableData[i];
// Create the row using rowData
// ...
radio.setAttribute('teamid', rowData.teamId);
radio.addEventListener('click', onRadioClick.bind(rowData));
// ...
}
function onRadioClick(domEvent){
// Here this represent data of the row clicked
console.log(this.teamId);
}
I think it's easier to manage because every data are JS side... You don't store any data in the DOM... However both works ;) Hope it helps
radio.setAttribute("onclick", "anotherFunction(this)")
and after this function create anotherFunction():
function anotherFunction(object){
alert(object.parentNode.parentNode.firstChild.innerHTML);
}

Categories