Hide/show row in a dynamic table using jscript - javascript

I have a json data through ajax call and displayed it in a dynamic html table based on the length of data object obtained from ajax using jscript. Now i need to hide or show data in the table on the basis of a drop down option selected, for example if the user clicks on an item "less than 100" from the drop down, only the related rows which has values less than 100 should be displayed and other rows should be hidden.
$.ajax({
url: "http://finance.google.com/finance/info?client=ig&q=" +CompName+ "",
type: "get",
dataType: "jsonp",
success:function(data, textstatus, jqXHR){
drawTable(data);
}
});
function drawTable(data) {
for (var i = 0; i < data.length; i++) {
drawRow(data[i]);
}
}
function drawRow(rowData){
var row= $("<tr />")
$("#table").append(row);
row.append($("<td>" + rowData.t + "</td>"));
row.append($("<td>" + rowData.l_cur + "</td>"));
row.append($("<td>" + rowData.c + "</td>"));
row.append($("<td>" + rowData.lt + "</td>"));
}
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Select the value
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li>Below 100</li>
<li>100-300</li>
<li>300-600</li>
<li>600-1000</li>
<li>above 1000</li>
</ul>
</div>
<div class="table-responsive">
<table id="table" class="table table-striped">
<tr>
<th>Name</th>
<th>Price</th>
<th>Change</th>
<th>Date</th>
</tr>
</table>
</div>
Here's the html AND javascript snippet.

In order to make it work correctly, apart from the text for li, you should also make use of data-attributes which would give you the range to lookup.
Following is an example which shows how you can make use of it.
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Select the value
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li>Below 100</li>
<li>100-300</li>
</ul>
</div>
<div class="table-responsive">
<table id="table" class="table table-striped">
<tr>
<th>Name</th>
<th>Price</th>
<th>Change</th>
<th>Date</th>
</tr>
<tr>
<td>ABC</td>
<td>99</td>
<td>+10</td>
<td>12/12/2014</td>
</tr>
<tr>
<td>EFG</td>
<td>79</td>
<td>+10</td>
<td>12/12/2014</td>
</tr>
<tr>
<td>HIJ</td>
<td>104</td>
<td>+20</td>
<td>12/12/2014</td>
</tr>
</table>
</div>
<script>
$('li').on("click",function()
{
var minRange = $(this).find('a').data("min"); // get the data-min attribute to get the min range
var maxRange = $(this).find('a').data("max"); // get the data-min attribute to get the max range
$("#table tr").each(function() // iterate through each tr inside the table
{
var data = $(this).find('td').eq(1).text(); // get the price td column value from each tr
if(!isNaN(data) && data != "") // skip th tags inside tr and any other td missing the price column value
{
$(this).hide(); // hide all tr by default
if(data >= minRange && data <= maxRange) // check if the price td column value falls within the range
$(this).show(); // show the current tr
}
});
});
</script>
Example : http://jsfiddle.net/RxguB/205/

