How to add class same record ?
<table>
<tr>
<td>ID</td>
<td>Name</td>
</tr>
<tr>
<td>1</td>
<td>haris</td>
</tr>
<tr>
<td>2</td>
<td>ali</td>
</tr>
<tr>
<td>3</td>
<td>haris</td>
</tr>
</table>
how to add class or how to add style in this duplicate record??
Iterate over all tr and filter out duplicate tr for applying class.
// object for refering text
var obj = {};
// get all tr except the first one which holds header
$('table tr:not(:first-child)').filter(function() {
// get td contents and trim out space
var txt = $('td:last-child', this).text().trim();
// check already defined in object or not
if (txt in obj)
// if defined return true, it's dupe
return true;
// else define the property
obj[txt] = true;
// add class to filtered tr
}).addClass('dup')
// object for refering text
var obj = {};
// get all tr except the first one which holds header
$('table tr:not(:first-child)').filter(function() {
// get td contents and trim out space
var txt = $('td:last-child', this).text().trim();
// check already defined in object or not
if (txt in obj)
// if defined return true, it's dupe
return true;
// else define the property
obj[txt] = true;
// add class to filtered tr
}).addClass('dup')
.dup {
color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>ID</td>
<td>Name</td>
</tr>
<tr>
<td>1</td>
<td>haris</td>
</tr>
<tr>
<td>2</td>
<td>ali</td>
</tr>
<tr>
<td>3</td>
<td>haris</td>
</tr>
</table>
</table>
Related
I am trying to get the value of the cell right of the cell where i click.
But right now I get the value of the cell I want, but I can click any cell in that row and get the desired value. But it should only be possible with the first column. So I click the any cell in the first column and I wanna get it's next neighbour cell value.
document.querySelector("#tableEventListId").addEventListener("click",event => {
let dataTr = event.target.parentNode;
let deleteEventId = dataTr.querySelectorAll("td")[1].innerText;
console.log(deleteEventId);
alert(deleteEventId);
Any help?
You can use nextElementSibling
document.getElementById('table1').onclick = function(event){
//REM: Target
var tElement = event.target;
if(
//REM: Only cells (=<td>)
tElement.tagName === 'TD' &&
//REM: Only first column cells
tElement.parentNode.firstElementChild === tElement
){
//REM: Next Elementsibling of Target or Null
var tNext = tElement.nextElementSibling;
if(tNext){
console.log('TD: ', tElement.textContent);
console.log('Next: ', tElement.nextElementSibling.textContent)
}
}
}
table, td{
border: 1px solid black
}
<table id = 'table1'>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
</tr>
</thead>
<tbody>
<tr>
<td>A1</td>
<td>B1</td>
<td>C1</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
<td>C2</td>
</tr>
<tr>
<td>A3</td>
<td>B3</td>
<td>C3</td>
</tr>
</tbody>
</table>
There is no HTML, so I can assume it's something like
<table border="1">
<tr>
<td class="first-column">1.1 (click here)</td>
<td>1.2</td>
<td>1.3</td>
</tr>
<tr>
<td class="first-column">2.1 (click here)</td>
<td>2.2</td>
<td>2.3</td>
</tr>
</table>
According to this HTML, you can try
const firstColumns = document.querySelectorAll(".first-column");
for (let i = 0; i < firstColumns.length; i++) {
firstColumns[i].addEventListener("click", function(event) {
let dataTr = event.target.parentNode;
let deleteEventId = dataTr.querySelectorAll("td")[1].innerText;
console.log(deleteEventId);
alert(deleteEventId);
});
}
Have a look https://jsfiddle.net/vyspiansky/k2toLd8w/
I would recommend you to a an event on every td element of the table. Then use nextElementSibling to get a next cell.
Look code snippet to see the example.
const cells = document.querySelectorAll('#tableEventListId td');
cells.forEach(cell => cell.onclick = function(){
const nextCell = cell.nextElementSibling;
if (nextCell)
alert(nextCell.innerHTML);
})
<table id="tableEventListId">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>11</td>
<td>22</td>
<td>33</td>
<td>44</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
<tr>
<td>1111</td>
<td>2222</td>
<td>3333</td>
<td>4444</td>
</tr>
</table>
If you want it to work only for cells at first column change the selector to #tableEventListId td:first-child.
I'm trying to modify a element using JS however this element does not have any unique properties like ID. Also the table in which this element resides does not have a unique class. Also, the HTML page has multiple tables and td elements.
For example:
Existing HTML :
<table border="1">
<tbody>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
<tr>
<td>12334567</td>
<td>BirthName</td>
</tr>
</tbody>
</table>
I'm trying to modify the cell which contains the value "BirthName" to "BirthName (Sidharth)"
Something Like this:
<table border="1">
<tbody>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
<tr>
<td>12334567</td>
<td>BirthName (Sidharth)</td>
</tr>
</tbody>
</table>
You can find all having BirthName by using bellow colde
const allTds = document.querySelectorAll('td')
// Find the td element that contains the text "BirthName"
const birthDateTd = Array.from(allTds).filter(td=>td.textContent==='BirthName')
After that you can target that <td> as you want.
You can do checking the text for all td and change where matches birthname
let element = document.querySelectorAll('td');
for(let i = 0; i<element.length; i++){
if(element[i].innerText == 'BirthName'){
element[i].innerText += '(Sidharth)';
}
}
If the text is unique then you can use Xpath as shown below and change it.
var td = document.evaluate("//td[contains(text(), 'BirthName')]", document, null, XPathResult.ANY_TYPE, null );
var thisTd = td.iterateNext();
thisTd.innerHTML = "BirthName (Sidharth)";
<table border="1">
<tbody>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
<tr>
<td>12334567</td>
<td>BirthName</td>
</tr>
</tbody>
</table>
I have many tables each one with an ID, (table1,2,3,...), and in each one I have many TD's <td><a href
example :
<table id="myTable1" class="someclass">
<tbody>
<tr>
<td>blablabla</td>
<td>random text</td>
<td>randomtext</td>
</tr>
</tbody>
</table>
</td>
<table id="myTable2" class="someclasse">
<tbody>
<tr>
<td>blablabla</td>
<td>random text</td>
<td>randomtext</td>
</tr>
</tbody>
</table>
</td>
(don't look at the HTML code it's not important for now )
My goal is to open all hrefs within the table "table X" then open them in new tab. I do that with
var els = document.getElementById("myTable1").querySelectorAll("a[href^='https://domaine.']");
for (var i = 0, l = els.length; i < l; i++) {
var el = els[i];
alert(el)
window.open (el,"_blank");
}
It works like a charm. Now I want to add a checkbox to each table, and if checked to open the href on "the" table I checked (I did some innerHTML to "insert" checkbox). Now my question, how can I get the table ID when I'll check the checkbox?
For example I check the table that have "table6" and then every link in that table gets opened.
table id=1 (checkbox)
table id=2 (checkbox)
etc
if i check the checkbox it will get the table with id 2
You can use closest to get the closest table, then you can get the id from that.
// List of checkboxes
let inputs = Array.from(document.querySelectorAll('input[type=checkbox]'))
// Add a click event to each
inputs.forEach(input => {
input.addEventListener('click', e => {
let target = e.currentTarget
// If the checkbox isn't checked end the event
if (!target.checked) return
// Get the table and id
let table = target.closest('table')
let id = table.id
console.log(id)
})
})
<table id="abc">
<tr>
<td><input type="checkbox"></td>
</tr>
</table>
<table id="def">
<tr>
<td><input type="checkbox"></td>
</tr>
</table>
<table id="ghi">
<tr>
<td><input type="checkbox"></td>
</tr>
</table>
<table id="jkl">
<tr>
<td><input type="checkbox"></td>
</tr>
</table>
You say that you are adding the checkbox dynamically, so you won't want to do a querySelectorAll like I did above. You will want to add it when it is created like this:
// List of tables
let tables = Array.from(document.querySelectorAll('table'))
// insert the checkbox dynamically
tables.forEach(table => {
table.innerHTML = '<tr><td><input type="checkbox"></td></tr>'
// Get the checkbox
let checkbox = table.querySelector('input[type=checkbox]')
// Add an eventlistener to the checkbox
checkbox.addEventListener('click', click)
})
function click(e) {
let target = e.currentTarget
// If the checkbox isn't checked end the event
if (!target.checked) return
// Get the table and id
let table = target.closest('table')
let id = table.id
console.log(id)
}
<table id="abc">
</table>
<table id="def">
</table>
<table id="ghi">
</table>
<table id="jkl">
</table>
…I want to add a checkbox to each table, and if [it's] checked…open the href [in] "the" table I checked…how can I get the table ID when I'll check the checkbox?
Given that you want to find the id of the <table> within which the check-box <input> is contained in order to select the <table> via its id property you don't need the id; you simply need to find the correct <table>.
To that end I'd suggest placing an event-listener on each of those <table> elements, and opening the relevant links found within. For example (bearing in mind that there are restrictions on opening new windows/tabs on Stack Overflow, I'll simply style the relevant <a> elements rather than opening them):
function highlight(e) {
// here we find the Static NodeList of <a> elements
// contained within the <table> element (the 'this'
// passed from EventTarget.addEventListener()) and
// convert that Array-like collection to an Array
// with Array.from():
Array.from(this.querySelectorAll('a'))
// iterating over the Array of <a> elements using
// Array.prototype.forEach() along with an Arrow
// function:
.forEach(
// here we toggle the 'ifCheckboxChecked' class-name
// via the Element.classList API, adding the class-name
// if the Event.target (the changed check-box, derived
// from the event Object passed to the function from the
// EventTarget.addEventListener function) is checked:
link => link.classList.toggle('ifCheckboxChecked', e.target.checked)
);
}
// converting the Array-like Static NodeList returned
// from document.querySelectorAll() into an Array:
Array.from(document.querySelectorAll('table'))
// iterating over the Array of <table> elements:
.forEach(
// using an Arrow function to pass a reference to the
// current <table> element (from the Array of <table>
// elements to the anonymous function, in which we
// add an event-listener for the 'change' event and
// bind the named highlight() function as the event-
// handler for that event:
table => table.addEventListener('change', highlight)
);
function highlight(e) {
Array.from(this.querySelectorAll('a'))
.forEach(
link => link.classList.toggle('ifCheckboxChecked', e.target.checked)
);
}
Array.from(document.querySelectorAll('table')).forEach(
table => table.addEventListener('change', highlight)
);
body {
counter-reset: tableCount;
}
table {
width: 80%;
margin: 0 auto 1em auto;
border: 1px solid limegreen;
}
table::before {
counter-increment: tableCount;
content: 'table' counter(tableCount);
}
a.ifCheckboxChecked {
background-color: #f90;
}
<table>
<tbody>
<tr>
<td><input type="checkbox"></td>
<td>cell 1</td>
<td>cell 2</td>
<td>cell 3</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><input type="checkbox"></td>
<td>cell 1</td>
<td>cell 2</td>
<td>cell 3</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><input type="checkbox"></td>
<td>cell 1</td>
<td>cell 2</td>
<td>cell 3</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><input type="checkbox"></td>
<td>cell 1</td>
<td>cell 2</td>
<td>cell 3</td>
</tr>
</tbody>
</table>
JS Fiddle demo.
References:
CSS:
::before pseudo-element
Using CSS Counters.
JavaScript:
Array.from().
Array.prototype.forEach().
Arrow Functions.
Element.querySelectorAll().
Event.
EventTarget.addEventListener().
Got a table with most of first cells in tr having first cell with the same value in a different tr. I'm going to use these for tr identification. Eventually, I want tds in these trs interact in a few diferent ways between themselves (pull data one and append into a different td, make calculations based on the data, etc). But for a start, I need all the doubled tr's have text the same color
html
<div class="tableclass">
<table>
<tbody>
<tr>
<td>id1</td>
<td>something else</td>
<td>1</td>
</tr>
<tr>
<td>id2</td>
<td>something else</td>
<td>2</td>
</tr>
<tr>
<td>id2</td>
<td>something else</td>
<td>3</td>
</tr>
<tr>
<td>id3</td>
<td>something else</td>
<td>4</td>
</tr>
<tr>
<td>id1</td>
<td>something else</td>
<td>5</td>
</tr>
<tbody>
</table>
<div>
and jquery
$(".tableclass table tbody tr").each(function(){
var trclass = $(this).find("td:first-child").html();
$(this).addClass(trclass);
$(this).parent().filter(trclass).eq(2).css('color','red');
});
And obviously, i'm doing something wrong.
You can try this:
var rows = $(".tableclass tbody tr");
var iterations = 0;
var rowNo = 0;
rows.each(function () {
var thisRow = $(this);
rowNo++;
if (!thisRow.hasClass('duplicate')) {
var trclass = thisRow.find("td:first-child").html();
var firstcols = thisRow.siblings('tr').find('td:first-child');
firstcols.each(function () {
if ($(this).html() == trclass) {
var dupeRow = $(this).parent();
var dupeRowNo = dupeRow.index() + 1;
thisRow
.addClass('duplicate')
.css({'color': 'red'})
.attr('title', 'Duplicated in row '+dupeRowNo);
dupeRow
.addClass('duplicate')
.css({'color': 'red'})
.attr('title', 'Duplicate of row '+rowNo);
iterations++;
}
})
}
});
//alert(iterations);
It is a little more compicated, but it identifies the duplicate rows without having to go through the each row twice. I added the iterations variable so you can see that it only goes and processes a tr if it has not already identified it before as having duplicates.
I added tooltips to the rows so you know which row is a duplicate of which.
You can see it on this jsfiddle.
I have a list of table rows and these tr's have numbered classes for some reason (leg-1, leg-2 etc). It is already possible to delete a single tr from within this context.
After deleting a tr I need to rename the remaining tr's.
Example:
I have
<tr class="leg-1"></tr>
<tr class="leg-2"></tr>
<tr class="leg-3"></tr>
Now I delete leg-2. Remaining are:
<tr class="leg-1"></tr>
<tr class="leg-3"></tr>
Now I want to rename the remaining tr's, so that it's back to leg-1 and leg-2.
How can this be done??
Thx for any help!
EDIT:
I forgot to mention that it can have more than one tr with class "leg-1", "leg-2" ... So the right starting example would be
<tr class="leg-1"></tr>
<tr class="leg-1"></tr>
<tr class="leg-2"></tr>
<tr class="leg-3"></tr>
<tr class="leg-3"></tr>
Now when I delete leg-2 , both of the tr's with class="leg-3" have to be renamed to be class="leg-2". ..
Sorry I didn't mention this earlier!!
SEE IT IN ACTION
http://jsfiddle.net/Lynkb22n/2/
I'd suggest, at its most straightforward:
$('tr').each(function(i) {
// looking for a class-name that starts with (follows a
// word-boundary: \b) leg- followed by one or more numbers (\d+)
// followed by another word-boundary:
var matchedClass = this.className.match(/\bleg-\d+\b/);
// if a match exists:
if (matchedClass) {
// set the node's className to the same className after replacing
// the found leg-X class name with the string of 'leg-' plus the
// index of the current element in the collection plus one:
this.className = this.className.replace(matchedClass[0], 'leg-' + (i + 1));
}
});
$('tr').each(function(i) {
var matchedClass = this.className.match(/\bleg-\d+\b/);
// if a match exists:
if (matchedClass) {
this.className = this.className.replace(matchedClass[0], 'leg-' + (i + 1));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr class="leg-2323523">
<td>1</td>
</tr>
<tr class="leg-2323523">
<td>2</td>
</tr>
<tr class="leg-2323523">
<td>3</td>
</tr>
<tr class="leg-2323523">
<td>4</td>
</tr>
</tbody>
</table>
Using an id is somewhat easier, since we don't need to preserve pre-existing concurrent ids, as we do with classes:
// selects all <tr> elements, sets their `id` property
// using the anonymous function available within prop():
$('tr').prop('id', function (i) {
// i: the index amongst the collection of <tr> elements:
return 'leg-' + (i+1);
});
$('tr').prop('id', function (i) {
return 'leg-' + (i+1);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
</tbody>
</table>
If the index/row-number is simply to be available to JavaScript, then you could just as easily use the native rowIndex property available to all HTMLTableRowElements:
// selects <tr> elements, binds the 'mouseenter' event-handler:
$('tr').on('mouseenter', function() {
// logs the HTMLTableRowElement rowIndex property
// to the console:
console.log(this.rowIndex);
});
$('tr').on('mouseenter', function() {
console.log(this.rowIndex);
});
td {
border: 1px solid #000;
width: 4em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
</tbody>
</table>
References:
JavaScript:
HTMLTableRowElement.
JavaScript Regular Expression Guide.
String.prototype.match().
String.prototype.replace().
jQuery:
each().
prop().
Updated
Based on your comment below and your updated question, here is an updated solution.
var removed = $(".leg-2"),
siblings = removed.nextAll(), // affect only next siblings to removed element
pos = ""; // store current number after "leg-"
removed.remove(); // remove element
siblings.each(function (k) {
$(this).removeClass(function (i, key) {
pos = key.split("-")[1]; // update number after "leg-"
return (key.match(/\bleg-\S+/g) || []).join(' ');
}).addClass("leg-" + (pos - 1)); // add "leg-" plus new position
});
See it working here.
You can use .removeClass() with .match() to remove class starts with leg and then add class leg plus tr's index using .addClass().
See it working here.
$("tr").each(function (k) {
k++;
$(this).removeClass(function (i, key) {
return (key.match(/\bleg-\S+/g) || []).join(' ');
}).addClass("leg-" + k);
});
Try this it will re-name the class:
$(document).ready(function(){
$("#click").click(function(){
reorder();
});
});
function reorder(){
$('#myTable > tbody > tr').each(function(index) {
console.log($(this).attr('class','leg-'+(index+1)));//avaoid starting fron 0
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tr class="leg-1"><td>a1</td></tr>
<tr class="leg-2"><td>a2</td></tr>
<tr class="leg-3"><td>a3</td></tr>
<tr class="leg-7"><td>a4</td></tr><!--after click on button class will become class="leg-4" -->
<tr class="leg-8"><td>a5</td></tr><!--after click on button class will become class="leg-5" -->
</table>
<button id="click">CliCk</button>