How to add Row into dynamic html table? - javascript

I have created one div that is not visible, in that div main table is hidden and I'm cloning that table into another div. that div id is main-div.
I want to add a row into that newly generated table? how to append rows using jQuery?
generate table function, delete table function, and remove row function are in working condition.
adding new row using javascript or Jquery which better way to handle? any hint?
// ==================== //
// Add aggregate Table//
// ==================== //
var aggTableNum = 0;
$('.addAggregatorCompo').click(function (e) {
const originTable = document.getElementById('aggregator-table');
let newTable = originTable.cloneNode(true);
newTable.id = 'newAggTable' + ++aggTableNum;
newTable.querySelectorAll('input').forEach((element) => {
element.value = '';
});
$('#main-div').append(newTable);
});
// ==================== //
// Delete Component //
// ==================== //
$('#main-div').on('click', '.delete-component', function (e) {
e.preventDefault(); // in case it is not a type=button and the table is wrapped in a form
this.closest('table').remove();
});
// ==================== //
// Delete Records//
// ==================== //
$('#main-div').on('click', '.delete-record', function () {
$('table tbody')
.find('input[name="record"]')
.each(function () {
if ($(this).is(':checked')) {
$(this).parents('tr').remove();
}
});
});
// ==================== //
// Add Aggregate records //
// ==================== //
$('#main-div').on('click', '.add-record', function () {
$('<tr>')
.append($('<td>').append('input'))
.append($('<td>').append('text2'))
.append($('<td>').append('text3'))
.append($('<td>').append('text4'));
});
#aggregator-table {
display: none;
}
table {
border-collapse: collapse;
margin: 1em;
}
thead {
background-color: lightblue;
}
td,
th {
border: solid grey 1px;
padding: 1em;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button style="margin: 1%" class="addAggregatorCompo">Add Table</button>
<table id="aggregator-table" class="component-base">
<thead>
<th colspan="6">Aggregator</th>
<tr>
<th> Select</th>
<th> Column 1 </th>
<th> Column 2 </th>
<th> Column 3 </th>
<th> Column 4 </th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" name="record"></td>
<td>
<input id='column1'>
</input>
</td>
<td><input id="column2">
</input></td>
<td>
<input id="column3">
</input>
</td>
<td>
<input id="4">
</input>
</td>
</tr>
<tr>
<td>
<button style="margin: 1%" class="add-record">add Record</button>
</td>
<td>
<button class="delete-component" style="margin: 1%">Delete Table </button>
</td>
<td>
<button class="delete-record" style="margin: 1%">Delete Record </button>
</td>
</tr>
</tbody>
</table>
<div class="generate-div" id="main-div"></div>
jsFiddle - >https://jsfiddle.net/shreekantbatale2/h2sv1q9p/

You've done the work of creating the new tr in memory. All you need to do is add it to the DOM. This can be achieved using appendTo():
$('#main-div').on('click', '.add-record', function() {
let $tbody = $(this).closest('tbody');
$('<tr>')
.append($('<td>').append('input'))
.append($('<td>').append('text2'))
.append($('<td>').append('text3'))
.append($('<td>').append('text4'))
.appendTo($tbody);
});
// ==================== //
// Add aggregate Table//
// ==================== //
var aggTableNum = 0;
$('.addAggregatorCompo').click(function(e) {
const originTable = document.getElementById('aggregator-table');
let newTable = originTable.cloneNode(true);
newTable.id = 'newAggTable' + ++aggTableNum;
newTable.querySelectorAll('input').forEach((element) => {
element.value = '';
});
$('#main-div').append(newTable);
});
// ==================== //
// Delete Component //
// ==================== //
$('#main-div').on('click', '.delete-component', function(e) {
e.preventDefault(); // in case it is not a type=button and the table is wrapped in a form
this.closest('table').remove();
});
// ==================== //
// Delete Records//
// ==================== //
$('#main-div').on('click', '.delete-record', function() {
$('table tbody')
.find('input[name="record"]')
.each(function() {
if ($(this).is(':checked')) {
$(this).parents('tr').remove();
}
});
});
// ==================== //
// Add Aggregate records //
// ==================== //
$('#main-div').on('click', '.add-record', function() {
let $tbody = $(this).closest('table').find('tbody');
$('<tr>')
.append($('<td>').append('input'))
.append($('<td>').append('text2'))
.append($('<td>').append('text3'))
.append($('<td>').append('text4'))
.appendTo($tbody);
});
#aggregator-table {
display: none;
}
table {
border-collapse: collapse;
margin: 1em;
}
thead {
background-color: lightblue;
}
td,
th {
border: solid grey 1px;
padding: 1em;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button style="margin: 1%" class="addAggregatorCompo">Add Table</button>
<table id="aggregator-table" class="component-base">
<thead>
<th colspan="6">Aggregator</th>
<tr>
<th>Select</th>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" name="record"></td>
<td><input id="column1" /></td>
<td><input id="column2" /></td>
<td><input id="column3" /></td>
<td><input id="4" /></td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
<button style="margin: 1%" class="add-record">add Properties</button>
</td>
<td>
<button class="delete-component" style="margin: 1%">Delete Table </button>
</td>
<td>
<button class="delete-record" style="margin: 1%">Delete Record </button>
</td>
</tr>
</tfoot>
</table>
<div class="generate-div" id="main-div"></div>
Also note in your HTML that <input /> elements do not have a closing tag.

Related

Why does my checkbox change-handling select or deselect all rows in every table instead of just the current one?

I have multiple tables on a page. Each table, has a "check all" checkbox in the header. In the body, there is another checkbox for each row.
When the user checks each boy row, then a active class is applied and highlights the marked row, and the counter increases/decreases.
I have a problem with the check all function.
When the user selects the check all checkbox in the header, then it should select all the rows in just that one table. I can only get it to check all the rows across all the tables. Also the counter counts all the rows across all the tables, rather than just that one table.
Where am I going wrong?
Here is my code:
// https://gomakethings.com/a-vanilla-js-foreach-helper-method/
var forEach = function forEach(arr, callback) {
Array.prototype.forEach.call(arr, callback);
};
var tableInputs = document.querySelectorAll('.table tbody td .form-check-input');
var tableSelectAll = document.querySelectorAll('.table thead th .form-check-input');
var count = document.querySelector('.output span')
forEach(tableInputs, function(element) {
element.addEventListener('change', function() {
// active class to make row blue
if (element.checked) {
element.parentNode.parentNode.classList.add('active');
} else {
element.parentNode.parentNode.classList.remove('active');
}
// set count to -
var numberSelected = 0;
// count number of checked
for (var i = 0; i < tableInputs.length; i++) {
if (tableInputs[i].checked == true) {
numberSelected++;
}
}
// display the count
count.innerHTML = numberSelected;
});
});
forEach(tableSelectAll, function(element) {
element.addEventListener('change', function() {
if (element.checked == true) {
forEach(tableInputs, function(input) {
input.parentNode.parentNode.classList.add('active');
input.checked = true;
// set count to -
var numberSelected = 0;
// count number of checked
for (var i = 0; i < tableInputs.length; i++) {
if (tableInputs[i].checked == true) {
numberSelected++;
}
}
// display the count
count.innerHTML = numberSelected;
});
} else {
forEach(tableInputs, function(input) {
input.parentNode.parentNode.classList.remove('active');
input.checked = false;
count.innerHTML = 0;
});
}
});
});
.form-check-input {
border: solid 1px #000;
position: relative;
}
tr.active {
background-color: lightblue;
}
body { margin: 0; zoom: .88; }
p { margin: 0; }
<div class="container">
<div class="row">
<div class="col-12">
<p>Table 1</p>
<table class="table table-sm table-borderless">
<thead>
<tr>
<th><input class="form-check-input" type="checkbox" value=""></th>
<th>Request date</th>
<th>Name</th>
<th>Organisation/Employer</th>
<th>Selected Course(s)</th>
</tr>
</thead>
<tbody>
<tr>
<td><input class="form-check-input" type="checkbox" value=""></td>
<td>10/10/2014</td>
<td>Clark Kent</td>
<td><span>Daily Planet</span></td>
<td><span>Flight</span></td>
</tr>
<tr>
<td><input class="form-check-input" type="checkbox" value=""></td>
<td>10/10/2014</td>
<td>Hal Jordan</td>
<td><span>Green Lantern Corps</span></td>
<td>Lighting</td>
</tr>
<tr>
<td><input class="form-check-input" type="checkbox" value=""></td>
<td>10/10/2014</td>
<td>Arthur Curry</td>
<td><span>Atlantis Water</span></td>
<td>Aquatics</td>
</tr>
</tbody>
</table>
<p>Table 2</p>
<table class="table table-sm table-borderless ">
<thead>
<tr>
<th><input class="form-check-input" type="checkbox" value=""></th>
<th>Request date</th>
<th>Name</th>
<th>Organisation/Employer</th>
<th>Selected Course(s)</th>
</tr>
</thead>
<tbody>
<tr>
<td><input class="form-check-input" type="checkbox" value=""></td>
<td>10/10/2014</td>
<td>Barry Allen</td>
<td><span>Star Labs</span></td>
<td><span>Speed</span></td>
</tr>
<tr>
<td><input class="form-check-input" type="checkbox" value=""></td>
<td>10/10/2014</td>
<td>Bruce Wayne</td>
<td><span>Wayne Enterprises</span></td>
<td>Combat</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p class="output">Total selected: <span>0</span></p>
Regardless of the approach one always should break down the problem into specific tasks which for the OP's requirements are ...
initialize a checkbox related change handling.
on any checkbox' state change do update all checkbox depended states.
do update the checkbox counter at init time and at checkbox state change time.
for any (initially) checked checkbox update its related table row state as well.
The techniques/tools are Event Delegation and the Selectors API
At any checkbox state change the handler inspects the event target whether it belongs to the current table's header or body.
Based on this check one either, for the first case, needs to check/uncheck all of a current table's body-related checkboxes or, according to the second case, one needs to update the state of the sole header-related checkbox.
Updating the checkbox counter is achieved by the correct selector and the queried node list's length value.
function updateCheckboxCounter() {
document
.querySelector('.output > span')
.textContent = document
.querySelectorAll('table.table tbody [type="checkbox"]:checked')
.length;
}
function updateTableRowActiveState(checkboxNode) {
checkboxNode
.closest('tr')
.classList
.toggle('active', checkboxNode.checked);
}
function updateCheckboxDependedStates({ target }) {
const tableNode = target.closest('table.table');
if (target.matches('thead [type="checkbox"]')) {
tableNode
.querySelectorAll('tbody [type="checkbox"]')
.forEach(elmNode => {
elmNode.checked = target.checked;
updateTableRowActiveState(elmNode);
});
} else if (target.matches('tbody [type="checkbox"]')) {
tableNode
.querySelector('thead [type="checkbox"]')
.checked = Array
.from(
target
.closest('tbody')
.querySelectorAll('[type="checkbox"]')
)
.every(elmNode => elmNode.checked);
updateTableRowActiveState(target);
}
updateCheckboxCounter();
}
function init() {
document
.querySelectorAll('table.table')
.forEach(elmNode =>
elmNode.addEventListener('change', updateCheckboxDependedStates)
);
document
.querySelectorAll('table.table tbody [type="checkbox"]:checked')
.forEach(updateTableRowActiveState);
updateCheckboxCounter();
}
init();
.form-check-input {
border: solid 1px #000;
position: relative;
}
tr.active {
background-color: lightblue;
}
body { margin: 0; zoom: .88; }
p { margin: 0; }
<div class="container">
<div class="row">
<div class="col-12">
<p>Table 1</p>
<table class="table table-sm table-borderless">
<thead>
<tr>
<th><input class="form-check-input" type="checkbox" value=""></th>
<th>Request date</th>
<th>Name</th>
<th>Organisation/Employer</th>
<th>Selected Course(s)</th>
</tr>
</thead>
<tbody>
<tr>
<td><input class="form-check-input" type="checkbox" value=""></td>
<td>10/10/2014</td>
<td>Clark Kent</td>
<td><span>Daily Planet</span></td>
<td><span>Flight</span></td>
</tr>
<tr>
<td><input class="form-check-input" type="checkbox" value=""></td>
<td>10/10/2014</td>
<td>Hal Jordan</td>
<td><span>Green Lantern Corps</span></td>
<td>Lighting</td>
</tr>
<tr>
<td><input class="form-check-input" type="checkbox" value="" checked></td>
<td>10/10/2014</td>
<td>Arthur Curry</td>
<td><span>Atlantis Water</span></td>
<td>Aquatics</td>
</tr>
</tbody>
</table>
<p>Table 2</p>
<table class="table table-sm table-borderless ">
<thead>
<tr>
<th><input class="form-check-input" type="checkbox" value=""></th>
<th>Request date</th>
<th>Name</th>
<th>Organisation/Employer</th>
<th>Selected Course(s)</th>
</tr>
</thead>
<tbody>
<tr>
<td><input class="form-check-input" type="checkbox" value="" checked></td>
<td>10/10/2014</td>
<td>Barry Allen</td>
<td><span>Star Labs</span></td>
<td><span>Speed</span></td>
</tr>
<tr>
<td><input class="form-check-input" type="checkbox" value=""></td>
<td>10/10/2014</td>
<td>Bruce Wayne</td>
<td><span>Wayne Enterprises</span></td>
<td>Combat</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p class="output">Total selected: <span>0</span></p>

How can I have filtered/seach results page stay place be remembered whilst navigating back and fourth to it using 'mysite.com/?search=words' concept?

When I click the 'back' button or the 'refresh/reload' button or the 'forward' button in the browser my search/filtered results disappear. How can I have the results page stay with the keyword whilst navigating back and fourth to the page, or refreshing/reloading using mysite.com/?search=words concept?
JS
<body>
<script>
var input, table, rows, noMatches, tr, markInstance;
$(document).ready(function init() {
input = document.getElementById('myInput');
noMatches = document.getElementById('noMatches');
table = document.querySelectorAll('#myTable table tr:first-child');
rows = document.querySelectorAll('#myTable table tr');
markInstance = new Mark(table);
if(document.getElementById('myInput').value.length >0){
ContactsearchFX();
}
input.addEventListener('keyup', _.debounce(ContactsearchFX, 250));
});
function ContactsearchFX() {
resetContent();
markInstance.unmark({ done: highlightMatches });
}
function resetContent() {
$('.noMatchErrorText').remove();
//Remove this line to have a log of searches
//noMatches.textContent = '';
rows.forEach(function(row) {
$(row).removeClass('show');
});
}
function highlightMatches() {
markInstance.mark(input.value, {
each: showRow,
noMatch: onNoMatches,
exclude: ['.nonsearch']
})
}
function showRow(element) {
//alert(element);
$(element).parents('tr').addClass('show'); $(element).parents('tr').siblings('tr').addClass('show');
//Parents incase of several nestings
}
function onNoMatches(text) {
$('#myInput').after('<p class="noMatchErrorText">No records match: "' + text + '"</p>');
}
/* Prevents Return/Enter key from doing anything */
$(document).on('submit', 'form', function(e){
/* on form submit find the trigger */
if( $(e.delegateTarget.activeElement).not('input, textarea').length == 0 ){
/* if the trigger is not between selectors list, return super false */
e.preventDefault();
return false;
}
});
/* Prevents Return/Enter key from doing anything */
////
CSS
<style>
.input-wrap {
margin-bottom: 12px;
}
#myInput:invalid ~ .hints {
display: block;
}
#noMatches:empty, #noMatches:empty + .hints {
display: none;
}
.style1 tr {
display: none;
}
.style1 .show {
display: table-row;
}
#myTable table tr:first-child td mark {
background: orange;
font-weight: bold;
color: black;
}
mark {
background: initial;
} .style1 {
text-align: left;
}
</style>
HTML
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.11/lodash.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1
/mark.min.js"></script>
<head>
<body>
<div class="input-wrap">
<label>
Search
<input id="myInput" type="text" spellcheck="false"
placeholder="Search Titles"/>
<div class="hintsWrap">
<p id="noMatches"></p>
<p class="hints">
Hints: type "Title1", "Title2", "Title3"...
</p>
</div>
</label>
</div>
<br />
<br />
<br />
<br />
<table id="myTable" style="width: 100%" class="style1">
<tr>
<td>
<br />
<br />
<table style="width: 100%">
<tr>
<td>
<table style="width: 100%">
<tr>
<th class="style1">Type</th>
<td>type1</td>
</tr>
<tr>
<th class="style1">Title</th>
<td>title1</td>
</tr>
<tr>
<th class="style1">Description</th>
<td>description1</td>
</tr>
<tr>
<th class="style1">Date</th>
<td>date1</td>
</tr>
</table>
</td>
</tr>
</table>
<br />
<br />
<table style="width: 100%">
<tr>
<th class="style1">Type</th>
<td>type2</td>
</tr>
<tr>
<th class="style1">Title</th>
<td>title2</td>
</tr>
<tr>
<th class="style1">Description</th>
<td>description2</td>
</tr>
<tr>
<th class="style1">Date</th>
<td>date2</td>
</tr>
</table>
<br />
<br />
<table style="width: 100%">
<tr>
<th class="style1">Type</th>
<td>type3</td>
</tr>
<tr>
<th class="style1">Title</th>
<td>title3</td>
</tr>
<tr>
<th class="style1">Description</th>
<td>description3</td>
</tr>
<tr>
<th class="style1">Date</th>
<td>date3</td>
</tr>
</table>
<br />
<br />
Have been trying to integrate this piece of JS with not too much success
let input = document.getElementById('myInput'),
text = '';
// Keyup listener on input field
input.on('keyup', function(e) {
text = input.value;
// Add the text change to the browser history so users can go back/forward, and save url parameter in the history state
let historyState = {
'text': text,
}
window.history.pushState(historyState, null, `?search=${text}`);
});
// Run something after History listener finds search text exists
const updateSearch = function(text) {
console.log(`I found the search to be: ${text}`);
}
// History listener
$(window).on('popstate', function(e) {
let state = e.originalEvent.state
if (state !== null) { //If text exists
updateSearch(state.text)
} else { //If no text set (URL has no params)
console.log('no history state found')
}
});
You could either save search parameter in your local storage (or session storage) or you could keep it in your GET at all times.
let searchQuery = $(`#id`).val();
// based on either a click or blur event fire
let nQuery= retrieveItems(`interests`, `search`); //this is your GET query string which you assign to your URL
let searchArr = localStorage.getItem(`interests`); // retrieve the original array as an array
searchArr.push(searchQuery); // push the new value into the array
localStorage.setItem(`interests`, searchArr); // override the object property
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
Now, every time you "search" for something, it'll push it in your local storage (or again, you could make it a session storage). You can now either loop through the interests property and assign it to your href such as:
function retrieveItems(name, getName)
{
let searchqueries = localStorage.getItem('interests');
let urlParam = getName;
if (searchqueries.length > 0)
{
for (let i = 0; i < searchqueries .length; i++)
{
//keep in mind you need to insert a character or whatnot to be able to "break" the words the user looked up for.
urlParam += searchqueries[i];
}
return urlParam; //assign this to your
}
return [];
}
Now call the function, bind the return value to a variable and then assign that to your href.
Notice: I did not test this, so it could contain errors, or it will need some modification. Also, it could probably be done in a much neater way, but this is an example to get you going.