We listen for changes on the select event. We then get the criteria we are using to filter records by getting the value of the selected item. We create multiple filters based on the value. We're going to toggle between showing and hiding them.
$("select").on("change", function() {
var criteria = ($(":selected").prop("value"));
var filterOne = $("td:nth-child(2)").filter(function() {
return Number($(this).html()) >= 100;
});
var filterTwo = $("td:nth-child(2)").filter(function() {
return Number($(this).html()) < 100;
});
if (criteria == "Less than 100") {
filterOne.parent().hide();
filterTwo.parent().show();
}
else {
filterTwo.parent().hide();
filterOne.parent().show();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option>Less than 100</option>
<option>More than 100</option>
</select>
<table>
<tr>
<th>Name</th>
<th>Price</th>
<th>Change</th>
<th>Date</th>
</tr>
<tr>
<td>Stock 1</td>
<td>72</td>
<td>+5</td>
<td>3/4/2012</td>
</tr>
<tr>
<td>Stock 2</td>
<td>102</td>
<td>+8</td>
<td>5/7/2013</td>
</tr>
<tr>
<td>Stock 3</td>
<td>90</td>
<td>-3</td>
<td>3/16/2013
</tr>
</table>

Related

Storing count of table rows in a JS variable

I have some old code I am trying to poke through. This table is loaded via a Controller action returning a model, based off of a button click somewhere else in the page.
How can I find the number of rows in the table in a JS variable? I am terrible with JS. I have tried a few things and nothing has worked. Below is my code and also what I have tried to do to store the num of rows.
Table:
<hr />
<div class="row" id="ReceiptsMainDiv">
<div class="col-md-12" style="overflow-y:scroll">
<table class="table table-striped table-hover table-bordered" id="terminalReceipts">
<thead>
<tr>
<th>Terminal ID</th>
<th>Local Transaction Time</th>
<th>Amount</th>
<th>Receipt</th>
<td class="hidden"></td>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TransactionsTests)
{
<tr id="#String.Concat("rowIndex", Model.TransactionsTests.IndexOf(item))">
<td>#item.TerminalID</td>
<td>#item.TransactionTime</td>
<td>#item.Amount</td>
#*<td>#Html.ActionLink("View Receipt", "ViewReceipt", new { id = item.Id }, new { #class = "btn btn-primary btn-sm" }) <br /></td>*#
<td class="transactionID hidden">#item.Id</td>
<td>
#if (item.ReceiptData == null)
{
<button class="btn btn-sm btn-primary viewReceipt" disabled>View Receipt</button>
}
else
{
<button class="btn btn-sm btn-primary viewReceipt" data-rowindex="#String.Concat("rowIndex", Model.TransactionsTests.IndexOf(item))">View Receipt</button>
}
</td>
</tr>
}
</tbody>
</table>
</div>
Here is what I have tried to do in JS:
var rowId = "#" + $(this).data("rowindex");
var row = $(rowId);
console.log(rowId);
console.log(row);
Results from the console.log don't appear to be accurate. Anything helps. Thanks
Probably you want the number of rows of your table.
// javascript
var rowsInTable = document.getElementById("terminalReceipts").getElementsByTagName("tr").length;
//jquery
var rowsInTable2 = $("#customers").children('tbody').children('tr').length;
//if you need to do something with the rows:
var rows = $("#customers").children('tbody').children('tr');
rows.each(function( index ) {
console.log( index + ": " + $( this ).text() );
});
you can also do that using jquery like this
var totalRowCount = $("#terminalReceipts tr").length; //this will give +1 row
var rowCount = $("#terminalReceipts td").closest("tr").length; //this will give actual row

Set OnClick attribute of an input with TR data-key and TD cell value when select a table row

i am driving nuts on this.
I have a table and assign a class (selected) when I select the row.
Now, I have an input within a form and this is suppose to redirect to another page when OnClick, also it should parse 2 variables.
This 2 variables I take from the row selected.
GetID is the TD data-key attribute and GetName is the second column cell value.
My OnClick should look like this:
onclick="location.href='test.phtml?GetID=1&GetName=Name1'"
My Intention is:
Click on table row, assign class 'selected' and put data-key attribute of the TR element which has the class 'selected' (as value1) and the TD cell value (as value2) in my OnClick string.
The click thing works, but i cant get the string to work.
I have a fiddle here: fiddle
can you check this approch :
https://jsfiddle.net/Kanzari/3sw01c9r/5/
it's a customized fork of your original code, base changes :
$("#myTable tr").click(function(AddGroupIDandName) {
$(this).addClass('selected').siblings().removeClass("selected");
$('.mybtn').attr('OnClick','./mysite.html?GetID='+$(this).attr('data-key')+'&GetName='+$(this).find('td:last-child').text());
});
You forgot the following lines in your $("#myTable tbody tr").on('click'
var str = "location.href='test.phtml?GetID='" + $(this).data('key') +
"'&GetName='" + $(this).find('td:last').text();
$(':input[value="Next"]').attr('onclickLocation', str);
$('#myTable').on('click', '.selected', function(event) {
if ($(this).hasClass('bg-info')) {
$(this).removeClass('bg-info');
} else {
$(this).addClass('bg-info').siblings().removeClass('bg-info');
}
});
$("#myTable tbody tr").on('click', function(AddGroupIDandName) {
$(this).addClass('selected').siblings().removeClass("selected");
var str = "location.href='test.phtml?GetID='" + $(this).data('key') + "'&GetName='" + $(this).find('td:last').text();
$(':input[value="Next"]').attr('onclickLocation', str);
console.log('onclick is: ' + str);
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.1.1.min.js" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<div class="container-fluid">
<table class="table table-sm table-hover" id="myTable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr class="selected" data-key="1">
<td>1</td>
<td>Name1</td>
</tr>
<tr class="selected" data-key="2">
<td>2</td>
<td>Name2</td>
</tr>
<tr class="selected" data-key="3">
<td>3</td>
<td>Name3</td>
</tr>
</tbody>
</table>
</div>
<div class="container-fluid">
<form><input class="btn btn-sm btn-secondary" onclick="location.href='test.phtml?GetID=1&GetName=Name1'" type="button" value="Next" ></form>
</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 copy the contents of one row in a table to another table and add the identical ones

var Sell_Button = document.getElementById('sellbtn'),
secondTable = document.getElementById("secondTableBody");
Sell_Button.addEventListener('click', function() {
var Row = secondTable.insertRow();
for (var c = 0; c < 2; c += 1) {
Row.insertCell(c);
}
Row.cells[0].innerHTML = this.parentNode.parentNode.cells[0].innerHTML;
Row.cells[2].innerHTML = this.parentNode.parentNode.cells[1].innerHTML;
//checks to see if the secondTable has a row containing the same name
for (var f = 0; f < secondTable.rows.length; f += 1) {
//adds only the sold amount if the second table has a row with the same name
//error
if (secondTable.rows[f].cells[0].innerText === this.parentNode.parentNode.cells[0].innerText) {
secondTable.rows[f].cells[1].innerHTML = +this.parentNode.parentNode.cells[2].innerHTML;
//deletes an extra row that is added at the bottom
if (secondTable.rows.length > 1) {
secondTable.deleteRow(secondTable.rows.length - 1);
}
//if nothing matched then a new row is added
} else {
secondTable.insertRow();
Row.cells[0].innerHTML = this.parentNode.parentNode.cells[0].innerHTML;
Row.cells[1].innerHTML = this.parentNode.parentNode.cells[2].innerHTML;
}
}
}
}
<html>
<body>
<div id="firstTableDiv">
<table border="1" id="firstTable">
<thead>
<th>Item</th>
<th>Stock</th>
<th colspan="1">Sold</th>
</thead>
<tbody id="firstTableBody">
<tr>
<td>Apples</td>
<td>300</td>
<td>200</td>
<td>
<button id="sellbtn">Sell</button>
</td>
</tr>
<tr>
<td>Apples</td>
<td>300</td>
<td>100</td>
<td>
<button id="sellbtn">Sell</button>
</td>
</tr>
<tr>
<td>Oranges</td>
<td>400</td>
<td>300</td>
<td>
<button id="sellbtn">Sell</button>
</td>
</tr>
</tbody>
</table>
</div>
</br>
<div id="secondTableDiv">
Sold
<table border="1" id="secondTable">
<thead>
<th>Item</th>
<th>Sold</th>
</thead>
<tbody id="secondTableBody">
</tbody>
</table>
</div>
</body>
</html>
Ok, this example isn't exactly what i'm working on but it's very similar. The only difference is that in mine the rows and buttons are dynamically added by the user and he inserts the details. What I want is that when i press on the button of each row (sell) the details (Item and Sold only) are copied into a row in the second table and checks if the same item exists in this second table if so then it adds the amount of sold of both items in one row. For instance I press on the first row button the Apples it copies the listed above details to the second table in a row and then when i click on the button of the second row (Apples also) it only adds the sold amount up and doesn't add a second apples row because an apples row already exists in the second table but when i click on the oranges button it makes a new row because the oranges row doesn't exist. So how do I do this in JavaScript? i hope i was thorough and made any sense. I have no idea why the code isn't working here but i hope you get the point. This code works perfectly just as i want it to until for some reason i get this error: Cannot read property 'innerText' of undefined when i press the buttons approx. 6-7 times targeting the if statement where i commented error.
This sets a click handler to all buttons. If the row doesn't exist in the second table it's created. It sets a data-type referring to the item. When somebody clicks the sell button again and there is a row containing the data-type the row is updated instead of created. All in plain JavaScript.
var Sell_Button = document.querySelectorAll('.sellbtn'),
secondTable = document.getElementById("secondTableBody");
Array.prototype.slice.call(Sell_Button).forEach(function(element){
element.addEventListener('click', function(e) {
//since the button is an element without children use e.
var clickedElement = e.target;
var parentRow = clickedElement.parentNode.parentNode;
//check if second table has a row with data-type
var rowWithData = secondTable.querySelector("[data-type='"+parentRow.cells[0].childNodes[0].nodeValue+"']");
if (rowWithData)
{
rowWithData.cells[1].innerHTML = parseInt(rowWithData.cells[1].childNodes[0].nodeValue) + parseInt(parentRow.cells[2].childNodes[0].nodeValue);
}
else
{
var Row = secondTable.insertRow();
Row.setAttribute("data-type", parentRow.cells[0].childNodes[0].nodeValue);
for (var c = 0; c < 2; c += 1) {
Row.insertCell(c);
}
Row.cells[0].innerHTML = parentRow.cells[0].childNodes[0].nodeValue;
Row.cells[1].innerHTML = parentRow.cells[2].childNodes[0].nodeValue;
}
});
});
<html>
<body>
<div id="firstTableDiv">
<table border="1" id="firstTable">
<thead>
<th>Item</th>
<th>Stock</th>
<th colspan="1">Sold</th>
</thead>
<tbody id="firstTableBody">
<tr>
<td>Apples</td>
<td>300</td>
<td>200</td>
<td>
<button class="sellbtn">Sell</button>
</td>
</tr>
<tr>
<td>Apples</td>
<td>300</td>
<td>100</td>
<td>
<button class="sellbtn">Sell</button>
</td>
</tr>
<tr>
<td>Oranges</td>
<td>400</td>
<td>300</td>
<td>
<button class="sellbtn">Sell</button>
</td>
</tr>
</tbody>
</table>
</div>
</br>
<div id="secondTableDiv">
Sold
<table border="1" id="secondTable">
<thead>
<th>Item</th>
<th>Sold</th>
</thead>
<tbody id="secondTableBody">
</tbody>
</table>
</div>
</body>
</html>
Do you mean something like:
$(document).on("click", "#firstTable tr button", function(b) {
b = $(this).closest("tr");
var d = $.trim(b.find("td:first").text());
b = parseFloat($.trim(b.find("td:nth-child(3)").text()));
var a = $("#secondTable"),
c = a.find("tr").filter(function(a) {
return $.trim($(this).find("td:first").text()) == d
});
c.length ? (a = c.find("td:nth-child(2)"), c = parseFloat($.trim(a.text())), a.text(b + c)) : (a = $("<tr />").appendTo(a), $("<td />", {
text: d
}).appendTo(a), $("<td />", {
text: b
}).appendTo(a))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="firstTableDiv">
<table border="1" id="firstTable">
<thead>
<tr>
<th>Item</th>
<th>Stock</th>
<th colspan="1">Sold</th>
</tr>
</thead>
<tbody id="firstTableBody">
<tr>
<td>Apples</td>
<td>300</td>
<td>200</td>
<td><button>Sell</button></td>
</tr>
<tr>
<td>Apples</td>
<td>300</td>
<td>100</td>
<td><button>Sell</button></td>
</tr>
<tr>
<td>Oranges</td>
<td>400</td>
<td>300</td>
<td><button>Sell</button></td>
</tr>
</tbody>
</table>
</div>
<br />
<div id="secondTableDiv">
Sold
<table border="1" id="secondTable">
<thead>
<tr>
<th>Item</th>
<th>Sold</th>
</tr>
</thead>
<tbody id="secondTableBody"></tbody>
</table>
</div>

How to find empty table column, including `th` and inject data into it

Updated Fiddle Example:
How would you find an empty table column,including th in the fiddle so that when you click on a button it'll inject data into that column only. For example, when you click on "X" it'll add data to the first empty column,"G" will add data to the second empty....When the table is full, start from the second child column (because the first column is some sort of title column) and replace old data in that column.
Just a guess:
columnTh = $("table th");
columnIndex = columnTh.index() + 1;
columnIndex.each(function(){
if ($(this).html() == '' && $('table tr td:nth-child(' + columnIndex + ')').html() == ''){
// add data
}
But how can I check if the whole table is full so that the button will add data to the first column again?
HTML:
<div class="area">
<select>
<option>Choose</option>
<option>R</option>
<option>T</option>
</select>
<div class="show">
</div>
</div>
<div class="area">
<select>
<option>Choose</option>
<option>X</option>
<option>G</option>
</select>
<div class="show">
</div>
</div>
<table>
<thead>
<tr>
<th>Placeholder</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Age</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Name</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Race</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Nationality</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Education</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Language</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
JS Code
$(function (){
$('.area').each(function(){
var area = $(this),
selectbox = area.find('select'),
show = area.find('.show'),
dialog_open = $(this).find(".dialog_open");
selectbox.change(function(){
selectbox = $(this).find('option:selected').text();
show.html('<button class="dialog_open">'+selectbox+'</button>')
});
var foo = function() {
var dialog_open_text = $(this).find(".dialog_open").text();
$('table td').html(dialog_open_text); // ****Need help in this part*****
};
show.one( "click",dialog_open, foo );
});
});
Here is how to check that the table is full:
var allCells = $('table').find('th,td').length;
var fullCells = $('table').find('th,td').filter(function() {
return $(this).text() != '';
}).length;
if( allCells === fullCells ) { // if true table is full, not full otherwise
//do something table is full
} else {
//table is not full
}
If the first select indicates the column # you're targeting and the second select indicates the content to put in the cells of the column, then you may use the following logic inside the function foo:
var colN = $('select').first().val(),
colCont = $('select').last().val(),
allColumns = $('table').find('th:eq(' + (colN - 1) + '),td:eq(' + (colN - 1) + ')').length,
fullColumns = $('table').find('th:eq(' + (colN - 1) + '),td:eq(' + (colN - 1) + ')').filter(function() { return $(this).text() != ''; }).length;
Then you can check to see if the targeted column is full or not:
if( allColumns === fullColumns ) {
//all cells in target column full
} else {
//not all cells in target column are full
}
You can empty everything but the first column this way:
$('table').find('th,td').not(':first-child').empty();
And here's how to fill a column:
$('td').filter(':nth-child(' + colN + ')').html(dialog_open_text);

Categories

Resources