I have a problem sorting a table.
My table HTML is this:
<table>
<tr>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
</table>
And I want it to look like this:
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
</table>
Here is my current sorting code:
var rows = $('tr');
rows.eq(0).find('td').sort(function(a, b) {
return $.text([a]) > $.text([b]) ? 1 : -1;
}).each(function(newIndex) {
var originalIndex = $(this).index();
rows.each(function() {
var td = $(this).find('td');
if (originalIndex !== newIndex)
td.eq(originalIndex).insertAfter(td.eq(newIndex));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tr>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
</table>
The code only sorts by separate rows. I can't use any plugins and I need to do this with jquery or javascript. Can anyone suggestion how to make it work?
It's simple.
Store all the numbers from td in an array.
Sort the array.
Modify the tds according to array.
Here's how you'd do it in JS:
var tds= [].slice.call(document.getElementsByTagName("td")); //Find <td> and store in array
var tdsa=tds.map(function (a) {return Number(a.innerHTML);}); //Take the innerHTMLs
tdsa.sort(); //Sort it
tds.forEach(function(a,i) {a.innerHTML=tdsa[i]}); //Modify <td>'s innerHTML
Try this - method:
get the items of the table into an array
sort the array
rebuild the rows
var columnCount = 2;
var items = [];
$('td').each(function (idx, obj) {
items.push(obj.innerHTML);
});
items.sort();
$('table tr').remove();
for(var i=0; i<items.length; i+=2) {
var row = '<tr>';
for(var j=0; j<columnCount; j++) {
row += '<td>' + items[i+j] + '</td>';
};
row += '</tr>';
$('table').append(row);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tr>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
</table>
Related
I am trying to sort the table using javascript to order by total points at the end. The table is a dynamic one so W1, W2, W3 columns adds up to total. Is there way to order rows them by total in javascript. Each row is dynamically created as well.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="fl-table">
<thead>
<tr>
<th>Player</th>
<th>Player Name</th>
<!-- <th>W1</th>
<th>W2</th> -->
<th>W1</th>
<th>W2</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td class="agl-profile-img-new"><img src="https://via.placeholder.com/70
C/O https://placeholder.com/"></td>
<td>Heather Rankin</td>
<td>4</td>
<td>21</td>
<td>25</td>
</tr>
<tr>
<td class="agl-profile-img-new"><img src="https://via.placeholder.com/70
C/O https://placeholder.com/"></td>
<td>Stephen Puopolo</td>
<td>3</td>
<td>1</td>
<td>4</td>
</tr>
<tr>
<td class="agl-profile-img-new"><img src="https://via.placeholder.com/70
C/O https://placeholder.com/"></td>
<td>Latheesh V M V</td>
<td>2</td>
<td>26</td>
<td>28</td>
</tr>
</tbody>
<tbody>
</tbody>
</table>
Is there is any way? Please help
can you gather the cells into object and sort them like this. https://jsfiddle.net/e4oscnz8/4/
const sortTotal = () => {
const tbl = [...document.getElementsByClassName("fl-table")][0];
const tbody = [...tbl.tBodies][0];
const oObjects = [];
[...tbody.rows].forEach(row => {
const cells = [...row.cells];
const obj = [...row.cells].map(cell => {
return cell.innerHTML;
});
oObjects.push(obj);
});
oObjects.sort((a, b) => a[a.length -2] > b[b.length -2] ? 1 : -1);
[...tbody.rows].forEach((row, i) => {
[...row.cells].forEach((cell, j) => {
cell.innerHTML = oObjects[i][j];
});
});
}
push tr rows into array or object and sort by your custom sort function: https://jsfiddle.net/2dq7m8k9/
you are using jquery so life is good :)
function SortByTotal(tr1, tr2){//descending sorting
var total1 = parseInt(tr1.find('td:last-child').text());
var total2 = parseInt(tr2.find('td:last-child').text());
return ((total1 > total2) ? -1 : ((total1 < total2) ? 1 : 0));
}
var trs=new Array();
$('#mytable tbody').first().children('tr').each(function(){
trs.push($(this).clone());
});
trs.sort(SortByTotal);
$('#mytable tbody').first().empty();
var i=0;
for (i = 0; i < trs.length; i++) {
$('#mytable tbody').first().append(trs[i]);
}
I have many tables and I want to give all tr's individual ids. I loop through all tbody but it only affects first tbody, not all of them. When I add loop indicating each tbody they work. Is there any efficient way available to loop through all tbody and give the tr's individual id. I want to do it using vanilla javascript, no jQuery.
My sample code here :
<table><tbody>
<tr><td>No.</td><td>Name</td><td>Score</td></tr>
<tr><td>01</td><td>ted</td><td>0.50</td></tr>
<tr><td>02</td><td>joe</td><td>0.25</td></tr>
</tbody></table>
<table><tbody>
<tr><td>Name</td><td>Address</td><td>Phone</td></tr>
<tr><td>joe</td><td>LA</td><td>012345</td></tr>
<tr><td>ted</td><td>NY</td><td>0124</td></tr>
</tbody></table>
<table><tbody>
<tr><td>Name</td><td>Spec</td><td>Budget</td></tr>
<tr><td>joe</td><td>i5</td><td>458</td></tr>
<tr><td>ted</td><td>i7</td><td>768</td></tr>
</tbody></table>
Javascript :
var c = document.getElementsByTagName('tbody');
var _trIndex = 1;
for ( i=0; i<c.length; i++) {
var x = c[i].rows;
for (i=0; i<x.length; i++){
x[i].setAttribute('id','tr'+_trIndex++)
}
}
Second Try :
var c = document.getElementsByTagName('tbody');
var _trIndex = 1;
for ( i=0; i<c.length; i++) {
var x = c[0].rows;
for (i=0; i<x.length; i++){
x[i].setAttribute('id','tr'+_trIndex++)
}
var y = c[1].rows;
for (i=0; i<y.length; i++){
y[i].setAttribute('id','tr'+_trIndex++)
}
}
Probably this is what you need:
// Instead of getting the table bodies, I get only the table
// rows inside the tbody elements.
var c = document.querySelectorAll('tbody tr');
// Here I check if definitely the above query found any values.
if ( c ) {
// Then I do the itteration to the found tr elements
for ( i = 0; i < c.length; i++) {
// And here I set the ID the same way you did in your example
c[i].setAttribute('id','tr'+i);
}
}
<table>
<tbody>
<tr><td>No.</td><td>Name</td><td>Score</td></tr>
<tr><td>01</td><td>ted</td><td>0.50</td></tr>
<tr><td>02</td><td>joe</td><td>0.25</td></tr>
</tbody>
</table>
<table>
<tbody>
<tr><td>Name</td><td>Address</td><td>Phone</td></tr>
<tr><td>joe</td><td>LA</td><td>012345</td></tr>
<tr><td>ted</td><td>NY</td><td>0124</td></tr>
</tbody>
</table>
<table>
<tbody>
<tr><td>Name</td><td>Spec</td><td>Budget</td></tr>
<tr><td>joe</td><td>i5</td><td>458</td></tr>
<tr><td>ted</td><td>i7</td><td>768</td></tr>
</tbody>
</table>
You can achieve this with a single line of javascript.
document.querySelectorAll("tbody tr").forEach((element, index) => element.setAttribute("id", "tr" + index));
<table>
<thead>
<tr>
<td>No.</td>
<td>Name</td>
<td>Score</td>
</tr>
</thead>
<tbody>
<tr>
<td>No.</td>
<td>Name</td>
<td>Score</td>
</tr>
<tr>
<td>01</td>
<td>ted</td>
<td>0.50</td>
</tr>
<tr>
<td>02</td>
<td>joe</td>
<td>0.25</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td>Name</td>
<td>Address</td>
<td>Phone</td>
</tr>
<tr>
<td>joe</td>
<td>LA</td>
<td>012345</td>
</tr>
<tr>
<td>ted</td>
<td>NY</td>
<td>0124</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td>Name</td>
<td>Spec</td>
<td>Budget</td>
</tr>
<tr>
<td>joe</td>
<td>i5</td>
<td>458</td>
</tr>
<tr>
<td>ted</td>
<td>i7</td>
<td>768</td>
</tr>
</tbody>
</table>
So I have two different HTML tables that may or may not have same values. Im looking for a way to hightlight individual cells in the tables that have the same value. For example in the table below, when the mouse hovers over a 1 in the first table, it will highlight this cell as well as all of the cells in table 2 that have a 1 in them as well.
I'm able to highlight invidual cells with some simple CSS but dont know how to highlight corresponding cells on different tables.
<table id="table1" border=1>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>1</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
<td>7</td>
<td>1</td>
<td>9</td>
<td>10</td>
</td>
</table>
..........
<table id="table2" border=1>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>1</td>
</tr>
<tr>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>1</td>
</td>
</table>
The given answer worked for this example code, however I was hoping to implement it using user inputted tables such as the following
<script type="text/javascript">
function generateTable()
{
var rows1 = document.getElementById('rows1').value;
var columns1 = document.getElementById('columns1').value;
var tableBegin = '<table border="1">\n';
var body = '';
for(var i=0; i < rows1; i++)
{
body += '<tr>';
for(var j=0; j < columns1; j++)
{
body += '<td>';
body += Math.floor(Math.random()*11);
body += '</td>'
}
body += '</tr>\n';
}
var endTable = '</table>';
document.getElementById('firstTable').innerHTML = tableBegin + body + endTable;
}
function generateTable2()
{
var rows2 = document.getElementById('rows2').value;
var columns2 = document.getElementById('columns2').value;
var tableBegin2 = '<table border="1">\n';
var body2 = '';
for(var i=0; i < rows2; i++)
{
body2 += '<tr>';
for(var j=0; j < columns2; j++)
{
body2 += '<td>';
body2 += Math.floor(Math.random()*11);
body2 += '</td>'
}
body2 += '</tr>\n';
}
var endTable2 = '</table>';
document.getElementById('secondTable').innerHTML = tableBegin2 + body2 + endTable2;
}
</script>
<form name="makeTable1">
Table 1<br>
Rows: <input type="text" name="rows1" id="rows1"><br>
Columns: <input type="text" name="columns1" id="columns1"><br><br>
<input name="generate" type="button" value="Generate Table" onclick='generateTable();'/>
</form>
Table 2<br>
Rows: <input type="text" name="rows2" id="rows2"><br>
Columns: <input type="text" name="columns2" id="columns2"><br>
<form name="makeTable2">
<input name="generate" type="button" value="Generate Table" onclick='generateTable2();'/>
</form>
<div id="firstTable"></div>
How do I modify the answer to be implemented on these tables?
You could try something like this (supposing JQuery is acceptable for you):
$(() => { // we need to attach listeners after the dom is ready
$('td').on('mouseover', (e)=> { // attach handler on TD-s to 'hover' equivalent event
let the = $(e.currentTarget).text() // get current element text
$("td").filter((_,x) => $(x).text() == the).addClass('hover') // find all TD-s with matching content and add marker class
})
$('td').on('mouseout', ()=> { // attach focus lost on TD-s
$(`td`).removeClass('hover') // remove marker class from all TD-s
})
})
.hover {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table1" border=1>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>1</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
<td>7</td>
<td>1</td>
<td>9</td>
<td>10</td>
</tr>
</table>
..........
<table id="table2" border=1>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>1</td>
</tr>
<tr>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>1</td>
</tr>
</table>
I am adding values to table like:
Item,Quantity,Price,TotalPrice
Now there are multiple rows: How can i sum TotalPrice of all to get GrandTotal using Jquery.
Code:
$("#Product").append(" <tr><td id='clientname'>" +ClientName+ "</td> <td id='item'>"+ItemName+"</td> <td id='quantity'>"+Quantity+"</td> <td id='price'>"+Price+"</td> <td id='totalprice'>"+TotalPrice+"</td> <td> <a onClick='deleteRow(this);'>Delete</a> </td> </tr>");
Its possible when i insert new row data its show grand total in textbox/label,Like:
function TotalPriceCalc()
{
var lblTotalPrice = document.getElementById('lblTotalPrice');
lblTotalPrice.value = sum;
}
Here's an example that will sum whatever column index you provide.
$(function() {
$("#subtotal").html(sumColumn(4));
$("#total").html(sumColumn(5));
});
function sumColumn(index) {
var total = 0;
$("td:nth-child(" + index + ")").each(function() {
total += parseInt($(this).text(), 10) || 0;
});
return total;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table style="border-spacing: 10px;">
<tr>
<td>ClientName</td>
<td>ItemName</td>
<td>Quantity</td>
<td>12</td>
<td>34</td>
</tr>
<tr>
<td>ClientName</td>
<td>ItemName</td>
<td>Quantity</td>
<td>56</td>
<td>78</td>
</tr>
<tr>
<td>ClientName</td>
<td>ItemName</td>
<td>Quantity</td>
<td>90</td>
<td>12</td>
</tr>
<tr>
<td colspan="3">Totals</td>
<td id="subtotal"></td>
<td id="total"></td>
</tr>
</table>
After you use class= instead of id= .Cause ID MUST be unique. you need to loop through each row and find totalPrice
$(document).ready(function(){
var TotalValue = 0;
$("#Product tr").each(function(){
TotalValue += parseFloat($(this).find('.totalprice').text());
});
alert(TotalValue);
});
While you tagged Jquery .. This is a Jquery solution so please be sure to include Jquery
You should use classes, not IDs, to name repeated elements. So it should be:
...<td class="totalprice">'+TotalPrice+'</td>...
Then you can do
function TotalPriceCalc() {
var total = 0;
$(".totalprice").each(function() {
total += parseFloat($(this).text());
});
$("#lblTotalPrice").val(total);
}
Have look, this is our table
<table class="table table-bordered">
<thead>
<tr>
<th>1</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td id="loop">50</td>
</tr>
<tr>
<td>1</td>
<td id="loop">60</td>
</tr>
<tr>
<td>1</td>
<td id="loop">70</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="text-right">Total</td>
<td></td>
</tr>
</tbody>
And this is loop to have sum of price
$(function() {
var TotalValue = 0;
$("tr #loop").each(function(index,value){
currentRow = parseFloat($(this).text());
TotalValue += currentRow
});
console.log(TotalValue);
});
Here is a table example:
<table id="tableId">
<thead>
<tr>
<th>line number</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td>
<td>value 1</td>
</tr>
<tr>
<td>3</td>
<td>value 2</td>
</tr>
<tr>
<td>1</td>
<td>value 3</td>
</tr>
</tbody>
</table>
<input type="button" value="relineing" onclick="reLineNumbering('tableId')"/>
I want only the "line number"s to be in sequence like this:
<table id="tableId">
<thead>
<tr>
<th>line number</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>value 1</td>
</tr>
<tr>
<td>2</td>
<td>value 2</td>
</tr>
<tr>
<td>3</td>
<td>value 3</td>
</tr>
</tbody>
</table>
<input type="button" value="relineing" onclick="reLineNumbering('tableId')"/>
I've tried both of the snippets below:
function reLineNumbering(tableId) {
$('#'+tableId+' tbody').each(function (i) {
this.rows[i].cells[0].text('i');
});
}
function reLineNumbering(tableId) {
var rowCount = $('#'+tableId+' tbody tr').length;
for (var i=0; i<rowCount; i++) {
$('#'+tableId+' tbody').rows[i].cells[0].text(i);
}
}
Could someone help me?
This will change the first column to a sequential number starting from 1:
function reLineNumbering(tableId){
$('#' + tableId + ' > tbody > tr').each(function(i, val){
$('td:first', this).text(i+1);
});
}
Fiddle
Plain Javascript - Fiddle:
function reLineNumbering(tableId){
var table = document.getElementById(tableId);
var total = table.rows.length;
for(var i=0; i<total; i++){
if(i > 0){
table.rows[i].cells[0].innerHTML = i;
}
}
}
Or by creating the text node instead of setting innerHTML. In this simple scenario the use of innerHTML isn't a problem, but usually you will want to work with DOM elements and set the text node instead of setting the HTML:
function reLineNumbering(tableId){
var table = document.getElementById(tableId);
var total = table.rows.length, text, cell;
for(var i=0; i<total; i++){
if(i > 0){
text = document.createTextNode(i);
cell = table.rows[i].cells[0];
cell.removeChild(cell.firstChild);
cell.appendChild(text);
}
}
}
Try
$('#tableId > tbody > tr').find('td:first').text(function(idx, text){
return idx + 1
})
Demo: Fiddle
this is the correct answer:
function reLineNumbering(tableId) {
var myTable=document.getElementById(tableId);
var rowCount = myTable.rows.length;
for (var i = 1; i < rowCount; i++) {
myTable.rows[i].cells[0].innerHTML = i;
}
}
For a VanillaJS version of the same thing:
(function(t)
{
for(var i=1;i<t.rows.length;i++)
{
t.rows[i].cells[0].innerHTML += ' Vanilla';
}
}(document.getElementById('tableId')));
Which I added to the fiddle of Arun
I post it here, because it's not an awful lot longer than the jQ version of the same code, but it is faster.
You can change it to:
var t = document.getElemebtById('tableId');
for(var i=1;i<t.rows.length;i++)
{
t.rows[i].cells[0].innerHTML = 1 + i;//number tbl
}
If you don't feel comfortable using the IIFE.
PS: the loop could be simplified to:
for(var i=1;i<t.rows.length;)//do nothing here
{
t.rows[i].cells[0].innerHTML = i++;//increment i here
}