How to delete two "tr" rows with js? - javascript

When I delete product into basket, products deleted successfully but company name does not delete. I'm using javascript. i cant solve the problem, help me pls...
function getCurrentRow(t) {
var v = parseInt($.trim(t.attr("data-row-id")));
if (isNaN(v)) {
console.log("data-row-id:null");
return null;
}
var currentRow = getRow(v);
if (currentRow == null) {
console.log("currentRow:null");
return null;
}
return currentRow;
}
// Delete
basketContainer.on('click', 'button[data-button-name="delete"]', function() {
var o = $(this);
var t = o.closest("tr");
var currentRow = getCurrentRow(t);
if (currentRow == null) {
return;
}
postData(t, currentRow.index, {
"basketid": currentRow.id,
"pdoductid": currentRow.ProductID,
"count": 0,
"cmdtype": cmdTypes.Delete
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<table>
<thead>
<tr data-row-id="item.id">
<td colspan="4" style="color: #d53434">Shop: <strong>Shop name</strong></td>
</tr>
</thead>
<tbody>
<tr role="row" data-row-id="item2.id">
...
</tr>
</tbody>
</table>

You mean remove the table when no more products from that shop?
$("#basketContainer").on('click', 'button[data-button-name="delete"]', function() {
const $tr = $(this).closest("tr");
const $tb = $(this).closest("tbody");
$tr.remove()
if ($tb.find("tr").length === 0) $tb.closest("table").remove()
});
table {
border: 1px solid black
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="basketContainer">
<table>
<thead>
<tr data-row-id="item.id">
<td colspan="4" style="color: #d53434">Shop: <strong>Shop name 1</strong></td>
</tr>
</thead>
<tbody>
<tr role="row" data-row-id="item2.id">
<td><button type="button" data-button-name="delete">Delete</button></td>
</tr>
<tr role="row" data-row-id="item2.id">
<td><button type="button" data-button-name="delete">Delete</button></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr data-row-id="item.id">
<td colspan="4" style="color: #d53434">Shop: <strong>Shop name 2</strong></td>
</tr>
</thead>
<tbody>
<tr role="row" data-row-id="item2.id">
<td><button type="button" data-button-name="delete">Delete</button></td>
</tr>
<tr role="row" data-row-id="item2.id">
<td><button type="button" data-button-name="delete">Delete</button></td>
</tr>
</tbody>
</table>
</div>

Related

Javascript table filter doesn't show table headers

Im using a script to filter a table based on a select value. The script works, the only problem is that it filter also the headers of the table, which Id like to show always.
This is the javascript and the table:
$(document).ready(function($) {
$('#mac').change(function() {
var selection = $(this).val();
var dataset = $('table').find('tr');
dataset.show();
dataset.filter(function(index, item) {
return $(item).find('td:last-child').text().split(';').indexOf(selection) === -1;
}).hide();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<input type="text" id="mac">
<table id="table_id" class="display">
<thead>
<tr>
<th>Tipo</th>
<th>Descrizione</th>
<th>Scadenza</th>
<th>Società</th>
<th>Macrotema</th>
</tr>
</thead>
<tbody>
<tr style=" background-color:">
<td>Prescrizione</td>
<td>Corsi di aggiornamento </td>
<td>
<nobr>2025/01/01</nobr>
</td>
<td>XXXX</td>
<td>SEDE; </td>
</tr>
<tr style=" background-color:">
<td>Prescrizione</td>
<td>Rinnovo iscrizione</td>
<td>
<nobr>2024/12/31</nobr>
</td>
<td>XXXX</td>
<td>SEDE; </td>
</tr>
<tr style=" background-color:">
</tbody>
</table>
My question is: How can I edit the script to show the headers?
Thank you for your time :D
let me know if I have to explain the situation better.
you can add a more specific selector :
var dataset = $('table tbody tr');
Please find the below solution with output.
$(document).ready(function($) {
$('#mac').change(function() {
var selection = $(this).val();
var dataset = $('table').find('tr');
dataset.show();
dataset.filter(function(index, item) {
return index !== 0 && $(item).find('td:last-child').text().split(';').map(x => x.trim()).indexOf(selection) === -1;
}).hide();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<input id="mac">
<table id="table_id" class="display">
<thead>
<tr>
<th>Tipo</th>
<th>Descrizione</th>
<th>Scadenza</th>
<th>Società</th>
<th>Macrotema</th>
</tr>
</thead>
<tbody>
<tr style=" background-color:">
<td>Prescrizione</td>
<td>Corsi di aggiornamento </td>
<td>
<nobr>2025/01/01</nobr>
</td>
<td>XXXX</td>
<td>SEDE; </td>
</tr>
<tr style=" background-color:">
<td>Prescrizione</td>
<td>Rinnovo iscrizione</td>
<td>
<nobr>2024/12/31</nobr>
</td>
<td>XXXX</td>
<td>SEDA; </td>
</tr>
<tr style=" background-color:">
</tbody>
</table>

How to get the entire row data based on a Max value for a column?

function siradaki() {
var high = Math.max.apply(Math, $('.sira').map(function() {
return $(this).text()
}))
alert(high);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table id="myTable">
<tr class="header">
<th style="width:10%;">Name</th>
<th style="width:10%;">Lastname</th>
<th style="width:10%;">Value</th>
</tr>
<tr>
<td>Deneme</td>
<td>SDeneme</td>
<td class="sira">100</td>
</tr>
<tr>
<td>Ornek</td>
<td>SOrnek</td>
<td class="sira">150</td>
</tr>
</table>
<button name="siradaki" id="siradaki" class="btn btn-warning" onclick="siradaki();">Sıradaki Kim ?</button>
This code works. But how can I get Name and Lastname along with max Value?
Grab all rows instead of just a value from .sira cell and then analyze them. That way you will have full info when you find max.
function siradaki() {
var max = -Infinity;
var maxRow;
$('tbody tr').each(function() {
var value = parseInt($('.sira', this).text(), 10);
if (value > max) {
max = value;
maxRow = $(this);
}
});
alert(maxRow.text());
}
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table id="myTable">
<thead>
<tr class="header">
<th style="width:10%;">Name</th>
<th style="width:10%;">Lastname</th>
<th style="width:10%;">Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Deneme</td>
<td>SDeneme</td>
<td class="sira">100</td>
</tr>
<tr>
<td>Ornek</td>
<td>SOrnek</td>
<td class="sira">150</td>
</tr>
</tbody>
</table>
<button name="siradaki" id="siradaki" class="btn btn-warning" onclick="siradaki();">Sıradaki Kim ?</button>
</html>
You can use .siblings to get the sibling td elements and .textContent to get their text. Store them in a string and alert them with the high
var str='';
function siradaki(){
var high = Math.max.apply(Math, $('tr > .sira').map(function(){
var a=Object.values($(this).siblings())
str=a[0].textContent+ " " + a[1].textContent;
return $(this).text();
}))
alert (str + " " +high );
}
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table id="myTable">
<tr class="header">
<th style="width:10%;">Name</th>
<th style="width:10%;">Lastname</th>
<th style="width:10%;">Value</th>
</tr>
<tr>
<td>Deneme</td>
<td>SDeneme</td>
<td class="sira">100</td>
<tr>
<tr>
<td>Ornek</td>
<td>SOrnek</td>
<td class="sira">150</td>
<tr>
</table>
<button name="siradaki" id="siradaki" class="btn btn-warning" onclick="siradaki();">Sıradaki Kim ?</button>
</html>
function siradaki(){
var value = $('tr td').map(function () {
return parseInt($(this).text(), 10) ? parseInt($(this).text(), 10) : null;
}).get();
var high = Math.max.apply(Math, value);
alert(high);
}
try this dont add class grab all rows
try to sort a list by value in desc order, and get the first object from the list
function siradaki() {
var high = $('.sira').sort(function(a, b) {
return $(a).text() < $(b).text()
})[0];
console.log($(high).closest('tr').find('td:eq(0)').text());
console.log($(high).closest('tr').find('td:eq(1)').text());
console.log($(high).text());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table id="myTable">
<tr class="header">
<th style="width:10%;">Name</th>
<th style="width:10%;">Lastname</th>
<th style="width:10%;">Value</th>
</tr>
<tr>
<td>Deneme</td>
<td>SDeneme</td>
<td class="sira">100</td>
</tr>
<tr>
<td>Ornek</td>
<td>SOrnek</td>
<td class="sira">150</td>
</tr>
</table>
<button name="siradaki" id="siradaki" class="btn btn-warning" onclick="siradaki();">Sıradaki Kim ?</button>
You can try like this
function siradaki() {
var arr = [];
$('.sira').each(function() {
arr.push($(this).text());
var Names = $(this).siblings('td').text();
console.log('Names: '+ Names);
})
var maxValue = Math.max.apply(Math, arr);
console.log('maxValue: '+maxValue);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table id="myTable">
<tr class="header">
<th style="width:10%;">Name</th>
<th style="width:10%;">Lastname</th>
<th style="width:10%;">Value</th>
</tr>
<tr>
<td>Deneme</td>
<td>SDeneme</td>
<td class="sira">100</td>
</tr>
<tr>
<td>Ornek</td>
<td>SOrnek</td>
<td class="sira">150</td>
</tr>
</table>
<button name="siradaki" id="siradaki" class="btn btn-warning" onclick="siradaki();">Sıradaki Kim ?</button>
Just check out this siblings method of jQuery here - https://api.jquery.com/siblings/
You can access siblings using tr tag as the parameters and distinguish the first name and the last name using index i.e. 0 for first and 1 for last name.

Show in jQuery seach the closest TR that was a header from data

This is my fiddle: https://jsfiddle.net/qpouvped/2/
What I want to do is display the header with the corresponding alphabetical letter of the searched name. But I had no success!
If you see the code and look for "Nanana", I want to display this line, and the gray header C, of which "Nanana" belongs.
Can anyone help me with this?
My HTML:
<div class="row">
<div class="col-12 col-lg-4">
<label for="nome">Nome</label>
<input type="text" class="form-control filter-nome" value="">
</div>
</div>
<table class="table table-stripped table-bordered lista-certidoes">
<thead>
<tr>
<th>Nº</th>
<th>Nome</th>
<th>Nº PROTOCOLO</th>
</tr>
</thead>
<tbody>
<tr class="subtitulo">
<td colspan="3" class="cab_interno">A</td>
</tr>
<tr>
<td >137418</td>
<td >Nonono Nonono Nonono</td>
<td >11225566</td>
</tr>
<tr class="subtitulo">
<td colspan="3" class="cab_interno">B</td>
</tr>
<tr>
<td >122222</td>
<td >Nonono Nonono Nonono</td>
<td >11225566</td>
</tr>
<tr class="subtitulo">
<td colspan="3" class="cab_interno">C</td>
</tr>
<tr>
<td >122222</td>
<td >Nonono Nonono Nonono</td>
<td >11225566</td>
</tr>
<tr>
<td >133</td>
<td >Nanana Nonono Nonono</td>
<td >11225566</td>
</tr>
</tbody>
</table>
My jQuery:
$(".filter-nome").keyup(function(){
var value = $(this).val();
$(".lista-certidoes tbody tr").each(function(index){
$row = $(this);
var id = $row.find("td:nth-child(2)").text();
if (id.indexOf(value) != 0) {
$(this).hide();
} else {
$(this).show();
//$(this).parent('tbody').next('td.cab_interno').show();
}
});
});
The alphabetic heading is a previous sibling of the closest tr, so you want to use .prevAll(). These are returned in order of distance from the current row, so the first one will be the heading for that group.
You also shouldn't process the heading rows in the .each() loop. Just hide everything first, and show the data rows that match, along with their headings.
$(".filter-nome").keyup(function() {
var value = $(this).val();
if (value == "") {
// Show everything when filter is empty
$(".lista-certidoes tbody tr").show();
return;
}
$(".lista-certidoes tbody tr").hide();
$(".lista-certidoes tbody tr:not(.subtitulo)").each(function(index) {
$row = $(this);
var id = $row.find("td:nth-child(2)").text();
if (id.indexOf(value) == 0) {
$row.show();
$row.closest("tr").prevAll(".subtitulo").first().show();
}
});
});
.lista-certidoes {
.cab_interno {
background-color: #333;
color: #fff;
text-align: center;
padding: 8px;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.0.4/popper.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" />
<div class="row">
<div class="col-12 col-lg-4">
<label for="nome">Nome</label>
<input type="text" class="form-control filter-nome" value="">
</div>
</div>
<table class="table table-stripped table-bordered lista-certidoes">
<thead>
<tr>
<th>Nº</th>
<th>Nome</th>
<th>Nº PROTOCOLO</th>
</tr>
</thead>
<tbody>
<tr class="subtitulo">
<td colspan="3" class="cab_interno">A</td>
</tr>
<tr>
<td>137418</td>
<td>Nonono Nonono Nonono</td>
<td>11225566</td>
</tr>
<tr class="subtitulo">
<td colspan="3" class="cab_interno">B</td>
</tr>
<tr>
<td>122222</td>
<td>Nonono Nonono Nonono</td>
<td>11225566</td>
</tr>
<tr class="subtitulo">
<td colspan="3" class="cab_interno">C</td>
</tr>
<tr>
<td>122222</td>
<td>Nonono Nonono Nonono</td>
<td>11225566</td>
</tr>
<tr>
<td>133</td>
<td>Nanana Nonono Nonono</td>
<td>11225566</td>
</tr>
</tbody>
</table>

code working in jfiddle but not in jfiddle result

Here is my jsFiddle
HTML:
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<table id="tableone" border="2" cellspacing="2" cellpadding="2">
<thead>
<tr>
<th class="col1">Seminar Name</th>
<th class="col2">Seminar Date</th>
<th class="col3">Download Link</th>
<tbody>
<tr class="del">
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td>
<button class="editbtn">Edit</button>
</td>
</tr>
<tr class="del" id="tablerow">
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td>
<button class="editbtn">Edit</button>
</td>
</tr>
</tbody>
<button class="addnewrow">Add New Row</button>
Javascript:
$('#tableone').on('click', '.editbtn', function() {
var $this = $(this);
var tds = $this.closest('tr').find('td').filter(function() {
return $(this).find('.editbtn').length === 0;
});
if ($this.html() === 'Edit') {
$this.html('Save');
tds.prop('contenteditable', true);
} else {
$this.html('Edit');
tds.prop('contenteditable', false);
}
});
$('.addnewrow').click(function() {
var $tr = $("#tableone").find("tr:last");
var $clone = $tr.clone();
$clone.find('input').val('');
$tr.after($clone);
});
the code works fine in jfiddle but when I go to
https://jsfiddle.net/yT92K/42/show/result
the "add new row" function has stopped working.
Also, when I try to export the file as an individual .html file, it just opens a blank page in my browser (chrome). Does anyone have a fix for this?
$('#tableone').on('click', '.editbtn', function() {
var $this = $(this);
var tds = $this.closest('tr').find('td').filter(function() {
return $(this).find('.editbtn').length === 0;
});
if ($this.html() === 'Edit') {
$this.html('Save');
tds.prop('contenteditable', true);
} else {
$this.html('Edit');
tds.prop('contenteditable', false);
}
});
$('.addnewrow').click(function() {
var $tr = $("#tableone").find("tr:last");
var $clone = $tr.clone();
$clone.find('input').val('');
$tr.after($clone);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableone" border="2" cellspacing="2" cellpadding="2">
<thead>
<tr>
<th class="col1">Seminar Name</th>
<th class="col2">Seminar Date</th>
<th class="col3">Download Link</th>
</thead>
<tbody>
<tr class="del">
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td>
<button class="editbtn">Edit</button>
</td>
</tr>
<tr class="del" id="tablerow">
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td>
<button class="editbtn">Edit</button>
</td>
</tr>
</tbody>
<button class="addnewrow">Add New Row</button>
This is an addition to #zhuravlyoy's answer, since his answer won't make the new row blank if the previous one was edited.
$( document ).ready(function() {
$('#tableone').on('click', '.editbtn', function() {
var $this = $(this);
var tds = $this.closest('tr').find('td').filter(function() {
return $(this).find('.editbtn').length === 0;
});
if ($this.html() === 'Edit') {
$this.html('Save');
tds.prop('contenteditable', true);
} else {
$this.html('Edit');
tds.prop('contenteditable', false);
}
});
$('.addnewrow').click(function() {
var $tr = $("#tableone").find("tr:last");
var $clone = $tr.clone();
$clone.children('.td').empty();
$clone.children('.td').attr('contenteditable', false);
$clone.find('.editbtn').text('Edit');
$tr.after($clone);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableone" border="2" cellspacing="2" cellpadding="2">
<thead>
<tr>
<th class="col1">Seminar Name</th>
<th class="col2">Seminar Date</th>
<th class="col3">Download Link</th>
<tbody>
<tr class="del">
<td contenteditable="false" class="td"></td>
<td contenteditable="false" class="td"></td>
<td contenteditable="false" class="td"></td>
<td>
<button class="editbtn">Edit</button>
</td>
</tr>
<tr class="del" id="tablerow">
<td contenteditable="false" class="td"></td>
<td contenteditable="false" class="td"></td>
<td contenteditable="false" class="td"></td>
<td>
<button class="editbtn">Edit</button>
</td>
</tr>
</tbody>
<button class="addnewrow">Add New Row</button>
$( document ).ready(function() {
$('#tableone').on('click', '.editbtn', function() {
var $this = $(this);
var tds = $this.closest('tr').find('td').filter(function() {
return $(this).find('.editbtn').length === 0;
});
if ($this.html() === 'Edit') {
$this.html('Save');
tds.prop('contenteditable', true);
} else {
$this.html('Edit');
tds.prop('contenteditable', false);
}
});
$('.addnewrow').click(function() {
var $tr = $("#tableone").find("tr:last");
var $clone = $tr.clone();
$clone.find('input').val('');
$clone.find('td:not(:last)').empty();
$clone.find('td:not(:last)').prop('contenteditable', false);
$clone.find('button').html('Edit');
$tr.after($clone);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableone" border="2" cellspacing="2" cellpadding="2">
<thead>
<tr>
<th class="col1">Seminar Name</th>
<th class="col2">Seminar Date</th>
<th class="col3">Download Link</th>
<tbody>
<tr class="del">
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td>
<button class="editbtn">Edit</button>
</td>
</tr>
<tr class="del" id="tablerow">
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td contenteditable="false"></td>
<td>
<button class="editbtn">Edit</button>
</td>
</tr>
</tbody>
<button class="addnewrow">Add New Row</button>
Try this!

Find and display only the highest score in the table

I was hoping you could help me with my code..
I have an HTML table with dynamically added data.
So, I wanted to create a filter for it so the same test taken by the same person be removed and display only one per person and get only the highest score.
<table class="test-table">
<thead>
<tr role="row">
<th> Name </th>
<th> Test </th>
<th> Date </th>
<th> Score </th>
</thead>
<tbody>
<tr role="row">
<td title="Name">John Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">8</td>
</tr>
<tr role="row">
<td title="Name">John Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">3</td>
</tr>
<tr role="row">
<td title="Name">Jane Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">8</td>
</tr>
<tr role="row">
<td title="Name">Jane Doe</td>
<td title="Test">Exam 2</td>
<td title="Date">02/11/2017</td>
<td title="Score">8</td>
</tr>
</tbody>
</table>
So it should only display Jonh Doe's Exam 1 with the score of 8.
But show both of Jane Doe's because it's two different exams..
Now, I have a script that search for the duplicates but I'm currently stuck..
var nTds = document.querySelectorAll('[title="Name"]'),
tTds = document.querySelectorAll('[title="Test"]'),
test = [],
names = [];
for (var i = 0; i < nTds.length; i++) {
names.push(nTds[i].textContent);
}
for (var i = 0; i < tTds.length; i++) {
test.push(tTds[i].textContent);
}
const nCount = names =>
names.reduce((a, b) =>
Object.assign(a, {
[b]: (a[b] || 0) + 1
}), {})
const tCount = test =>
test.reduce((a, b) =>
Object.assign(a, {
[b]: (a[b] || 0) + 1
}), {})
const duplicates = dict =>
Object.keys(dict).filter((a) => dict[a] > 1)
console.log(duplicates(tCount(test)))
console.log(duplicates(nCount(names)))
Thank you so much! any help would be appreciated..
With a checkbox button you can show/hide as you please. Let me know what you don't understand.
function duplicate_hide()
{
var table_rows = document.querySelectorAll('tbody tr');
var unique = {};
var selection = ["Name", "Test", "Score"];
for (row of table_rows)
{
var temp = [];
for (select of selection)
{
temp.push(row.querySelector(`td[title="${select}"]`));
}
// Destructuring assignment
var [the_name, the_test, the_score] = temp;
the_name = the_name.innerHTML;
the_test = the_test.innerHTML;
the_score = the_score.innerHTML == " " ? 0 : the_score.innerHTML;
if (the_name in unique && the_test in unique[the_name])
{
//same test, saved score is lower than current score, hide previous row
if (+unique[the_name][the_test].score < +the_score)
{
unique[the_name][the_test].row.className = "hidden";
unique[the_name][the_test].score = the_score;
unique[the_name][the_test].row = row;
}
else
{
row.className = "hidden";
}
}
else
{
// Create new object if it doesn't exist on name
if (!(the_name in unique))
{
unique[the_name] = {};
}
unique[the_name][the_test] = {score: the_score, row};
}
}
}
function duplicate_show()
{
var table_rows = document.querySelectorAll('tbody tr');
for (row of table_rows)
{
row.className = "";
}
}
function duplicate_check(event)
{
if (event.target.checked)
{
duplicate_hide();
}
else
{
duplicate_show();
}
}
.hidden {
display: none;
}
<div>
<input type="checkbox" onchange="duplicate_check(event)" /> Toggle Me
</div>
<table class="test-table">
<thead>
<tr role="row">
<th> Name </th>
<th> Test </th>
<th> Date </th>
<th> Score </th>
<th> something else </th>
</thead>
<tbody>
<tr class='odd'>
<td title="Name">John Doe</td>
<td title="Test">exam 1</td>
<td title="Date">03/08/2017</td>
<td title="Score">4</td>
</tr>
<tr class='even'>
<td title="Name">John Doe</td>
<td title="Test">exam 1</td>
<td title="Date">03/08/2017</td>
<td title="Score">5</td>
</tr>
<tr class='odd'>
<td title="Name">John Doe</td>
<td title="Test">exam 2</td>
<td title="Date">03/08/2017</td>
<td title="Score">7</td>
</tr>
<tr class='even'>
<td title="Name">Wendy Doe</td>
<td title="Test">exam 1</td>
<td title="Date">03/08/2017</td>
<td title="Score">7</td>
</tr>
<tr class='odd'>
<td title="Name">Wendy Doe</td>
<td title="Test">exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">4</td>
</tr>
<tr class='even'>
<td title="Name">Wendy Doe</td>
<td title="Test">exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">3</td>
</tr>
</tbody>
</table>
please see the demo.If you want add a checkbox to show the rest scores,this code doesn't helped you,and you must grouped the data via [name,test] before render.so you must provide multi table instead,not one table only.the strcture may be like this:
<table>
<thead>
<tr>
<th>Name</th>
<th>Test</th>
<th>Scores</th>
</tr>
</thead>
<tbody>
<tr>
<td title="Name">John Doe</td>
<td title="Test">Exam 1</td>
<td>
<table>
<thead>
<tr>
<th>Date</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<tr>
<td>02/11/2017</td>
<td>8</td>
</tr>
<tr>
<td>02/11/2017</td>
<td>3</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.23.0/polyfill.min.js"></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<table class="test-table">
<thead>
<tr role="row">
<th> Name</th>
<th> Test</th>
<th> Date</th>
<th> Score</th>
</thead>
<tbody>
<tr role="row">
<td title="Name">John Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">8</td>
</tr>
<tr role="row">
<td title="Name">John Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">3</td>
</tr>
<tr role="row">
<td title="Name">Jane Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">8</td>
</tr>
<tr role="row">
<td title="Name">Jane Doe</td>
<td title="Test">Exam 2</td>
<td title="Date">02/11/2017</td>
<td title="Score">8</td>
</tr>
</tbody>
</table>
<script type="text/babel">
let highest = {};
Array.from(document.querySelectorAll('table tbody tr')).forEach((exam) => {
const get = (name) => {
return exam.querySelector(`[title="${name}"]`).textContent;
};
var [name, test, score]=[get('Name'), get('Test'), parseInt(get('Score'))];
let key = [name, test];
if (highest[key] >= score) {
exam.parentNode.removeChild(exam);
return;
}
highest[key] = score;
});
</script>
You seem to be making it too complex. Just loop over the rows in the table body and collect name, test, score and the row it's in. If you encounter a combination more than once, hide the lower score or show the higher score and update the saved score and row.
var rows = document.querySelector('table').tBodies[0].rows;
var seen = {};
[].forEach.call(rows, row => {
var name = row.cells[0].textContent,
test = row.cells[1].textContent,
score = Number(row.cells[3].textContent);
if (seen[name] && seen[name].hasOwnProperty(test)){
if (seen[name][test].score > score) {
row.style.display = 'none';
} else {
seen[name][test].row.style.display = 'none';
seen[name][test] = {score: score, row: row};
}
} else {
seen[name] = {[test]:{score: score, row: row}};
}
})
<table class="test-table">
<thead>
<tr role="row">
<th> Name </th>
<th> Test </th>
<th> Date </th>
<th> Score </th>
</thead>
<tbody>
<tr role="row">
<td title="Name">John Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">8</td>
</tr>
<tr role="row">
<td title="Name">John Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">13</td>
</tr>
<tr role="row">
<td title="Name">John Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">3</td>
</tr>
<tr role="row">
<td title="Name">Jane Doe</td>
<td title="Test">Exam 1</td>
<td title="Date">02/11/2017</td>
<td title="Score">8</td>
</tr>
<tr role="row">
<td title="Name">Jane Doe</td>
<td title="Test">Exam 2</td>
<td title="Date">02/11/2017</td>
<td title="Score">8</td>
</tr>
</tbody>
</table>
In some recent browsers, NodeLists (such as HTMLCollections like rows and those returned by querySelectorAll) have a forEach method that makes it simpler.
This also uses computed property names, which can be avoided but takes a couple more lines of code. If they're not supported, likely nor are arrow functions. Neither are an issue and are easily replaced.

Categories