Mirroring a HTML table with Javascript/jQuery - javascript

I'm trying to mirror a table, with a dynamic grid like 4x4, 7x7, or 9x2.
I dynamically create this:
<table id="mainTable" class="mainClassTable" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr id="row-1">
<td id="col-1" onclick="imgClick(this)">Stuff Here</td>
<td id="col-2" onclick="imgClick(this)">Stuff Here</td>
<td id="col-3" onclick="imgClick(this)">Stuff Here</td>
<td id="col-4" onclick="imgClick(this)">Stuff Here</td>
</tr>
<tr id="row-2">
<td id="col-1" onclick="imgClick(this)">Stuff Here</td>
<td id="col-2" onclick="imgClick(this)">Stuff Here</td>
<td id="col-3" onclick="imgClick(this)">Stuff Here</td>
<td id="col-4" onclick="imgClick(this)">Stuff Here</td>
</tr>
<tr id="row-3">
<td id="col-1" onclick="imgClick(this)">Stuff Here</td>
<td id="col-2" onclick="imgClick(this)">Stuff Here</td>
<td id="col-3" onclick="imgClick(this)">Stuff Here</td>
<td id="col-4" onclick="imgClick(this)">Stuff Here</td>
</tr>
</tbody>
</table>
I'm wondering what would be the best way for each row to get col-1 to move to col-4, and col-2 on col-3. And with uneven columns I fear it would be more complicated.
I found something about shuffling rows, but I want to shuffle columns.
I'm thinking about using jQuery selectors to tediously repositioning each td, but i'm wondering if there might be a nice jquery plugin to rearrange tables.
I don't want draggable, I just want one click to mirror the table (not the contents).
/Edit
So I tried making each col ID unique, but I ended up with this steaming pile of code:
function makeGrid(content, rowCount, colCount)
{
//Empty TD string
tableVarSet = "";
//gridTotal = gridTotal - gridTotal;
//Loop for multiple columns
for (c=1;c<=colCount;c++)
{
//make column var
tableVarSet = tableVarSet + makeColumns(content, c);
}
//Loop for multiple rows
for (i=1;i<=rowCount;i++)
{
//Make new Row
rowVarToAdd = "<tr id=TMPR>"+tableVarSet+"</tr>";
$("#mainTable").append(rowVarToAdd);
//Set new RowID
rowName = "row-" + i;
$("#TMPR").attr('id', rowName);
}
};
function makeColumns(content, count)
{
//Split String
tableVar1 = "<td id=col-"
tableNum = count;
tableVar2 = " onClick='imgClick(";
tableFunction = "this" ;
tableVar3 = ")'>"+content+"</td>";
//Combine Strings:
colVar = tableVar1 + tableNum + tableVar2 + tableFunction + tableVar3;
//Return result
return colVar;
};
So, yeah it kind of works but It can probably be a lot easier. (any ideas?)

Instead of using strings, consider DOM manipulation.
var rows = document.getElementById("mainTable").rows, cells, fragment = document.createDocumentFragment();
for(var i = 0, len = rows.length; i<len; i++){ //Iterate over each row
cells = rows[i].cells;
for(var j = cells.length-1; j>=0; j--) {
fragment.appendChild(cells[j]); //Remove the cells starting from the end and put them in a document fragment
}
rows[i].appendChild(fragment); //Append the fragment's contents to the current row
}
Demo on jsFiddle

