How to delete each third row from <tbody> using only JavaScript? [duplicate] - javascript

This question already has an answer here:
Javascript table tr deletes on tr (Dynamic tr delete and re-generate tr id)
(1 answer)
Closed 3 years ago.
I want to delete each third row in this code.
How I can do this?
Thanks for any answers
I was trying to do something like this:
const table = document.getElementById('myTable');
for (let i =0; i <table.rows.length; i++) {
if (i%3 === 0 ) {
table.deleteRow(i)
}
}
I have this table:
<tbody>
<tr>
<td>First row.</td>
</tr>
<tr>
<td>Second row.</td>
</tr>
<tr>
<td>DELETE 3</td>
</tr>
<tr>
<td>4 row.</td>
</tr>
<tr>
<td>5 row.</td>
</tr>
<tr>
<td>DELETE 6</td>
</tr>
<tr>
<td>First row.</td>
</tr>
<tr>
<td>Second row.</td>
</tr>
<tr>
<td>DELETE 9</td>
</tr>
</tbody>
I need a script which I will put in the console of my browser and I will delete each third row in anything table. Thank you!

The problem is that as soon as you remove a row from your table, the tables rows.length property decreases by 1 as well as the the order of your rows changes. (thus after removing, the next third will be a different element as before removing)
Better iterate over the elements from the last to the first like:
var myTable = document.getElementById("myTable");
for (var a = myTable.rows.length - 1; a > 0; a--) {
if ((a + 1) % 3 === 0) {
myTable.deleteRow(a)
}
}
<table id="myTable">
<tbody>
<tr>
<td>First row.</td>
</tr>
<tr>
<td>Second row.</td>
</tr>
<tr>
<td>DELETE 3</td>
</tr>
<tr>
<td>4 row.</td>
</tr>
<tr>
<td>5 row.</td>
</tr>
<tr>
<td>DELETE 6</td>
</tr>
<tr>
<td>First row.</td>
</tr>
<tr>
<td>Second row.</td>
</tr>
<tr>
<td>DELETE 9</td>
</tr>
</tbody>
</table>

You can try the following way:
var table = document.querySelectorAll('tbody tr');
for (let i =0; i <table.length; i++) {
if(i%3==2)
table[i].remove();
}
<table>
<tbody>
<tr>
<td>First row.</td>
</tr>
<tr>
<td>Second row.</td>
</tr>
<tr>
<td>DELETE 3</td>
</tr>
<tr>
<td>4 row.</td>
</tr>
<tr>
<td>5 row.</td>
</tr>
<tr>
<td>DELETE 6</td>
</tr>
<tr>
<td>First row.</td>
</tr>
<tr>
<td>Second row.</td>
</tr>
<tr>
<td>DELETE 9</td>
</tr>
</tbody>
</table>

Use Array.forEach to iterate over a selection of all the rows.
const tableRows = document.querySelectorAll("#mytable tr")
Array.from(tableRows).forEach((row, i) => {
if ((i + 1) % 3 === 0) {
row.parentNode.removeChild(row);
}
})
<table id="mytable">
<tbody>
<tr>
<td>1 row.</td>
</tr>
<tr>
<td>2 row.</td>
</tr>
<tr>
<td>DELETE 3</td>
</tr>
<tr>
<td>4 row.</td>
</tr>
<tr>
<td>5 row.</td>
</tr>
<tr>
<td>DELETE 6</td>
</tr>
<tr>
<td>7 row.</td>
</tr>
<tr>
<td>8 row.</td>
</tr>
<tr>
<td>DELETE 9</td>
</tr>
</tbody>
</table>
Or use ECMAScript 2015's spread syntax to do the same thing
[...document.querySelectorAll('#mytable tr')].forEach((el, i) => {if (i % 3 === 2) {el.remove()}});
<table id="mytable">
<tbody>
<tr>
<td>1 row.</td>
</tr>
<tr>
<td>2 row.</td>
</tr>
<tr>
<td>DELETE 3</td>
</tr>
<tr>
<td>4 row.</td>
</tr>
<tr>
<td>5 row.</td>
</tr>
<tr>
<td>DELETE 6</td>
</tr>
<tr>
<td>7 row.</td>
</tr>
<tr>
<td>8 row.</td>
</tr>
<tr>
<td>DELETE 9</td>
</tr>
</tbody>
</table>

