How to empty table in javascript? - javascript

I cant delete the row contents of a table, but what if I want to delete the rows too?
My Javascript code: (I want all the rows to disappear except the first one.)
function deleteAll() {
for ( var i = 0; i <= table.rows.length; i++){
table.rows[i].cells[0].innerHTML = "";
table.rows[i].cells[1].innerHTML = "";
table.rows[i].cells[2].innerHTML = "";
}
}
My HTML table:
<body>
<div class="container">
<div class="tab tab-1">
<table id="table" border="1">
<th>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
</th>
<tr>
<td>Frank</td>
<td>Nenjim</td>
<td>19</td>
</tr>
<tr>
<td>Alex</td>
<td>Ferreira</td>
<td>23</td>
</tr>
</table>
</div>
<div class="tab tab-2">
First Name :<input type="text" name="fname" id="fname">
Last Name :<input type="text" name="lname" id="lname">
Age :<input type="number" name="age" id="age">
<button onclick="deleteAll()">Delete All</button>
</div>
</div>
<script src="tableEdit.js"></script>
</body>
So, the Javascript code above doesn't satisfy me because I want only the first row to remain. I don't want empty rows.

You can use the jQuery remove() function as described in this example to delete all rows except the (first) header row:
$('#table tr:not(:first)').remove();
You may instead want to delete just the rows of body section (inside <tbody>) as mentioned in this post:
$('#table > tbody > tr').remove();

for(var i = 1;i<table.rows.length;){
table.deleteRow(i);
}

If you want to remove data rows only then use
$("#table tr").remove();
And if you want to empty table with header then use
$("#table").empty();

Related

How to Create dynamic tbody onclick of button using javascript or jquery