First you should not be using multiple ID's with the same value! You should use classes.
Second of all, the below code works but you will need to change it to suit your application.
If you don't want the contents copied just remove the html() call on each of the cells.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<script type="text/javascript" language="javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<table id="test">
<tr id="row-1"><td class="col-1">col 1</td><td class="col-2">col 2</td><td class="col-3">col 3</td></tr>
<tr id="row-2"><td class="col-1">col 1</td><td class="col-2">col 2</td><td class="col-3">col 3</td></tr>
<tr id="row-3"><td class="col-1">col 1</td><td class="col-2">col 2</td><td class="col-3">col 3</td></tr>
</table>
</body>
<div id="mirror"></div>
<script type="text/javascript">
var table = $('#test');
var OUTPUT = '<table id="test">';
for (var i = 1; i <= $('#test tr').length; i++){
OUTPUT += '<tr id="row-' + i + '">';
OUTPUT += '<td class="col-1">' + $('#row-' + i + " .col-3").html() + '</td>' + "\n";
OUTPUT += '<td class="col-2">' + $('#row-' + i + " .col-2").html() + '</td>' + "\n";
OUTPUT += '<td class="col-3">' + $('#row-' + i + " .col-1").html() + '</td>' + "\n";
OUTPUT += '</tr>';
};
OUTPUT += '</table>';
$('#mirror').html(OUTPUT);
</script>
</html>

Related

Puppeteer - Dynamic get parent element

I checked out this very similar question, but the solution posted to that one isn't quite what I need and I'm not sure how to set it up as I've only been using nodeJS/puppeteer for a couple of weeks now. Puppeteer - get parent element
I'd like to check for an id among the child elements/nodes (td) of a table row (tr), and then select the row that corresponds to the cell containing the specified id, but specifically I'd like to set it up so that I don't have to define the id of the parent node in the puppeteer code in order to select it, as this may change depending on the position of the row in the displayed table.
Right now my puppeteer code is able to select a row with a provided row id such as '#row1', but this code will eventually be set up to do alot of the same things to several table rows/options, so it'd be cleaner overall to check for the innerText of the reportID 2929 or the report name Stephen_Test, and then select whatever table row that cell resides in.
My table is built with this loop:
for (var i = 0; i < arr.length; i++) {
txtTable = txtTable + "<tr id='row" + i + "'>";
txtTable = txtTable + "<td style='width:30%;'>" + arr[i].teamName + "</td>";
txtTable = txtTable + "<td style='display:none; width:10%;'>" + arr[i].reportId + "</td>";
txtTable = txtTable + "<td id='m" + arr[i].reportId + "' style='width:40%;'>" + arr[i].reportName + "</td>";
txtTable = txtTable + "<td style='width:20%;'>" + arr[i].reportAuthor + "</td>";
txtTable = txtTable + "</tr>";
};
How it shows in html:
<table id="myTable">
<tbody>
<tr id="row1">
<td style="width:30%;">Team Name</td>
<td style="display:none; width:10%;">2929</td>
<td id="2929" style="width:40%;">Stephen_Test</td>
<td style="width:20%;">null</td>
</tr>
<tr id="row2">
<td style="width:30%;">Team Name</td>
<td style="display:none; width:10%;">2929</td>
<td id="3131" style="width:40%;">Stephen_Test2</td>
<td style="width:20%;">null</td>
</tr>
<tr id="row3">
<td style="width:30%;">Team Name</td>
<td style="display:none; width:10%;">2929</td>
<td id="3232" style="width:40%;">Stephen_Test3</td>
<td style="width:20%;">null</td>
</tr>
<tr id="row4">
<td style="width:30%;">Team Name</td>
<td style="display:none; width:10%;">2929</td>
<td id="3030" style="width:40%;">Stephen_Test4</td>
<td style="width:20%;">null</td>
</tr>
</tbody>
</table>
My current puppeteer code:
let reportId = await page.$$eval('td', td => td.find(t => t.innerText === "Stephen_Test")?.id);
console.log(reportId);
var number = '1';
await page.click('#row' + number);

Conditional popup text, onmouseover depending of the value in cell of a table. Html, javascript and css

