Hello I'm trying to follow this
Add/Delete table rows dynamically using JavaScript
My goal is to scan/enter in barcodes that will make an HTML table. The "user", the "station" will be a variable. The "container" will be entered in once and saved. The only changing item will be scan which is the new row. I've gotten it to add the row but I can't add the variables into their respective columns. Any guidance on this would be great!
Here is my HTML FORM
<form id="trackForm"
autocomplete='off'>
<div class="row">
<div class="col col-lg">
<div id="s1group" class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">
<b>CONTAINER: </b>
</div>
</div>
<input id="container" class="form-control"
type="text"
placeholder="Scan container."
onpropertychange="checkScanInput();">
</input>
<div class="invalid-feedback">
This field cannot be empty!
</div>
</div>
<div id="s2group" class="input-group">
<div class="input-group-prepend">
<div id="s2label" class="input-group-text font-weight-bold">
SCAN:
</div>
</div>
<input id="scan" class="form-control"
type="text"
placeholder="Scan entry or code."
onpropertychange="checkScanInput();">
</input>
<div class="invalid-feedback">
This field cannot be empty!
</div>
</div>
</div>
</div>
<div class="col-sm-2">
<button id="trackSubmit" class="btn btn-dark font-weight-bold"
type="submit"
style="background-color: #005997; display:none;">
</button>
</div>
</form>
This is the table:
<table id="resultTable" class="table display compact">
<thead>
<tr>
<th>User</th>
<th>Station</th>
<th>Scan</th>
<th>Container</th>
<th>Date/Time</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Below is the Javascript
var thisStation = stationList[ssv][1];
var sessionUser = document.getElementById('userDisplay').textContent;
var table = document.getElementById("resultTable");
var rowCount = table.rows.length;
var colCount = table.rows[0].cells.length;
var row = table.insertRow(rowCount);
for(var i = 0; i < colCount; i++) {
var newcell = row.insertCell(i);
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
}
row = table.insertRow(table.rows.length);
for(var i = 0; i < colCount; i++) {
var newcell = row.insertCell(i);
if(i == (colCount - 1)) {
newcell.innerHTML = "<INPUT type=\"button\" value=\"Delete Row\" onclick=\"removeRow(this)\"/>";
} else {
newcell.innerHTML = table.rows[3].cells[i].innerHTML;
}
}
Check out the code snippet, run it and see if this works for you. Obviously, you can/ should adjust it to your (specific) needs, but you have your table with the ability to add rows, input data, remove correct rows as you please, and also the ability to "submit" your data.
// 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');
button.setAttribute('id', 'rm');
// 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('Data send:\n' + values);
}
table {
width: 70%;
font: 17px Calibri;
}
table, th, td
{
border: solid 1px #DDD;
border-collapse: collapse;
padding: 2px 3px;
text-align: center;
color: grey;
}
#addRow {
color: green;
font-weight: bold;
}
#bt {
color: blue;
font-style: italic;
font-weight: bold;
}
#rm {
color: red;
font-weight: bold;
}
<body onload="createTable()">
<p>
<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>
Related
I have created a function that inserts table row and data by user's request. I was asked to add a small red square (div) in the right corner of table cell, which when clicked, deletes the table row.
I've got so far that I've written a function that removes the table row, but the problem is - it only needs to be done, when the small red div is clicked, not when the table cell is clicked. How could this be achieved? I've tried several ways how to address the div, but none have worked so far.
Would be really grateful for your assistance.
<button class="btn" onclick="createNewTableElement()">Add</button>
<input id="new-item" type="text" value="item">
<table id="main-table" onclick="deleteRow(obj)">
function createNewTableElement() {
var inputField = document.getElementById("new-item");
if (inputField.value == "") {
return;
}
var row = document.createElement("tr");
var cell = document.createElement("td");
var div = document.createElement("div");
var cellText = document.createTextNode(inputField.value);
cell.appendChild(div);
cell.appendChild(cellText);
row.appendChild(cell);
obj = document.getElementById("main-table");
obj.appendChild(row);
}
function deleteRow(e) {
document.getElementById('main-table').deleteRow(e);
}
I made some changes in your code. Removed deleteRow binded on table and add event only on div element, then find parent row element and removed it from table
Does this help you?
function createNewTableElement() {
var inputField = document.getElementById("new-item");
if (inputField.value == "") {
return;
}
var row = document.createElement("tr");
var cell = document.createElement("td");
var div = document.createElement("div");
div.onclick = deleteRow;
var cellText = document.createTextNode(inputField.value);
cell.appendChild(div);
cell.appendChild(cellText);
row.appendChild(cell);
obj = document.getElementById("main-table");
obj.appendChild(row);
}
function deleteRow(e) {
document.getElementById('main-table').removeChild(e.target.parentElement.parentElement);
}
#main-table div {
height: 10px;
width: 10px;
border: 1px solid;
display: inline-block;
margin-right: 10px;
}
<button class="btn" onclick="createNewTableElement()">Add</button>
<input id="new-item" type="text" value="item">
<table id="main-table">
Remove onclick from table:
<button class="btn" onclick="createNewTableElement()">Add</button>
<input id="new-item" type="text" value="item">
<table id="main-table">
Then in same function you are creating row create also red div and event:
function createNewTableElement() {
var inputField = document.getElementById("new-item");
if (inputField.value == "") {
return;
}
var row = document.createElement("tr");
var cell = document.createElement("td");
var div = document.createElement("div");
div.addEventListener('click', function(event) {
// the row call parent (table) and tell removes him self
row.parentNode.removeChild(row);
});
var cellText = document.createTextNode(inputField.value);
cell.appendChild(div);
cell.appendChild(cellText);
row.appendChild(cell);
obj = document.getElementById("main-table");
obj.appendChild(row);
}
my way..
const mainTable = document.querySelector('#main-table tbody')
, btAdd = document.getElementById('btn-Add')
, newItem = document.getElementById('new-item')
;
newItem.oninput=()=>
{
btAdd.disabled = (newItem.value === '')
}
btAdd.onclick=()=>
{
let newCell = mainTable.insertRow().insertCell()
;
newCell.textContent = newItem.value
newCell.appendChild( document.createElement('div'))
newItem.value = ''
btAdd.disabled = true
}
mainTable.onclick=e=>
{
if (!e.target.matches('td div')) return
mainTable.deleteRow( e.target.closest('tr').rowIndex -1 )
}
#main-table {
border-collapse: collapse;
margin: 1em;
}
#main-table thead {
background-color: cadetblue;
}
#main-table th {
padding: .7em;
width:20em;
}
#main-table td {
border: 1px solid grey;
padding: .5em;
}
#main-table td div {
display: block;
float: right;
width: 1em;
height: 1em;
background-color: crimson;
cursor: pointer;
}
#main-table td div:hover {
border: 1px solid blue;
}
<button id="btn-Add" disabled >Add</button>
<input id="new-item" type="text" placeholder="item">
<table id="main-table">
<thead> <th>items list</th> </thead>
<tbody> </tbody>
</table>
I have this function to do a filter by jquery, and it is returning this error:
Cannot read property 'getElementById' of undefined
function VerificaCheck() {
var input, filter, table, tr, td, i, filtro;
input = document.getElementById("busca2");
filter = input.value.toUpperCase();
table = document.getElementById("tablepesquisa2");
tr = table.getElementsByTagName("tr");
filtro = document.getElementById("filtroPesquisa2").value;
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[filtro];
var tipoProduto = tr[i].getElementById("tipoProduto").value;
if (td) {
if (tipoProduto == $('#Produtos').prop("checked")) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
This is the HTML of my table, and the checkbox. If the checkbox is checked it should look for in the table the fields of typeProduct that are true
<div class="form-group">
<div class="col-sm-3">
<select id="filtroPesquisa2" class="form-control">
<option value="0">Código</option>
<option value="1">Descrição</option>
</select>
</div>
<div class="col-sm-7">
<input type="text" id="busca2" placeholder="Pesquisa.." onkeyup="myFunction2();" class="form-control" />
</div>
</div>
<div class="modal-body">
<div class="table-overflow col-sm-12">
<table class="table table-responsive table-hover" id="tablepesquisa2">
<thead>
<tr>
<th>Código</th>
<th>Nome</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Produto)
{
<tr>
<td>#item.Codigo</td>
<td>#item.nome</td>
<td align="right">
<i class="fa fa-check-circle fa-lg"></i>
</td>
<td id="tipoProduto" value="#item.TipoProduto">#item.TipoProduto</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<input type="checkbox" asp-for="Produtos" onclick="checkProduto();" name="Produtos" id="Produtos"/>
getElementById is available on the document, not on tr.
Documentation
change the following line to
var tipoProduto = document.getElementById("tipoProduto").value;
However, this may not get what you want, based on my guesses that you have multiple elements by this id in your table. Post your html and what you are trying to do, may be there's another way to do this.
UPDATE:
As suspected, your td repeats in the loop, so you multiple td with same id. I'd suggest to remove id from it.
Since the value you are looking is the last td, what you can possibly do to get the value you are looking for is (one way that is):
td[td.length-1].innerHTML
So the loop would look more like:
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[filtro];
if (td) {
var tipoProduto = td[td.length-1].innerHtml;
if (tipoProduto == $('#Produtos').prop("checked")) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
I am trying to search a table cell that has a child (textarea) in it. I have tried
td.children.value,
td.childNodes.value,
td.firstChild.value,
td.lastChild.value,
td.textarea.value... none of these have worked. here is my snippet:
addCell = function() {
var table = document.getElementById('myTable');
var tr = document.createElement('tr');
var td = document.createElement('td');
var txt = document.createElement('textarea');
table.appendChild(tr);
tr.appendChild(td);
td.appendChild(txt);
}
searchT = function() {
var table = document.getElementById('myTable');
var search = document.getElementById('search');
var tr = document.getElementsByTagName('tr');
var td = document.getElementsByTagName('td');
if (search.value === td.textarea.value) {
alert('hello');
}
/* I have tried:
td.childNodes.value
td.children.value
td.firstChild.value
td.lastChild.value
td.textarea.value
*/
}
td {
background-color: #ccc;
width: 100px;
height: 20px;
}
textarea {
resize: none;
}
.search {
width: 100px;
}
<button onclick="addCell()">
add
</button>
<input id="search" placeholder="search">
<button onclick="searchT()">
search
</button>
<table id="myTable">
<tr>
<td>
<textarea></textarea>
</td>
</tr>
</table>
When you do document.getElementsByTagName(), this returns a list of all the items on the document which contain that tag name. In order to find out if it exists in that list (I'm assuming that's what you want) then you have to loop for the list returned by getElementsByTagName().
I'm also assuming that you want to add a table with whatever you entered in the <input> so I added that in the addCell().
addCell = function() {
var table = document.getElementById('myTable');
var tr = document.createElement('tr');
var td = document.createElement('td');
var txt = document.createElement('textarea');
var search = document.getElementById('search'); // Get value in input field
table.appendChild(tr);
tr.appendChild(td);
txt.innerHTML = search.value; // Set value to table
td.appendChild(txt);
}
searchT = function() {
var search = document.getElementById('search');
var textareas = document.getElementsByTagName('textarea'); // Get the textareas instead
for(var i = 0; i < textareas.length; i++) {
if(search.value === textareas[i].innerHTML) { // If the text matches the search field
console.log("Found: " + search.value + " at index: " + i);
}
}
}
td {
background-color: #ccc;
width: 100px;
height: 20px;
}
textarea {
resize: none;
}
.search {
width: 100px;
}
<button onclick="addCell()">
add
</button>
<input id="search" placeholder="search">
<button onclick="searchT()">
search
</button>
<table id="myTable">
<tr>
<td>
<textarea readonly="readonly">Template</textarea> <!-- This doesn't have to be readonly but I made it Note: readonly="readonly" is only for valid XHTML. It could be left as readonly without the assignment for valid HTML -->
</td>
</tr>
</table>
If you're curious, you can read more about getElementsByTagName() here.
I might start with something like this. The comments should explain what's going on.
// as both functions are using them,
// I can define these outside the functions.
var myTable = document.getElementById("myTable");
var search = document.getElementById('search');
addCell = function() {
// create the references to the new els.
var tr = document.createElement('tr');
var td = document.createElement('td');
var txt = document.createElement('textarea');
// append the new els to my table.
myTable.appendChild(tr);
tr.appendChild(td);
td.appendChild(txt);
}
searchT = function() {
// Get all the td els in my table.
let tdEls = myTable.getElementsByTagName("td");
// Iterate over the array of td els, and
for (let i = 0; i < tdEls.length; i++) {
// get the textarea node if they have one
let textareaEl = tdEls[i].getElementsByTagName("textarea")[0];
// compare the textarea to the search
if (textareaEl.value.includes(search.value)) {
// They match -- do something with them.
console.log(textareaEl.value);
}
}
}
td {
background-color: #ccc;
width: 100px;
height: 20px;
}
textarea {
resize: none;
}
.search {
width: 100px;
}
<button onclick="addCell()">
add
</button>
<input id="search" placeholder="search">
<button onclick="searchT()">
search
</button>
<table id="myTable">
<tr>
<td>
<textarea></textarea>
</td>
</tr>
</table>
I have created a table where the user should be able to search by name or city.
When searching through names, the function should choose the correct table and the index attached to the call. Here is my attempt.
Desired Outcome: user chooses to search by name or by city and when he/she
types in the selected input, the function listens to the index number
that is in the call inside the input.
function searchIndex(id, index) {
// Declare variables
var filter, tr, td, i;
var table = document.getElementById(id);
var input = document.getElementById(index);
filter = input.value.toUpperCase();
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[''];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
const searchName = document.getElementById('searchName');
const searchCity = document.getElementById('searchCity');
const Select = document.getElementById('Select');
Select.addEventListener('click', () => {
if (Select.value == 'name') {
searchName.style.display = 'block';
searchCity.style.display = 'none';
} else {
searchName.style.display = 'none';
searchCity.style.display = 'block';
}
})
table {
margin: 0 auto;
text-align: center;
width: 500px;
}
td {
width: 250px;
}
tr:nth-child(even) {
background-color: #fff;
}
tr:nth-child(odd) {
background-color: #eee;
}
<div id="ListDiv">
<div class="Btns">
<input id="searchName" onkeyup="searchIndex('List' , [0])" type="text" placeholder="search name" />
<input id="searchCity" onkeyup="searchIndex('List' , [1])" style="display: none;" type="text" placeholder="search city" />
<div id="SelectDiv">
<select id="Select">
<option value="name">search name</option>
<option value="city">search city</option>
</select>
</div>
</div>
<table id="ListTop">
<tr>
<td>name</td>
<td>city</td>
</tr>
</table>
<div class="custScroll">
<table id="List">
<tr>
<td>hanna</td>
<td>big sandy</td>
</tr>
<tr>
<td>bonne</td>
<td>big sandy</td>
</tr>
<tr>
<td>thomas</td>
<td>big sandy</td>
</tr>
</table>
</div>
</div>
figured it out, changed the index from [0] to [index] and added [index] into function parameter list.
function searchIndex(id, id2, [index]) {
// Declare variables
var filter, tr, td, i;
var table = document.getElementById(id);
var input = document.getElementById(id2);
filter = input.value.toUpperCase();
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[index];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
const searchName = document.getElementById('searchName');
const searchCity = document.getElementById('searchCity');
const Select = document.getElementById('Select');
Select.addEventListener('click', () => {
if (Select.value == 'name') {
searchName.style.display = 'block';
searchCity.style.display = 'none';
} else {
searchName.style.display = 'none';
searchCity.style.display = 'block';
}
})
table {
margin: 0 auto;
text-align: center;
width: 500px;
}
td {
width: 250px;
}
tr:nth-child(even) {
background-color: #fff;
}
tr:nth-child(odd) {
background-color: #eee;
}
<div id="ListDiv">
<div class="Btns">
<input id="searchName" onkeyup="searchIndex('List' , 'searchName', [0])" type="text" placeholder="search name" />
<input id="searchCity" onkeyup="searchIndex('List' , 'searchCity', [1])" style="display: none;" type="text" placeholder="search city" />
<div id="SelectDiv">
<select id="Select">
<option value="name">search name</option>
<option value="city">search city</option>
</select>
</div>
</div>
<table id="ListTop">
<tr>
<td>name</td>
<td>city</td>
</tr>
</table>
<div class="custScroll">
<table id="List">
<tr>
<td>hanna</td>
<td>big sandy</td>
</tr>
<tr>
<td>bonne</td>
<td>hawkins</td>
</tr>
<tr>
<td>thomas</td>
<td>gilmer</td>
</tr>
</table>
</div>
</div>
I try to make lines dynamically, the problem is when I add a checkbox with label dynamically using javascript does not work. However the one I created with Html by default works correctly.
In fact I want the image that I added (on.png / off.png) replaces the checkbox. When I do it only with html (checkbox + label) the code works, but now I only want to create the element with Javascript, I can chow the label but it when I click It's not work.
This is all my code :
Main.html
<HTML>
<HEAD>
<TITLE> </TITLE>
<link rel="stylesheet" type="text/css" href="style.css" />
<SCRIPT language="javascript">
function addRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var cell1 = row.insertCell(0);
var element1 = document.createElement("input");
element1.type = "checkbox";
element1.id = "id2" ;
cell1.appendChild(element1);
// Create label
var label = document.createElement("label");
label.for = "id2" ;
cell1.appendChild(label);
var cell2 = row.insertCell(1);
cell2.innerHTML = rowCount + 1;
var cell3 = row.insertCell(2);
var element2 = document.createElement("input");
element2.type = "text";
cell3.appendChild(element2);
}
function deleteRow(tableID) {
try {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
for(var i=0; i<rowCount; i++) {
var row = table.rows[i];
var chkbox = row.cells[0].childNodes[0];
if(null != chkbox && true == chkbox.checked) {
table.deleteRow(i);
rowCount--;
i--;
}
}
}catch(e) {
alert(e);
}
}
</SCRIPT>
</HEAD>
<BODY>
<INPUT type="button" value="Add Row" onclick="addRow('dataTable')" />
<INPUT type="button" value="Delete Row" onclick="deleteRow('dataTable')" />
<TABLE id="dataTable" width="350px" border="1">
<TR>
<TD><INPUT type="checkbox" name="chk" id="id1" /> <label for="id1" > </label> </TD>
<TD> 1 </TD>
<TD> <INPUT type="text" /> </TD>
</TR>
</TABLE>
</BODY>
</HTML>
style.css
input[type=checkbox] {
display:none;
}
input[type=checkbox] + label
{
background: url(images/off.png) no-repeat;
height: 64px;
width: 64px;
display:inline-block;
padding: 0 0 0 0px;
}
input[type=checkbox]:checked + label
{
background: url(images/on.png) no-repeat;
height: 64px;
width: 64px;
display:inline-block;
padding: 0 0 0 0px;
}
Help me please.
Change this
label.for = "id2" ;
to this
label.htmlFor = "id2" ;
Because some JavaScript implementations didn't allow keywords/reserved words as object properties, a workaround had to be made for the for property, so they chose htmlFor.
A similar situation was with .class, which is why they use .className.
Your problem is line 17, label.for = "id2" ; that should be label.htmlFor = "id2";