Delete Dynamic HTML table using table id?

I'm creating multiple tables from one table (table id = table6)
If I created a new table from table id ='table6', I want to delete that newly generated table using its table id. I have assigned table ids to the newly generated tables. what's wrong in my code?
I want to delete this HTML table. Any hint?
var aggTableNum = 0;
function generateAgg() {
const originTable = document.getElementById('table6');
const baseRowTbl = originTable.querySelector('tbody tr');
let newTable = originTable.cloneNode(true);
let newTbody = newTable.querySelector('tbody');
newTable.id = 'newAggTable' + ++aggTableNum;
// for (i = 0; i < 0; i++) {
// newTbody.appendChild(baseRowTbl.cloneNode(true));
// }
newTable.querySelectorAll('input').forEach((element) => {
element.value = '';
});
document.body.appendChild(newTable);
}
function tID() {
$('table').on('click', 'button', function (e) {
alert(e.delegateTarget.id);
var tbl = e.delegateTarget.id;
console.log(tbl);
// if (tbl) tbl.parentNode.removeChild(tbl);
$(tbl).remove();
});
}
table {
border-collapse: collapse;
margin: 1em;
}
thead {
background-color: lightblue;
}
td,
th {
border: solid grey 1px;
padding: 1em;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button style="margin: 1%" onclick="generateAgg()">Generate New Table</button>
<table id="table6">
<thead>
<th colspan="6">Table</th>
<tr>
<th> Column 1 </th>
<th> Column 2 </th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input>
</input>
</td>
<td><input>
</input></td>
</tr>
<tr>
<td>
<button style="margin: 1%" onclick="tID()">delete </button>
</td>
</tr>
</tbody>
</table>
JsFiddle link - > https://jsfiddle.net/shreekantbatale2/hn0286zd/8/
Though you are getting the table id's value, need to refer that properly with jquery with a leading # in the selector.
Change this:
$(tbl).remove();
...to:
$('#' + tbl).remove();
Then the table removes.

How to generate table from HTML?

So, I have to generate multiple tables from the HTML code. I can be generating multiple tables using pure javascript code but its too difficult to assign ids and getting its value. as I wrote javascript function generate_table
so I have created one sample HTML table from that HTML TAble how to generate the same Table again(multiple times). I have written too much javascript code for tables TD and TR. How to reduce that code.
I have many tables I want to regenerate the specific table so I cant use <table> tag. Any hint ? code sample ?
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 tblBody = document.createElement('tbody');
// creating all cells
for (var i = 0; i < 1; i++) {
var seqnumber = 1;
var seq = +1;
// creates a table row
var row2 = document.createElement('tr');
//====== table first row data =======//
var seq = document.createElement('td');
var seqText = document.createTextNode('Seq');
var l = document.createElement('td');
var seqText1 = document.createElement('input');
//===== seq generator =====//
seq.appendChild(seqText);
row2.appendChild(seq);
l.appendChild(seqText1);
row2.appendChild(l);
// add the row to the end of the table body
tblBody.appendChild(row2);
}
// 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');
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
<h3> TABLE FROM JAVA SCRIPT</h3>
<input type="button" value="Generate a table." onclick="generate_table()" />
<h3> TABLE FROM HTML</h3>
<table id="table6">
<tr>
<th colspan="2">Aggregator</th>
</tr>
<tr>
<th> Column Name </th>
<th> Function </th>
</tr>
<tr>
<td> <input> </td>
<td> <input> </td>
</tr>
</table>
<input type="button" value="Generate same table from HTML." />
JSfiddle Link : - >https://jsfiddle.net/shreekantbatale2/evqsuxm8/5/
What I understand is that you want to add a template table. Here is a simple way to do it with jQuery
var id = 0;
function generate_table() {
var table = `<table id='table${id}'>
<tr>
<th colspan="2">Aggregator</th>
</tr>
<tr>
<th> Column Name </th>
<th> Function </th>
</tr>
<tr>
<td> <input> </td>
<td> <input> </td>
</tr>
</table>`
$('#table-template').append(table)
id++
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3> TABLE FROM JAVA SCRIPT</h3>
<input type="button" value="Generate a table." onclick="generate_table()" />
<h3> TABLE FROM HTML</h3>
<div id='table-template'></div>
<input type="button" value="Generate same table from HTML." />
I think this is what you are lookign for.
function generate_table() {
var table = $('#table6').clone()
table.find('input').val('')
$('#table-template').append(table)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3> TABLE FROM JAVA SCRIPT</h3>
<input type="button" value="Generate a table." onclick="generate_table()" />
<h3> TABLE FROM HTML</h3>
<table id='table6'>
<tr>
<th colspan="2">Aggregator</th>
</tr>
<tr>
<th> Column Name </th>
<th> Function </th>
</tr>
<tr>
<td> <input> </td>
<td> <input> </td>
</tr>
</table>
<input type="button" value="Generate same table from HTML." />
<div id='table-template'></div>
You could use a <template> element to generate new HTML each time you want a new <table>
const button = document.querySelector('.js-create-table');
const template = document.createElement('template');
template.innerHTML = `
<table>
<tr>
<th colspan="2">Aggregator</th>
</tr>
<tr>
<th> Column Name </th>
<th> Function </th>
</tr>
<tr>
<td> <input> </td>
<td> <input> </td>
</tr>
</table>
`;
function generateTable() {
const table = template.content.cloneNode(true);
document.body.append(table);
}
button.addEventListener('click', generateTable);
<button class="js-create-table">Create table</button>
And if you just want to clone the original table and create a duplicate from it one.
const button = document.querySelector('.js-clone-table');
const table = document.querySelector('.js-table');
function cloneTable() {
const clone = table.cloneNode(true);
document.body.append(clone);
}
button.addEventListener('click', cloneTable);
<button class="js-clone-table">Clone table</button>
<table class="js-table">
<tr>
<th colspan="2">Aggregator</th>
</tr>
<tr>
<th> Column Name </th>
<th> Function </th>
</tr>
<tr>
<td> <input> </td>
<td> <input> </td>
</tr>
</table>
to duplicater a table with everyting inside (or any html element)
const btTableCopy = document.getElementById('bt-table-copy')
, originTable = document.getElementById('table6')
, baseRowTbl = originTable.querySelector('tbody tr')
;
var tableNum = 0
;
btTableCopy.onclick=()=>
{
let newTable = originTable.cloneNode(true)
, newTbody = newTable.querySelector('tbody')
;
newTable.id = `table-copy-${++tableNum}` // there cannot be two identical id values on an HTML page
for(let i=0;i<5;i++) // add 5 new rows
{
newTbody.appendChild(baseRowTbl.cloneNode(true))
}
newTable.querySelectorAll('input').forEach(inp=>inp.value='') // clear all table inputs
document.body.appendChild(newTable)
}
table {
border-collapse: collapse;
margin: 1em;
}
thead {
background-color: lightblue;
}
td, th {
border: solid grey 1px;
padding: 1em;
text-align : center;
}
<table id="table6">
<thead>
<tr>
<th colspan="2">Aggregator</th>
</tr>
<tr>
<th> Column Name </th>
<th> Function </th>
</tr>
</thead>
<tbody>
<tr>
<td> <input> </td>
<td> <input> </td>
</tr>
</tbody>
</table>
<button id="bt-table-copy">copy table with 5 new rows</button>

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>

Categories

Resources