I have a table in html.
I want that when I mouse over a cell, it pop-ups a text. The text popped-up, should depend of the text inside of the cell.
Example of an html table:
City number
Paris 1454
Madrid 1345
Roma 684
If I mouseover a City (Paris), it should pop-up the country (France).
I have seen partial solutions, (
https://www.w3schools.com/howto/howto_js_popup.asp
https://www.w3schools.com/css/css_tooltip.asp), but I don´t know how to solve the conditional part of the pop-up.
Thank you
I think that you need a hover
The <abbr title="World Health Organization">WHO</abbr> was founded in 1948.
https://www.w3schools.com/tags/tag_abbr.asp
There is an easier way to have "hover-popups" in HTML. You can add a title property to set the text shown in the popup:
<td title="France">Paris</td>
You can also set this via JavaScript:
td.title = "France"
I don't know if that is what you're looking for, but if it is, it's easier that way
Supposing a DOM like that :
<table>
<thead>
<tr>
<th>City</th>
<th scope="col">Number</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Paris </th>
<td>1454</td>
</tr>
<tr>
<th scope="row">Madrid</th>
<td>1345</td>
</tr>
<tr>
<th scope="row">Roma</th>
<td>684</td>
</tr>
</tbody>
</table>
Assuming you have a JS code that show the popup on hover.
You can use the data attribute to set the country on each city cell:
<th scope="row" data-country="France">Paris</th>
And patch the JS code to use it:
const elts = document.getElementsByTagName('th');
for (let elt of elts) {
elt.addEventListener("mouseover", (evt) => {
const country = evt.target.getAttribute('data-country');
yourPopupScript(country); // this trigger your popup, and you can write the country into
});
}
Static generated Table:-
var list = [{
city: "Italy",
country: "Rome"
}, {
city: "Belgium",
country: "Brussels"
}];
var statusCol = "";
var table = '<table><tr><th>City</th><th>Country</th></tr>';
var ID = 0;
for (var i = 0; i < list.length; i++) {
var row = "<tr class='staff-row' >";
row += '<td title=' + list[i].city + '>' + list[i].city + '</td>';
row += '<td title=' + list[i].country + '>' + list[i].country + '</td>'
row += "</tr>"
ID++;
table += row;
}
table += '</table>';
$('#DisplayTable').html(table);
$('#DisplayTable').tooltip({
'show': true,
'selector': '.staff-row',
'placement': 'bottom',
'title': function(event) {
var $this = $(this);
var tds = $this.find('td');
return
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href='http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css' />
<script src='http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js'></script>
Static Table:-
<table class="popup">
<tr onclick="myFunction(event)">
<th title="City">City</th>
<th title="Country">Country</th>
</tr>
<tr>
<td title="Delhi">Delhi</td>
<td title="India">India</td>
</tr>
<tr>
<td title="Paris">Paris</td>
<td title="France">France</td>
</tr>
</table><br /> Dynamic Table:-
<div id="DisplayTable"></div>

How to sum values from table column and update when remove/add new row

I'm trying to sum the values of one specific column but honestly I dont know how to it, also I want to refresh that total value when I add or remove some row, what can I do to make this? I'm triying with the anwsers of similar question here on SO but they sum values from all columns and I only want to do that for an specific column! Here is what I have:
function deleteRow(btn) {
var row = btn.parentNode.parentNode;
row.parentNode.removeChild(row);
}
$('#xd').click(function() {
var lines = "";
lines += '<td>3</td>';
lines += '<td>3</td>';
lines += '<td>15</td>';
lines += '<td>Credit</td>';
lines += '<td>1</td>';
lines += '<td>100.00</td>';
lines += '<td><input type="button" value="Delete" onclick="deleteRow(this)"/></td>';
$('#TableBody').append(lines);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="Table">
<thead>
<tr>
<td>ID</td>
<td>Code</td>
<td>Client</td>
<td>Debit/Credit</td>
<td>Quantity</td>
<td>Price</td>
<td>Options</td>
</tr>
</thead>
<tbody id="TableBody">
<tr>
<td>1</td>
<td>1</td>
<td>3</td>
<td>Debit</td>
<td>10</td>
<td>12.00</td>
<td>
<input type="button" value="Delete" onclick="deleteRow(this)" />
</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>12</td>
<td>Debit</td>
<td>5</td>
<td>10.00</td>
<td>
<input type="button" value="Delete" onclick="deleteRow(this)" />
</td>
</tr>
</tbody>
<tfoot id="TableFooter">
<tr>
<td colspan="4">Total</td>
<td>15</td>
<td>170.00</td>
</tr>
</tfoot>
</table>
<input type="button" id="xd" value="add row">
In the above code I added the Total columns (Price, Quantity) manually, I want to update total result when user add/remove a row.
Your approach is a bit brittle for long term use, but as a proof of concept this may help.
The key technique for summing up an array of numbers is to use Array.reduce, which works like this:
var array = [1, 2, 6, 1, 5];
var total = array.reduce(function(total, number) {
return total + number;
}, 0);
document.write('<h1>Total: <code>' + total + '</code></h1>');
Given an array of numbers, iterate over each of them and add number to total, with total starting at 0.
Array.reduce takes two arguments: a function to execute over each item, and a starting value. The iterator function will receive two arguments, in your case the running total and the next number.
See the MDN documentation on Array.reduce for more details.
Some Tips
Break things down into smaller functions whenever possible.
Limit use of global variables, but when you do need them, be clean and consistent about it
Limit storing data on the DOM (I'm violating this slightly, but this is just sketch code)
Try and write code in a way that's reusable
The benefits of this approach are it makes it a bit easier to add new features/change what you built. For example, if we write a generic function getColumnTotal(selector), which would let you specify a jQuery selector for a column's cells (ex: .priceCell), then you can reuse that for other columns like quantity.
I assume you were working towards a grand total cell, that displays the total of all individual orders/rows. To do that, all we'd need to do is calculate the subtotal for each row, add a new column for that, then re-use that getColumnTotal function to sum up all the sub-totals. Voila, grand total.
Note that my code doesn't account for errors, so you may need to handle situations where invalid quantity or price data is input.
var $tableBody = $('#TableBody');
var $totalQuantityCell = $('#totalQuantityCell');
var $totalPriceCell = $('#totalPriceCell');
var $totalGrandCell = $('#grandTotalCell');
// Add a row with random values on "Add Row" button click
$('#xd').click(addRandomRow);
function addRandomRow(event) {
var randomCode = Math.round(Math.random() * 4);
var randomClient = Math.round(Math.random() * 15);
var randomCharge = ( Math.round(Math.random()) ? 'Debit' : 'Credit' );
var randomQuantity = Math.ceil(Math.random() * 5);
var randomPrice = Math.ceil(Math.random() * 100).toFixed(2);
addRow(randomCode, randomClient, randomCharge, randomQuantity, randomPrice);
};
// Add some rows to start
addRandomRow();
addRandomRow();
// Listen for clicks on ".deleteRowButton" within the table
$tableBody.on('click', '.deleteRowButton', function(event) {
deleteRow( $(event.target).data('row') );
updateTotals();
});
// --------------------------
function addRow(code, client, chargeType, quantity, price) {
// Create a new row element
var idNum = ( $tableBody.find('tr').length + 1 );
var rowId = 'row-' + idNum;
var $row = $('<tr id="' + rowId + '"></tr>');
// Add the table cells
$row.append('<td class="idCell">' + idNum + '</td>');
$row.append('<td class="codeCell">' + code + '</td>');
$row.append('<td class="clientCell">' + client + '</td>');
$row.append('<td class="chargeTypeCell">' + chargeType + '</td>');
$row.append('<td class="quantityCell">' + quantity + '</td>');
$row.append('<td class="priceCell">' + price + '</td>');
$row.append('<td class="orderTotalCell">' + getSubtotal(quantity, price) + '</td>');
$row.append('<td><input type="button" value="Delete" class="deleteRowButton" data-row="#' + rowId + '" /></td>');
// Append the row to the table body
$tableBody.append($row);
updateTotals();
}
function deleteRow(rowId) {
$(rowId).remove();
}
function updateTotals() {
var totalQuantity = getColumnTotal('.quantityCell');
var totalPrice = getColumnTotal('.priceCell');
var totalOrder = getColumnTotal('.orderTotalCell');
$totalQuantityCell.text( totalQuantity );
$totalPriceCell.text( toMoney(totalPrice) );
$totalGrandCell.text( toMoney(totalOrder) );
}
/**
A standard function to calaculate the subtotal of a row, this is
where you could apply tax or other data transformations if need be.
*/
function getSubtotal(quantity, price) {
return (quantity * price).toFixed(2);
}
/**
Takes a jQuery selector, finds all matching elements for it, and totals up their contents.
It works by converting the elements list to an Array and then using Array.reduce.
#see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
*/
function getColumnTotal(selector) {
return Array.from( $(selector) ).reduce(sumReducer, 0);
}
/**
The reducer function that adds up a running total. This function parses the innerHTML content
of an element and converts it to a number so math works on it.
*/
function sumReducer(total, cell) {
return total += parseInt(cell.innerHTML, 10);
}
function toMoney(number) {
return '$' + number.toFixed(2);
}
#TableHead td {
border-bottom: 1px #000 solid;
}
.orderTotalCell,
#grandTotalCell,
#totalPriceCell {
text-align: right;
}
#TableFooter tr:first-child td {
border-top: 1px #000 solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="Table">
<thead id="TableHead">
<tr>
<td>ID</td>
<td>Code</td>
<td>Client</td>
<td>Debit/Credit</td>
<td>Quantity</td>
<td>Price</td>
<td>Order Total</td>
<td>Options</td>
</tr>
</thead>
<tbody id="TableBody">
</tbody>
<tfoot id="TableFooter">
<tr>
<td colspan="4">Sub-Total</td>
<td id="totalQuantityCell">–</td>
<td id="totalPriceCell">–</td>
<td id="grandTotalCell">–</td>
</tr>
</tfoot>
</table>
<input type="button" id="xd" value="add row">
wow lots of answers but here is a somewhat of a more object oriented approach.
function row(Id, Code, Client, DebitCredit, Quantity, Price) {
this.Id = Id;
this.Code = Code;
this.Client = Client;
this.DebitCredit = DebitCredit;
this.Quantity = Quantity;
this.Price = Price;
}
function model() {
this.rows = [];
}
var mymodel = new model();
$(document).ready(function() {
mymodel.rows.push(new row(1, 1, 3, 'Debit', 10, 12))
mymodel.rows.push(new row(2, 2, 12, 'Debit', 5, 10))
draw();
$("body").on("click", ".delete", function() {
var id = $(this).data('id');
for (i = 0; i < mymodel.rows.length; i++) {
console.log(mymodel.rows[i].Id);
if (mymodel.rows[i].Id == id) {
mymodel.rows.splice(i, 1);
}
}
draw();
});
$('#add').click(function() {
mymodel.rows.push(new row(
$('#Id').val(),
$('#Code').val(),
$('#Client').val(),
'Debit',
Number($('#Quantity').val()),
Number($('#Price').val())
))
draw();
});
})
function draw() {
$('tbody').empty();
var totalQuantity = 0;
var totalPrice = 0;
$.each(mymodel.rows, function(i, row) {
totalQuantity += row.Quantity;
totalPrice += row.Price;
var myrow = '<tr>'
$.each(row, function(key, value) {
myrow += '<td>' + value + '</td>'
});
myrow += '<td><input type="button" class="btn btn-danger delete" data-id="' + row.Id + '" value="X"/></td>'
myrow += '<tr>'
$('tbody').append(myrow);
});
$('#totalQuantity').text(totalQuantity)
$('#totalPrice').text(totalPrice)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<table class="table table-condensed">
<thead>
<tr>
<td>ID</td>
<td>Code</td>
<td>Client</td>
<td>Debit/Credit</td>
<td>Quantity</td>
<td>Price</td>
<td>Delete</td>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan=7>Total Quantity:
<span id="totalQuantity"></span> Total Price:
<span id="totalPrice"></span>
</td>
</tr>
</tfoot>
</table>
<form class="form-inline">
<div class="form-group">
<label for="id">Id:</label>
<input type="number" class="form-control" id="Id">
</div>
<div class="form-group">
<label for="Code">Code:</label>
<input type="number" class="form-control" id="Code">
</div>
<div class="form-group">
<label for="Client">Client:</label>
<input type="number" class="form-control" id="Client">
</div>
<div class="form-group">
<label for="Quantity">Quantity:</label>
<input type="number" class="form-control" id="Quantity">
</div>
<div class="form-group">
<label for="Price">Price:</label>
<input type="number" class="form-control" id="Price">
</div>
<input type="button" class="btn btn-info" value="add" id="add" />
</form>
You are missing:
<tr> </tr>
Tags when you add a new row. Also, just add a class that will add up "Quantities" and "Prices". Here's a working solution. Hope it helps!
function deleteRow(btn) {
var row = btn.parentNode.parentNode;
row.parentNode.removeChild(row);
sumOfColumns();
}
function sumOfColumns(){
var totalQuantity = 0;
var totalPrice = 0;
$(".someClass").each(function(){
totalQuantity += parseInt($(this).html());
$(".someTotalClass").html(totalQuantity);
});
$(".classPrice").each(function(){
totalPrice += parseInt($(this).html());
$(".someTotalPrice").html(totalPrice);
});
}
$(document).ready(function () {
$('#xd').click(function() {
var lines = "";
lines += '<tr>';
lines += '<td>3</td>';
lines += '<td>3</td>';
lines += '<td>15</td>';
lines += '<td>Credit</td>';
lines += '<td class = "someClass">1</td>';
lines += '<td class = "classPrice">100.00</td>';
lines += '<td><input type="button" value="Delete" onclick="deleteRow(this)"/></td>';
lines += '</tr>';
$('#TableBody').append(lines);
sumOfColumns();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="Table">
<thead>
<tr>
<td>ID</td>
<td>Code</td>
<td>Client</td>
<td>Debit/Credit</td>
<td>Quantity</td>
<td>Price</td>
<td>Options</td>
</tr>
</thead>
<tbody id="TableBody">
<tr>
<td>1</td>
<td>1</td>
<td>3</td>
<td>Debit</td>
<td class = "someClass">10</td>
<td class = "classPrice">12.00</td>
<td>
<input type="button" value="Delete" onclick="deleteRow(this)" />
</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>12</td>
<td>Debit</td>
<td class = "someClass">5</td>
<td class = "classPrice">10.00</td>
<td>
<input type="button" value="Delete" onclick="deleteRow(this)" />
</td>
</tr>
</tbody>
<tfoot id="TableFooter">
<tr>
<td colspan="4">Total</td>
<td class = "someTotalClass">15</td>
<td class = "someTotalPrice"">170.00</td>
</tr>
</tfoot>
</table>
<input type="button" id="xd" value="add row">
You can create a function to calculate total and call it after you add each line and on page load if you have some initial value.
function setTotal()
{
var totalPrice=0;
var totalQty=0;
$('#TableBody').find('tr').each(
function(){
totalQty +=parseFloat($(this).find('td').eq(4).text());
totalPrice +=parseFloat($(this).find('td').eq(5).text());
//console.log(totalPrice);
});
$('#TableFooter').find('tr td').eq(1).text(totalQty);
$('#TableFooter').find('tr td').eq(2).text(totalPrice);
}
$(function(){
setTotal();
})
$('#ID').find('tr') will find all the rows of table with id 'ID'. then you iterate through each tr using each function. Then in each row you find all the td similarly and get to specific td using eq function. eq takes index of the element.
Here is running fiddler : https://jsfiddle.net/8a4umvdr/
There are several flaws within your script, which I will want to walk you through so that you can better understand the process:
Avoid using inline JS. If you want to bind events dynamically, you can use .on() instead. Since the table is present on DOM ready, you can use $('#Table').on(...) to listen to click events on the delete button
Modularise sum computation into a single function. You can create a function, say computeSum(), which will be called every time you modify the table: be it when a table row is added, or a table row is deleted. You can also call this function at runtime, so that you do not have to use server-side languages to precompute the starting sums.
In my example below, I will fetch the text node in the 5th and 6th columns (which is 4 and 5 by zero-based index), and convert them to float by appending + in front of them
I have also used the .toFixed(2) function when printing the sums, so that its nicely showing two decimal places.
Fix your HTML injection. Remember that for <td> elements to be valid, they have to be nested in <tr>. You seem to have left that out by accident.
So here is a completely functional example of your code snippet:
$(function() {
// Function to compute sum
var computeSum = function() {
// Get the total quantity and price by column index
var quantity = 0,
price = 0;
// Iterate through each row
$('#TableBody tr').each(function() {
quantity += +$(this).find('td').eq(4).text();
price += (+$(this).find('td').eq(5).text() * +$(this).find('td').eq(4).text());
});
// Update sum
$('#TableFooter td.total.quantity').text(quantity.toFixed(2));
$('#TableFooter td.total.price').text(price.toFixed(2));
};
// Use on to bind click event handlers to input buttons with delete-row action
$('#Table').on('click', 'input[type="button"][data-action="delete-row"]', function(e) {
e.preventDefault();
// Delete row
$(this).closest('tr').remove();
// Recompute sum
computeSum();
});
$('#xd').click(function() {
// Remember to wrap your cells within <tr>
var lines = "<tr>";
lines += '<td>3</td>';
lines += '<td>3</td>';
lines += '<td>15</td>';
lines += '<td>Credit</td>';
lines += '<td>1</td>';
lines += '<td>100.00</td>';
lines += '<td><input type="button" value="Delete" data-action="delete-row" /></td>';
lines += "</tr>";
// Append new table row
$('#TableBody').append(lines);
// Recompute sum
computeSum();
});
// Compute sum when starting up
computeSum();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="Table">
<thead>
<tr>
<td>ID</td>
<td>Code</td>
<td>Client</td>
<td>Debit/Credit</td>
<td>Quantity</td>
<td>Price</td>
<td>Options</td>
</tr>
</thead>
<tbody id="TableBody">
<tr>
<td>1</td>
<td>1</td>
<td>3</td>
<td>Debit</td>
<td>10</td>
<td>12.00</td>
<td>
<input type="button" value="Delete" data-action="delete-row" />
</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>12</td>
<td>Debit</td>
<td>5</td>
<td>10.00</td>
<td>
<input type="button" value="Delete" data-action="delete-row" />
</td>
</tr>
</tbody>
<tfoot id="TableFooter">
<tr>
<td colspan="4">Total</td>
<td class="total quantity">15</td>
<td class="total price">170.00</td>
</tr>
</tfoot>
</table>
<input type="button" id="xd" value="add row">
Further improvements
There are some minor improvements that you can make to my code above, but they are considered non-mission critical and hence I did not include them in my original answer.
Extensibility. If you want to compute additional columns, it would be difficult to rewrite the same lines over and over again. Instead, I recommend you store the sums in an object instead.
Value fetching. We are retrieving values based on the text node in the column. Sometimes, you do not want that—say you want to include currencies, or other texts in the quantity and/or price column. In that sense, you might want to store such data in a custom HTML5 data- attribute instead.
$(function() {
// Function to compute sum
var computeSum = function() {
// Get the total quantity and price by column index
var sums = { quantity: 0, price: 0 };
// Iterate through each table cell
$('#TableBody tr').each(function() {
sums.quantity += +$(this).find('td').eq(4).data('value');
sums.price += (+$(this).find('td').eq(4).data('value')*+$(this).find('td').eq(5).data('value'));
});
// Update sum
$.each(sums, function(key, value) {
$('#TableFooter td.total.'+key).text(value.toFixed(2));
});
};
// Use on to bind click event handlers to input buttons with delete-row action
$('#Table').on('click', 'input[type="button"][data-action="delete-row"]', function(e) {
e.preventDefault();
// Delete row
$(this).closest('tr').remove();
// Recompute sum
computeSum();
});
$('#xd').click(function() {
// Remember to wrap your cells within <tr>
var lines = "<tr>";
lines += '<td>3</td>';
lines += '<td>3</td>';
lines += '<td>15</td>';
lines += '<td>Credit</td>';
lines += '<td class="quantity" data-value="1">1</td>';
lines += '<td class="price" data-value="100.00">100.00</td>';
lines += '<td><input type="button" value="Delete" data-action="delete-row" /></td>';
lines += "</tr>";
// Append new table row
$('#TableBody').append(lines);
// Recompute sum
computeSum();
});
// Compute sum when starting up
computeSum();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="Table">
<thead>
<tr>
<td>ID</td>
<td>Code</td>
<td>Client</td>
<td>Debit/Credit</td>
<td>Quantity</td>
<td>Price</td>
<td>Options</td>
</tr>
</thead>
<tbody id="TableBody">
<tr>
<td>1</td>
<td>1</td>
<td>3</td>
<td>Debit</td>
<td class="quantity" data-value="10">10</td>
<td class="price" data-value="12.00">12.00</td>
<td>
<input type="button" value="Delete" data-action="delete-row" />
</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>12</td>
<td>Debit</td>
<td class="quantity" data-value="5">5</td>
<td class="price" data-value="10.00">10.00</td>
<td>
<input type="button" value="Delete" data-action="delete-row" />
</td>
</tr>
</tbody>
<tfoot id="TableFooter">
<tr>
<td colspan="4">Total</td>
<td class="total quantity">15</td>
<td class="total price">170.00</td>
</tr>
</tfoot>
</table>
<input type="button" id="xd" value="add row">

How to populate html table using javascript without using div?

I am trying to fill html table(my table got 3 columns) with data from json using javascript but the data never get filled using div method! could any tell me how to fill content of table rows using without using div ?
for(i in json)
{
var div = "<tr id=\""+i+"\">\n" +
"<td>"+i+"</td>\n" +
"<td><img src=\""+ json[i].thumb +"\" height=\"42\" width=\"42\"></td>\n" +
"<td>\n" +
"" + json[i].title + "<br> \n" +
"<br></td></tr>\n\n";
$("#myDiv").append(div);
}
Table to be filled:
<table id="list" cellspacing="0" border="1">
<tr>
<th>Item#</th>
<th>Logo</th>
<th>Description</th>
</tr>
<div id='myDiv'></div>
</table>
This Your new table:
<table id="list" cellspacing="0" border="1">
<thead>
<tr>
<th>Item#</th>
<th>Logo</th>
<th>Description</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
And code:
var html = '';
for(var i in json)
{
html += '<tr id="'+i+'">';
html += '<td>'+i+'</td>';
html += '<td><img src="'+json[i].thumb+'" height="42" width="42"></td>';
html += "<td>";
html += "" + json[i].title + "<br/><br/>";
html += '</td>';
html += '</tr>';
}
$('#list > tbody').html(html);

Using jQuery to select table group columns

This is a part of my table columns I want to select. Here's the code:
<tr>
<th colspan="2">
</th>
</tr>
<tr>
<td></td><td></td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
Now i want to be able to select the whole big column. Tried many methods but none work so far. Any help would be appreciated.
well it will be
$('th[colspan="2"],td[colspan="2"]')
well if you know which column it is , ie 3rd column then it will be like
$("table td:nth-child(3),table th:nth-child(3)")
another answer could be
in case you can change the markup
<tr>
<th colspan="2" class="bigcol">
</th>
</tr>
<tr>
<td class="bigcol"></td><td></td>
</tr>
<tr>
<td colspan="2" class="bigcol"></td>
</tr>
$(".bigcol").hide()
This bit more complex jquery code does the trick. It is looking for a th and all the td with a specific colspan (so it's not perfect, because you can't have 2 big tds ina a row). It also hides the required amount of tds with 1 colspan. http://jsfiddle.net/balintbako/xz6W4/
var colw = 2;
var position = $("th[colspan=" + colw + "]").prevAll().length;
$("th[colspan=" + colw + "]").hide();
$("tr").each(function () {
if ($(this).find("th").length !== 0) {
return;
}
if ($(this).find("td[colspan=" + colw + "]").length !== 0) {
$(this).find("td[colspan=" + colw + "]").hide();
return;
}
for (var i = 1; i <= colw; i++) {
$(this).find("td:nth-child(" + (position + i) + ")").hide();
}
});

Categories

Resources