Related

onclick show/hide next table rows

onclick get button show/hide next rows between the clicked button and next button.
How to display these rows as hidden first and after that i can switch between show and hide them. if it is possible with vanilla JavaScript and CSS.
table,
th,
td {
border: 1px solid black;
}
<table>
<tr>
<td><button>show/hide</button> A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>test 1</td>
<td>test 1</td>
<td>test 1</td>
</tr>
<tr>
<td><button>show/hide</button> AA</td>
<td>BB</td>
<td>CC</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>test 1</td>
<td>test 1</td>
<td>test 1</td>
</tr>
<tr>
<td><button>show/hide</button> AAA</td>
<td>BBB</td>
<td>CCC</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>test 1</td>
<td>test 1</td>
<td>test 1</td>
</tr>
</table>
The key here to achieve what you want is to use .nextUntil("tr:has(button)")
as in:
$('table button').click(function() {
var n = $(this).closest("tr").nextUntil("tr:has(button)");
n.toggle()
})
Demo
$('table button').click(function() {
var n = $(this).closest("tr").nextUntil("tr:has(button)");
n.toggle()
})
table,
th,
td {
border: 1px solid black;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td><button>show/hide</button> A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>test 1</td>
<td>test 1</td>
<td>test 1</td>
</tr>
<tr>
<td><button>show/hide</button> AA</td>
<td>BB</td>
<td>CC</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>test 1</td>
<td>test 1</td>
<td>test 1</td>
</tr>
<tr>
<td><button>show/hide</button> AAA</td>
<td>BBB</td>
<td>CCC</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>test 1</td>
<td>test 1</td>
<td>test 1</td>
</tr>
</table>
With vanilla javascript you can utilise the indexOf method to find where the table-row element containing the clicked button is and then iterating over N rows after and toggling the display state.
document.querySelectorAll('button').forEach(bttn=>bttn.addEventListener('click',function(e){
/* create an array from the nodelist so that `indexOf` can be used */
let col=[...document.querySelectorAll('tr')];
/* find the parent table row of the invoking button */
let tr=this.parentNode.parentNode;
/* find which table row in the array was the event source */
let index=col.indexOf( tr ) + 1;
/* process the next N records/rows */
for( let i=index; i < index + 2; i++ ){
col[i].style.display=col[i].style.display=='table-row' || col[i].style.display=='' ? 'none' : 'table-row'
}
}))
table, th, td {
border: 1px solid black;
}
tr{display:table-row}
<table>
<tr>
<td><button>show/hide</button> A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>test 1</td>
<td>test 1</td>
<td>test 1</td>
</tr>
<tr>
<td><button>show/hide</button> AA</td>
<td>BB</td>
<td>CC</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>test 1</td>
<td>test 1</td>
<td>test 1</td>
</tr>
<tr>
<td><button>show/hide</button> AAA</td>
<td>BBB</td>
<td>CCC</td>
</tr>
<tr>
<td>test</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>test 1</td>
<td>test 1</td>
<td>test 1</td>
</tr>
</table>

Get all tr in table between tr with table-primary class and push in array

At the click of the button #create-arrays I need to create multiple arrays. Each array will contain the set of tr (not .table-primary) present between the two tr (previous and next) with class table primary. this set of tr will be called context. Using jquery, how can I identify any such context and place it in an array? Thanks to everyone who will help.
HTML part (for testing):
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<table class="table table-sm">
<thead>
</thead>
<tbody>
<tr class="table-primary">
<td colspan="2">Group 1</td>
</tr>
<tr>
<td>Name: Jonh</td>
<td>Surname: Doe</td>
</tr>
<tr>
<td>Name: Mark</td>
<td>Surname: Lon</td>
</tr>
<tr class="table-primary">
<td colspan="2">Group 2</td>
</tr>
<tr>
<td>Name: Will</td>
<td>Surname: Man</td>
</tr>
<tr>
<td>Name: Ben</td>
<td>Surname: Harper</td>
</tr>
<tr>
<td>Name: Mitch</td>
<td>Surname: Collins</td>
</tr>
<tr class="table-primary">
<td colspan="2">Group 3</td>
</tr>
<tr>
<td>Name: Serena</td>
<td>Surname: Mellin</td>
</tr>
<tr class="table-primary">
<td colspan="2">Group 4</td>
</tr>
<tr>
<td>Name: Nickolas</td>
<td>Surname: Malinof</td>
</tr>
<tr>
<td>Name: David</td>
<td>Surname: Benner</td>
</tr>
<tr>
<td>Name: Lenny</td>
<td>Surname: Doe</td>
</tr>
<tr>
<td>Name: Micheal</td>
<td>Surname: Pitzford</td>
</tr>
<tr>
<td>Name: Melania</td>
<td>Surname: Bebant</td>
</tr>
</tbody>
</table>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>
the jquery script that i use to get all the tr inside tbody.
$('#create-arrays').on('click', function(){
var context = [];
var a = $('#file_table_available tbody tr');
console.log(a);
for (let i = 0; i < a.length; i++) {
const element = a[i];
}
})
You're off to a good start looping over all rows in the table.
You could check each row (element in your snippet) for the existance of the table-primary class. If the row has this class, you know you have to create a new group.
Here's a vanilla javascript example. It outputs an array of groups. Each group contains 1 or more rows that belong together.
const rows = document.querySelectorAll("tr");
const groups = [];
let group = null;
for (const row of rows) {
if (row.classList.contains("table-primary")) {
group = [];
groups.push(group);
} else {
group.push(row);
}
}
console.log(groups);
<table class="table table-sm">
<thead>
</thead>
<tbody>
<tr class="table-primary">
<td colspan="2">Group 1</td>
</tr>
<tr>
<td>Name: Jonh</td>
<td>Surname: Doe</td>
</tr>
<tr>
<td>Name: Mark</td>
<td>Surname: Lon</td>
</tr>
<tr class="table-primary">
<td colspan="2">Group 2</td>
</tr>
<tr>
<td>Name: Will</td>
<td>Surname: Man</td>
</tr>
<tr>
<td>Name: Ben</td>
<td>Surname: Harper</td>
</tr>
<tr>
<td>Name: Mitch</td>
<td>Surname: Collins</td>
</tr>
<tr class="table-primary">
<td colspan="2">Group 3</td>
</tr>
<tr>
<td>Name: Serena</td>
<td>Surname: Mellin</td>
</tr>
<tr class="table-primary">
<td colspan="2">Group 4</td>
</tr>
<tr>
<td>Name: Nickolas</td>
<td>Surname: Malinof</td>
</tr>
<tr>
<td>Name: David</td>
<td>Surname: Benner</td>
</tr>
<tr>
<td>Name: Lenny</td>
<td>Surname: Doe</td>
</tr>
<tr>
<td>Name: Micheal</td>
<td>Surname: Pitzford</td>
</tr>
<tr>
<td>Name: Melania</td>
<td>Surname: Bebant</td>
</tr>
</tbody>
</table>

How to hide the specific tr:nth-child(6) based on the content of a tr:nth-child(7) > td:nth-child(2)

I would like to hide with javascript a specific child :
#table-detail > tbody > tr:nth-child(10)
based on the content of another specific preceding child :
#table-detail > tbody > tr:nth-child(7) > td:nth-child(2)
I can hide the child as followed :
$('#table-detail > tbody > tr:nth-child(10)').css('display', 'none');
but I have no clue how to check the content of the preceding child (if child element
#table-detail > tbody > tr:nth-child(7) > td:nth-child(2)" content == 'Tarte-fine
then hide child element X.
Please find hereafter the table :
<table id="table-detail" class="table table-striped">
<tbody>
<tr>
<td># Commande</td>
<td>26</td>
</tr>
<tr>
<td>Statut Commande</td>
<td>Non traitée</td>
</tr>
<tr>
<td>Statut Laboratoire</td>
<td>Assignée</td>
</tr>
<tr>
<td>Nom</td>
<td>Client Deux</td>
</tr>
<tr>
<td>Nature</td>
<td>Client Mage</td>
</tr>
<tr>
<td>Date Retrait</td>
<td></td>
</tr>
<tr>
<td>Catégorie</td>
<td>Tarte-fine</td> <-CONTENT TO CHECK IN THIS CHILD ELEMENT
</tr>
<tr>
<td>Produit</td>
<td>Abricots</td>
</tr>
<tr>
<td># Personnes</td>
<td>10</td>
</tr>
<tr> <- CHILD ELEMENT TO HIDE
<td>Taille (cm)</td>
<td>16</td>
</tr>
<tr>
<td>Inscription</td>
<td></td>
</tr>
<tr>
<td>Décoration petites fleurs</td>
<td>undefined</td>
</tr>
<tr>
<td>Décoration Chocolat et fruits</td>
<td>undefined</td>
</tr>
<tr>
<td>Nombre de sandwiches</td>
<td></td>
</tr>
<tr>
<td>Poids</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 1</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 2</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 3</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 4</td>
<td></td>
</tr>
<tr>
<td>Couleur du ruban</td>
<td></td>
</tr>
<tr>
<td>Prix</td>
<td>58</td>
</tr>
<tr>
<td>Total</td>
<td>0</td>
</tr>
</tbody>
You need to use :contains() selector that select element has special text content.
$('#table-detail > tbody > tr:nth-child(7) > td:nth-child(2):contains("Tarte-fine")').css('display', 'none');
Also you can simplify the code and use :eq() selector instead of :nth-child
$('#table-detail tr:eq(6) td:eq(1):contains("Tarte-fine")').css('display', 'none');
$('#table-detail > tbody > tr:nth-child(7) > td:nth-child(2):contains("Tarte-fine")').css('color', 'red');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table-detail" class="table table-striped">
<tbody>
<tr>
<td># Commande</td>
<td>26</td>
</tr>
<tr>
<td>Statut Commande</td>
<td>Non traitée</td>
</tr>
<tr>
<td>Statut Laboratoire</td>
<td>Assignée</td>
</tr>
<tr>
<td>Nom</td>
<td>Client Deux</td>
</tr>
<tr>
<td>Nature</td>
<td>Client Mage</td>
</tr>
<tr>
<td>Date Retrait</td>
<td></td>
</tr>
<tr>
<td>Catégorie</td>
<td>Tarte-fine</td> <!-- CONTENT TO CHECK IN THIS CHILD ELEMENT -->
</tr>
<tr>
<td>Produit</td>
<td>Abricots</td>
</tr>
<tr>
<td># Personnes</td>
<td>10</td>
</tr>
<tr> <!-- CHILD ELEMENT TO HIDE -->
<td>Taille (cm)</td>
<td>16</td>
</tr>
<tr>
<td>Inscription</td>
<td></td>
</tr>
<tr>
<td>Décoration petites fleurs</td>
<td>undefined</td>
</tr>
<tr>
<td>Décoration Chocolat et fruits</td>
<td>undefined</td>
</tr>
<tr>
<td>Nombre de sandwiches</td>
<td></td>
</tr>
<tr>
<td>Poids</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 1</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 2</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 3</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 4</td>
<td></td>
</tr>
<tr>
<td>Couleur du ruban</td>
<td></td>
</tr>
<tr>
<td>Prix</td>
<td>58</td>
</tr>
<tr>
<td>Total</td>
<td>0</td>
</tr>
</tbody>
</table>
Note that :contain() return unwanted result in some case, so you can use .filter() instead
$('#table-detail tr:eq(6) td:eq(1)').filter(function(){
return $(this).text() == "Tarte-fine";
}).css('display', 'none');
You could check if that cell contains the specific text using :contains and hide that other cell using hide():
$(function() {
var found = $("#table-detail > tbody > tr:nth-child(7) > td:nth-child(2):contains(Tarte-fine)").length > 0;
if (found) {
$("#table-detail > tbody > tr:nth-child(10)").hide();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table-detail" class="table table-striped">
<tbody>
<tr>
<td># Commande</td>
<td>26</td>
</tr>
<tr>
<td>Statut Commande</td>
<td>Non traitée</td>
</tr>
<tr>
<td>Statut Laboratoire</td>
<td>Assignée</td>
</tr>
<tr>
<td>Nom</td>
<td>Client Deux</td>
</tr>
<tr>
<td>Nature</td>
<td>Client Mage</td>
</tr>
<tr>
<td>Date Retrait</td>
<td></td>
</tr>
<tr>
<td>Catégorie</td>
<td>Tarte-fine</td>
<!-- CONTENT TO CHECK IN THIS CHILD ELEMENT -->
</tr>
<tr>
<td>Produit</td>
<td>Abricots</td>
</tr>
<tr>
<td># Personnes</td>
<td>10</td>
</tr>
<tr>
<!-- CHILD ELEMENT TO HIDE -->
<td>Taille (cm)</td>
<td>16</td>
</tr>
<tr>
<td>Inscription</td>
<td></td>
</tr>
<tr>
<td>Décoration petites fleurs</td>
<td>undefined</td>
</tr>
<tr>
<td>Décoration Chocolat et fruits</td>
<td>undefined</td>
</tr>
<tr>
<td>Nombre de sandwiches</td>
<td></td>
</tr>
<tr>
<td>Poids</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 1</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 2</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 3</td>
<td></td>
</tr>
<tr>
<td>Sandwiches 4</td>
<td></td>
</tr>
<tr>
<td>Couleur du ruban</td>
<td></td>
</tr>
<tr>
<td>Prix</td>
<td>58</td>
</tr>
<tr>
<td>Total</td>
<td>0</td>
</tr>
</tbody>
</table>
As an alternative this is the code to do what you need without using jquery.
This is by the way a more solid solution since you don't need to know the numerical order of both of the rows that contain the cell you want to check and the cell you want to hide.
const rows = document.getElementsByTagName('tr');
let textToCheck = 'Tarte-fine';
let childTextOfTheElementToHide = 'Taille (cm)';
let check = Object.keys(rows).filter(key => {
return rows[key].children[1].innerHTML === textToCheck
});
if(check.length > 0){
let hide = Object.keys(rows).filter(key => {
return rows[key].children[0].innerHTML === childTextOfTheElementToHide
});
rows[hide].style.display = 'none';
}

Hide all the rows after a specific row

I'm developing an ASP.NET MVC application with C#, .NET Framework 4.7 and jQuery 3.1.1.
I have a view with a table:
<table id="myTable">
<tbody>
<tr> ... </tr>
<tr> ... </tr>
<tr> ... </tr>
<tr id="row_x"> ... </tr>
<tr> ... </tr>
<tr> ... </tr>
<tr> ... </tr>
...
I want to hide all the rows under the row <tr id="row_x"> ... </tr> but I don't know how to access those rows. Do I need to set an id to all of them?
I've thought to surround them with a <div> but I don't think it is a good idea or possible.
You can use the jQuery method nextAll()
$("#row_x").nextAll().hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tbody>
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr id="row_x">
<td>Row 5</td>
</tr>
<tr>
<td>Row 6</td>
</tr>
<tr>
<td>Row 7</td>
</tr>
<tr>
<td>Row 8</td>
</tr>
<tr>
<td>Row 9</td>
</tr>
</tbody>
</table>
$("#row_x").nextAll('tr').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tbody>
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr id="row_x">
<td>Row 5</td>
</tr>
<tr>
<td>Row 6</td>
</tr>
<tr>
<td>Row 7</td>
</tr>
<tr>
<td>Row 8</td>
</tr>
<tr>
<td>Row 9</td>
</tr>
</tbody>
</table>
Just try like this
$('#row_x').nextAll('tr').hide();

two column html table with group

I expect next to name column is besides iphone, why my table doesn't work as expected?
<table>
<tbody>
<tr>
<td>
<tr>
<td>Name:</td>
<td>iphone</td>
</tr>
<tr>
<td>Price:</td>
<td>123</td>
</tr>
<tr>
<td>Qty</td>
<td>1</td>
</tr>
</td>
<td>next to name:</td>
<td>12345</td>
</tr>
</tbody>
</table>
You can't write tr inside of td. You can add table wrapper for the <tr>
<table border='1'>
<tbody>
<tr>
<td>
<table>
<tr>
<td>Name:</td>
<td>iphone</td>
</tr>
<tr>
<td>Price:</td>
<td>123</td>
</tr>
<tr>
<td>Qty</td>
<td>1</td>
</tr>
</table>
</td>
<td>next to name:</td>
<td>12345</td>
</tr>
</tbody>
</table>

Categories