I have this code:
$(document).ready(function() {
//Try to get tbody first with jquery children. works faster!
var tbody = $('#myTable').children('tbody');
//Then if no tbody just select your table
var table = tbody.length ? tbody : $('#myTable');
$('button').click(function() {
//Add row
table.append('<tr>\n\
<td><input name="product_name[]" type="text"/></td>\n\
<td><input name="qty[]" type="text"/></td>\n\
<td><input name="price[]" type="text"/></td>\n\
</tr>');
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input name="row_no" type="text" placeholder="Type Your Number of row" />
<button>Add row</button>
<table id="myTable">
<tbody>
<tr>
<th class="column-title">Product name</th>
<th class="column-title">Quantity</th>
<th class="column-title">Price</th>
</tr>
</tbody>
</table>
When I click on the button Add row, it appends a row to the table.
But now, I have a textbox in the HTML. I want to append the table to generate rows based on the value of:
<input name="row_no" type="text" placeholder="Type Your Number of row" />
How do I achieve this?
Here's what you're looking for:
$(document).ready(function() {
//Try to get tbody first with jquery children. works faster!
var tbody = $('#myTable').children('tbody');
//Then if no tbody just select your table
var table = tbody.length ? tbody : $('#myTable');
$('[name=row_no]').text();
$('button').click(function() {
var rows = $('[name=row_no]').val();
// If rows are at maximum 10,
if (!(rows > 10)) {
// then add rows
for (var i = 0; i < rows; i++) {
table.append('<tr>\n\
<td><input name="product_name[]" type="text"/></td>\n\
<td><input name="qty[]" type="text"/></td>\n\
<td><input name="price[]" type="text"/></td>\n\
</tr>');
}
}
else {
alert("Error: Too many rows!\n" +
"Maximum allowed: 10\n" +
"- Inserted: " + rows);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<input name="row_no" type="number" placeholder="Type Your Number of row" />
<button>Add row</button>
<table id="myTable">
<tbody>
<tr>
<th class="column-title">Product name</th>
<th class="column-title">Quantity</th>
<th class="column-title">Price</th>
</tr>
</tbody>
</table>
</body>
What changed?
You needed to get the value inserted in the textfield, this can be achieved using, in this case: $('[name=row_no]').val();, so I valorised it as rows variable and then the only thing to add was a cycle that creates as many rows as the user inserts.
I also changed<input name="row_no" type="text" placeholder="Type Your Number of row" />to <input name="row_no" type="number" placeholder="Type Your Number of row" />. This little change allows the user to insert only integers and this is a nice solution to avoid time-loss because of writing a new function to validate values inserted.
Edit:
Added a control on about how many rows the user can insert with if (!(rows > 10)) condition (if you need more or less rows, the only thing to edit is the number)

chrome shows Uncaught TypeError: Cannot read property 'cells' of null when trying to get the last row first cell value

<!DOCTYPE html>
<html>
<head>
<title>Employee Details</title>
<style>
table,th,tr,td{
border: 1px solid black;
}
#add
{
padding-top:2em;
}
tr,td{
border-collapse:collapse;
}
</style>
</head>
<body>
<script>
function addRow(){
var table=document.getElementById("table1");
var x3=document.getElementById("table1").rows.length;
var x4=document.getElementById("table1").rows[x3].cells.value;
console.log(x4);
var row=table.insertRow(-1);
var cell1=row.insertCell(0);
var cell2=row.insertCell(1);
var cell3=row.insertCell(2);
var x=document.getElementById("ename").value;
var x2=document.getElementById("emp_mail").value;
cell1.innerHTML=(x4+1);
cell2.innerHTML=x;
cell3.innerHTML=x2;
}
</script>
<h1 align="center">EMPLOYEE DETAILS</h1>
<div align="center">
<table id="table1" style="width:50%">
<tr>
<th>Employee ID</th>
<th>Name</th>
<th>E-mail ID</th>
</tr>
<tr>
<td>100</td>
<td>Ram</td>
<td>ram_95#gmail.com</td>
</tr>
<tr>
<td>101</td>
<td>Suresh</td>
<td>suresh#gmail.com</td>
</tr>
<tr>
<td>102</td>
<td>Ramesh</td>
<td>hello2ramesh#gmail.com</td>
</tr>
</table>
<div id="add" align:left style="width:50%">
Name <input type="text" id="ename" placeholder="Employee Name" required><br><br>
E-mail<input type="email" id="emp_mail" placeholder="E-mail" required><br><br>
<input type="submit" value="Submit" onclick=addRow()>
</div>
</div>
</body>
</html>
Here i'm trying to acess the value of last row first cell and increasing it by 1. and adding it to the next row but the it always shows Uncaught TypeError: Cannot read property 'cells' of null.
The aim here is to fetch the last row first cell data and increment it by 1 and add it to the next row using the values passed by the user through the textboxes
Arrays (and array like structures) in javascript are 0 based ... therefore an Array of length 1 will have a single item at index 0
Therefore, to access the last row, you would use rows.length - 1
also, row[n].cells has no property named value so I'm not sure what you're trying to access there - perhaps it's cells[0].textContent as a number (since you're adding one to it later on in your code) - so to coerce the textContent to a number simply use unary + - see code
you're also overusing getElementById - see code below
function addRow() {
var table = document.getElementById("table1");
// after this, can use table instead of document.getElementById("table1")
var x3 = table.rows.length - 1; // subtract 1, because index is 0 based
var x4 = +table.rows[x3].cells[0].textContent; // + coerces to number
console.log(x4);
var row = table.insertRow(-1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var x = document.getElementById("ename").value;
var x2 = document.getElementById("emp_mail").value;
cell1.innerHTML = (x4 + 1);
cell2.innerHTML = x;
cell3.innerHTML = x2;
}
table,
th,
tr,
td {
border: 1px solid black;
}
#add {
padding-top: 2em;
}
tr,
td {
border-collapse: collapse;
}
<h1 align="center">EMPLOYEE DETAILS</h1>
<div align="center">
<table id="table1" style="width:50%">
<tr>
<th>Employee ID</th>
<th>Name</th>
<th>E-mail ID</th>
</tr>
<tr>
<td>100</td>
<td>Ram</td>
<td>ram_95#gmail.com</td>
</tr>
<tr>
<td>101</td>
<td>Suresh</td>
<td>suresh#gmail.com</td>
</tr>
<tr>
<td>102</td>
<td>Ramesh</td>
<td>hello2ramesh#gmail.com</td>
</tr>
</table>
<div id="add" align:left style="width:50%">
Name <input type="text" id="ename" placeholder="Employee Name" required><br><br> E-mail
<input type="email" id="emp_mail" placeholder="E-mail" required><br><br>
<input type="submit" value="Submit" onclick=addRow()>
</div>
</div>
Now this should work as you expect.
The problem is that length of an array is always going to be one more than the last index, as arrays start from position 0. To fix your code, change this line:
var x4=document.getElementById("table1").rows[x3].cells.value;
Into this:
var x4=document.getElementById("table1").rows[x3 - 1].cells.value;
And your code will work.

JavaScript Search Table by Index

I have a table with multiple columns (for this question I only made two columns) and I want the user to be able to search through a column by the index depending on an option that the user can select. I have working code, but in order to change the search option, I had to copy the function for each input.
How can I search by the index? If a user selects an option like (name), then the javascript function will change the index that it is searching to [0]. if the user selects (location), the function will change the index to [1] and search through that column.
Is this possible? Any help would be appreciated.
const searchName = document.getElementById('searchName');
const searchLoc = document.getElementById('searchLoc');
custSelect.addEventListener('click', () => {
if (custSelect.value == 'custname') {
searchName.style.display = 'block';
searchLoc.style.display = 'none';
} else {
searchName.style.display = 'none';
searchLoc.style.display = 'block';
}
});
// Search for customer, or search for location, index will change based on option selected.
function tableSearch(id, index) {
// Declare variables
var filter, input, table, tr, td, i;
input = document.getElementById(id);
filter = input.value.toUpperCase();
table = document.getElementById(id);
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")[0]; // index will change based on option selected.
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<div id="custDiv">
<div class="addBtns">
<input id="searchName" onkeyup="tableSearch('searchName','custList'[0])" type="text" placeholder="search name" />
<!-- this searches through the first index or [0] -->
<input id="searchLoc" onkeyup="tableSearch('searchLoc','custList'[1])" style="display: none;" type="text" placeholder="search location" />
<!-- this searches through the second index or [1] -->
<div id="custSelectDiv" style="width: 175px; height: 35px; max-height: 35px; margin: 0 auto;">
<select id="custSelect" style="position: absolute;">
<option value="custname">name</option> <!-- if user selects this, the corresponding input is displayed, which changes the index to search through -->
<option value="location">location</option> <!-- if user selects this, the corresponding input is displayed, which changes the index to search through -->
</select>
</div>
</div>
<table id="custListTop" contenteditable="false">
<tr>
<td style="border-top-left-radius: 5px;">Customers</td>
<td style="border-top-right-radius: 5px;">Main Location</td>
</tr>
</table>
<table id="custList" contenteditable="true">
<tr>
<td>josh</td>
<td>hawkins</td>
</tr>
<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>
<script src="test.js"></script>
</body>
</html>
This should get you on track
var table = document.getElementById('tab'),
col = document.getElementById('col'),
val = document.getElementById('val');
col.max = table.rows[0].cells.length - 1;
function search() {
var regex = new RegExp(val.value || '', 'i');
for (var i = table.rows.length; i-- > 1;) {
if (regex.test(table.rows[i].cells[+col.value].innerHTML)) {
table.rows[i].style.display = 'table-row';
} else
table.rows[i].style.display = 'none';
}
}
table {
border-collapse: collapse;
}
table,
th,
td {
border: 1px solid;
}
<label for="col">Column :</label>
<input type="number" id="col" placeholder="column" onkeyup="search()" min="0" step="1" />
<br>
<label for="val">Find :</label>
<input type="text" id="val" placeholder="cell" onkeyup="search()" />
<table id="tab">
<tr>
<th>Customers</th>
<th>Main Location</th>
</tr>
<tr>
<td>josh</td>
<td>hawkins</td>
</tr>
<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>
I think they are two simplier ways to do that research :
Use an object array to search what you need, reorganize it at each research and re-make your html table each time the table changes.
Or use dataTable, which is a very simple tool to sort table.

A table by specific columns content

I have a table that should eventually have 5 columns which I want to be able to sort though only the value of one column, "Name". This is what my function looks like so far:
function RenderResultsByName() {
//Declaration of variables
var nameInput, nameFilter, ul, li, a, i;
//Set the variables accorging to matching id's
//Name
nameInput = document.getElementById('nameInput');
nameFilter = nameInput.value.toUpperCase();
ul = document.getElementById("UL");
li = document.getElementsByTagName('tr');
console.log(li[0]);
//Loop trough items and hide those who don't match the query-->
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("td")[0];
if (a.innerHTML.toUpperCase().indexOf(nameFilter) > -1) {
li[i].style.display = "";
}
else {
li[i].style.display = "none";
}
}
}
The HTML looks like this
<div class="row">
<div class="col-md-3">
<label>Namn: </label><br />
<input type="text" id="nameInput" onkeyup="RenderResultsByName()" placeholder="Sök efter namn..." /> <br /> <br />
</div>
</div>
<br /><br />
<table id="UL" class="table table-bordered">
<tr>
<th>Name</th>
<th>Yada</th>
<th>Yada</th>
<th>Yada</th>
<th>Yada</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.visitor.FullName</td>
</tr>
}
</table>
I tried to apply a class "tdOfName" on all the 's in the Name column, but after that the sort stopped working because the a variable became undefined.
How would you solve this?
First, two things for your HTML code:
First a piece of advice, add thead and tbody to your tables to simplify jquery row selectors (and is a good practice, anyway).
You're creating 5 columns in the head row but only one in the rest. You have to add the rest or set a colspan.
<table id="UL" class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Yada</th>
<th>Yada</th>
<th>Yada</th>
<th>Yada</th>
</tr>
<thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>#item.visitor.FullName</td><td></td><td></td><td></td><td></td>
</tr>
}
<tbody>
</table>
Then, you say sort but your function is trying to show/hide rows attending at the input of the value. I can't see any sign of sorting. In case what you want is show/hide rows that has the input value in the first column, you can simplify it with this...
jQuery.expr[':'].icontains = function(a, i, m) {
return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
};
$('input#nameInput').on('keyup',function() {
$('table#UL tbody tr').hide().filter(':has(td:first:icontains('+this.value+'))').show();
});
Here you have an fiddle example... https://fiddle.jshell.net/rigobauer/4rzf4wt7/
Is this what you're looking for?
I hope it helps.

Get the hidden column value in a table on row click

I have a table with four columns. The first two columns are hidden. I want to get the values of the second and third columns on row click. I can get the value of the third column using the below code. But how can I get the value of the hidden column?
$('body').on( 'click','#item-grid table tbody tr', function() {
$('#PurchaseOrder_supplier_name').val($(this).children(':nth-child(3)').text());
});
Below is the table html.
<table class="table table-bordered table-condensed table-hover table-striped dataTable">
<thead>
<tr>
<th id="item-grid_c0" style="display:none">Supplier ID</th>
<th id="item-grid_c1" style="display:none">Supplier ID</th>
<th id="item-grid_c2"><a href="/builders_common/index.php?r=purchase/purchase/multipurchaseorderdetailview&PurchaseOrder%5Bvoucher_no%5D=12&PurchaseOrderDetails%5Bpurchase_voucher_no%5D=12&PurchaseOrderDetails%5Bproject_id%5D=45&PurchaseOrderDetails%5Bitem_id%5D=79&ajax=item-grid&sort=supplier"
class="sort-link">Supplier</a>
</th>
<th id="item-grid_c3"><a href="/builders_common/index.php?r=purchase/purchase/multipurchaseorderdetailview&PurchaseOrder%5Bvoucher_no%5D=12&PurchaseOrderDetails%5Bpurchase_voucher_no%5D=12&PurchaseOrderDetails%5Bproject_id%5D=45&PurchaseOrderDetails%5Bitem_id%5D=79&ajax=item-grid&sort=item"
class="sort-link">Item</a>
</th>
<th id="item-grid_c4"><a href="/builders_common/index.php?r=purchase/purchase/multipurchaseorderdetailview&PurchaseOrder%5Bvoucher_no%5D=12&PurchaseOrderDetails%5Bpurchase_voucher_no%5D=12&PurchaseOrderDetails%5Bproject_id%5D=45&PurchaseOrderDetails%5Bitem_id%5D=79&ajax=item-grid&sort=rate"
class="sort-link">Rate</a>
</th>
</tr>
</thead>
<tbody>
<tr class="odd selected">
<td style="display:none">
<input type="hidden" id="ProjectPurchaseOrderSupplierwise_item_id_5" name="ProjectPurchaseOrderSupplierwise[item_id_5]" value="79" class="gridfield">
</td>
<td style="display:none">
<input type="hidden" id="ProjectPurchaseOrderSupplierwise_supplier_id_5" name="ProjectPurchaseOrderSupplierwise[supplier_id_5]" value="14" class="gridfield">
</td>
<td>General</td>
<td>Cement</td>
<td>
<input type="text" id="ProjectPurchaseOrderSupplierwise_rate_5" name="ProjectPurchaseOrderSupplierwise[rate_5]" value="50.00" readonly="readonly" class="gridfield">
</td>
</tr>
</tbody>
</table>
Try like below.
$('body').on( 'click','#item-grid table tbody tr', function() {
$(this).find('td:eq(1) input').val(); // 2nd column
$(this).find('td:eq(2)').text(); // 3rd column
});
You can use either of the two :eq() Selector or :nth-child() Selector.
https://api.jquery.com/nth-child-selector/
https://api.jquery.com/eq-selector/
Click here
Example code with your HTML
To get a specific cell by index, you can use :
$(this).find('td:nth-child(2) input').val(); // 2nd column
$(this).find('td:eq(1) input').val(); // 2nd column
$(this).find('td:nth-child(3)').text(); // 3rd column
$(this).find('td:eq(2)').text(); // 3rd column
$('#PurchaseOrder_supplier_name').val($(this).children(':nth-child(3):visible').text());

Categories