Count number of columns in a table row - javascript

I have a table similar to:
<table id="table1">
<tr>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
</tr>
<tr>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
</tr>
<table>
I want to count the number of td element in a row. I am trying:
document.getElementById('').cells.length;
document.getElementById('').length;
document.getElementById('').getElementsByTagName('td').length;
It did not show actual result.

document.getElementById('table1').rows[0].cells.length
cells is not a property of a table, rows are. Cells is a property of a row though

You could do
alert(document.getElementById('table1').rows[0].cells.length)
fiddle here http://jsfiddle.net/TEZ73/

Why not use reduce so that we can take colspan into account? :)
function getColumns(table) {
var cellsArray = [];
var cells = table.rows[0].cells;
// Cast the cells to an array
// (there are *cooler* ways of doing this, but this is the fastest by far)
// Taken from https://stackoverflow.com/a/15144269/6424295
for(var i=-1, l=cells.length; ++i!==l; cellsArray[i]=cells[i]);
return cellsArray.reduce(
(cols, cell) =>
// Check if the cell is visible and add it / ignore it
(cell.offsetParent !== null) ? cols += cell.colSpan : cols,
0
);
}

Count all td in table1:
console.log(
table1.querySelectorAll("td").length
)
<table id="table1">
<tr>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
</tr>
<tr>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
</tr>
<table>
Count all td into each tr of table1.
table1.querySelectorAll("tr").forEach(function(e){
console.log( e.querySelectorAll("td").length )
})
<table id="table1">
<tr>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
</tr>
<tr>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
</tr>
<table>

It's a bad idea to count the td elements to get the number of columns in your table, because td elements can span multiple columns with colspan.
Here's a simple solution using jquery:
var length = 0;
$("tr:first").find("td,th").each(function(){
var colspan = $(this).attr("colspan");
if(typeof colspan !== "undefined" && colspan > 0){
length += parseInt(colspan);
}else{
length += 1;
}
});
$("div").html("number of columns: "+length);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>single</td>
<td colspan="2">double</td>
<td>single</td>
<td>single</td>
</tr>
</table>
<div></div>
For a plain Javascript solution, see Emilio's answer.

First off, when you call getElementById, you need to provide an id. o_O
The only item in your dom with an id is the table element. If you can, you could add ids (make sure they are unique) to your tr elements.
Alternatively, you can use getElementsByTagName('tr') to get a list of tr elements in your document, and then get the number of tds.
here is a fiddle that console logs the results...

If the colspan or rowspan is all set to 1, counting the children tds will give the correct answer. However, if there are spans, we cannot count the number of columns exactly, even by the maximum number of tds of the rows. Consider the following example:
var mytable = document.getElementById('table')
for (var i=0; i < mytable.rows.length; ++i) {
document.write(mytable.rows[i].cells.length + "<br>");
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
padding: 3px;
}
<table id="table">
<thead>
<tr>
<th colspan="2">Header</th>
<th rowspan="2">Hi</th>
</tr>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2">hello</td>
<td>world</td>
</tr>
<tr>
<td>hello</td>
<td colspan="2">again</td>
</tr>
</tbody>
</table>

Here is a terse script taking into account colspan.
numCols will be 0 if the table has no rows, or no columns, and it will be equal to the number of columns regardless of whether some of the cells span multiple rows or columns, as long as the table markup is valid and there are no rows shorter or longer than the number of columns in the table.
const table = document.querySelector('table')
const numCols = table.rows[0]
? [...table.rows[0].cells]
.reduce((numCols, cell) => numCols + cell.colSpan , 0)
: 0

<table id="table1">
<tr>
<td colspan=4><input type="text" value="" /></td>
</tr>
<tr>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
<td><input type="text" value="" /></td>
</tr>
<table>
<script>
var row=document.getElementById('table1').rows.length;
for(i=0;i<row;i++){
console.log('Row '+parseFloat(i+1)+' : '+document.getElementById('table1').rows[i].cells.length +' column');
}
</script>
Result:
Row 1 : 1 column
Row 2 : 4 column

$('#table1').find(input).length

Related

Copying TD value to dynamically created input inside a TD

I have a table with dynamically generated td's that contain text inputs and I need to get the value from the first td in the row and insert into one of the inputs depending on what I select in a <select>. This is trigger by a button.
So far I'm able to get the the value I need with first-child and from my select I have the value of the option same as the class of the inputs.
$("#t_a").click(function() {
var selected = $('select[name=t_r]').val();
$("table tr").each(function() {
var s = $(this).find('td:first-child').html();
$(this).find('.' + selected).attr("value", s);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="t_r" name="t_r" style="width:200px;">
<option value="1234">Option 1234</option>
<option value="1235">Option 1235</option>
<option value="1236">Option 1236</option>
</select>
<input type="button" name="t_a" id="t_a" value="Apply" />
<table>
<tr>
<td>123</td>
<td><input type="text" id="a_1234" class="1234" value=""></td>
<td><input type="text" id="a_1235" class="1235" value=""></td>
<td><input type="text" id="a_1236" class="1236" value=""></td>
</tr>
<tr>
<td>321</td>
<td><input type="text" id="b_1234" class="1234" value=""></td>
<td><input type="text" id="b_1235" class="1235" value=""></td>
<td><input type="text" id="b_1236" class="1236" value=""></td>
</tr>
<tr>
<td>456</td>
<td><input type="text" id="c_1234" class="1234" value=""></td>
<td><input type="text" id="c_1235" class="1235" value=""></td>
<td><input type="text" id="c_1236" class="1236" value=""></td>
</tr>
</table>
With the help of monkawitz and user7290573 I was able to solve my problem by using val() instead of attr().
Thank you Tim Lewis for the guidance.

Get all input values from table excluding first column

I want to alert the input value of each row except the first column.
Here is my code.
<table id="table">
<tr>
<td><input type="text" size="5" value="name"/></td>
<td><input type="text" size="5" value="number"/></td>
<td><input type="text" size="5" value="class"/></td>
</tr>
<tr>
<td><input type="text" size="5" value="bbbbb"/></td>
<td><input type="text" size="5" value="1"/></td>
<td><input type="text" size="5" value="2"/></td>
</tr>
<tr>
<td><input type="text" size="5" value="cccc"/></td>
<td><input type="text" size="5" value="5"/></td>
<td><input type="text" size="5" value="2"/></td>
</tr>
<tr>
<td><input type="text" size="5" value="ddddd"/></td>
<td><input type="text" size="5" value="1"/></td>
<td><input type="text" size="5" value="2"/></td>
</tr>
$(document).ready(function() {
$("#table tr:gt(0) td:gt(0) ").each(function()
{
a=$(this).find('input[type="text"]').val();
alert(a);
});
});
While running this code all value alerted except "bbbb". (ie,ccccc ,dddd alerted.). I only need each rows second one column onwords.
fiddle: https://jsfiddle.net/k1tfo5kb/
This should work:
https://jsfiddle.net/23jcejbm/
$(document).ready(function() {
var $cells = $("#table tr td").not(':first-child'),
$inputs = $cells.find('input[type="text"]');
$.each($inputs, function(){
var value = this.value;
alert(value);
});
});
Here you go: https://jsfiddle.net/pukw0uLz/1/
I changed alert to console.log, much less aggressive. Make sure to open you web console!

Using the same jQuery in multiple operations

I have a small question and I hope someone can help me with it :D
I’m trying to create a product table, in which a user just add the quantity of a product and the jquery makes the multiplication to its value and gives the result
I already made this, and it works well:
<script>
$(document).ready(function(){
$('#quantity_1').keyup(function(){
var price_1 = $("#price_1").val();
var quantity_1 = $("#quantity_1").val();
quantity_1 = quantity_1.replace(/[^0-9]+/g, '');
$("#quantity_1").val(quantity_1);
var total_1 = price_1 * quantity_1;
$( "#total_1" ).val( total_1.toFixed(2) );
});
});
</script>
<table border="1" cellpadding="5px" cellspacing="0" >
<tr>
<td>Product</td>
<td>Price</td>
<td>Quantity</td>
<td>Total</td>
</tr>
<tr>
<td>Product Name</td>
<td><input type="hidden" name="product[1][price]" id="price_1" value="10.00" />10.00</td>
<td><input type="text" name="product[1][quantity]" id="quantity_1" /></td>
<td><input type="text" name="product[1][total]" id="total_1" value="0" /></td>
</tr>
</table>
Working demo here:
http://jsfiddle.net/EnterateNorte/9kswL0gf/
But I would like to be able to add more than one line, like so:
<table border="1" cellpadding="5px" cellspacing="0" >
<tr>
<td>Product</td>
<td>Price</td>
<td>Quantity</td>
<td>Total</td>
</tr>
<tr>
<td>Name 1</td>
<td><input type="hidden" name="product[1][price]" id="price_1" value="10.00" />10.00</td>
<td><input type="text" name="product[1][quantity]" id="quantity_1" /></td>
<td><input type="text" name="product[1][total]" id="total_1" value="0" /></td>
</tr>
<tr>
<td>Name 5</td>
<td><input type="hidden" name="product[5][price]" id="price_5" value="10.00" />23.00</td>
<td><input type="text" name="product[5][quantity]" id="quantity_5" /></td>
<td><input type="text" name="product[5][total]" id="total_5" value="0" /></td>
</tr>
<tr>
<td>Name 3</td>
<td><input type="hidden" name="product[3][price]" id="price_3" value="130.00" />10.00</td>
<td><input type="text" name="product[3][quantity]" id="quantity_3" /></td>
<td><input type="text" name="product[3][total]" id="total_3" value="0" /></td>
</tr>
<tr>
<td>Name 4</td>
<td><input type="hidden" name="product[4][price]" id="price_4" value="12.00" />10.00</td>
<td><input type="text" name="product[4][quantity]" id="quantity_4" /></td>
<td><input type="text" name="product[4][total]" id="total_4" value="0" /></td>
</tr>
</table>
And if it isn’t to much trouble, I would be awesome if it would SUM all the totals and show a gran total at the end of the table :)
Use:
$(document).ready(function(){
$('[name*=quantity]').keyup(function(){
var price = $(this).parent().prev().find('input').val();
var quantity = $(this).val();
var total = price * quantity;
$(this).parent().next().find('input').val( total.toFixed(2) );
});});
Working Demo
Update: For showing Grand Total
var sum = 0;
//iterate through each textboxes and add the values
$('[name*=total]').each(function() {
//add only if the value is number
if(!isNaN(this.value) && this.value.length!=0) {
sum += parseInt(this.value);
}
});
Working Demo
What you can do is to find the elements using their relative position instead of hard coded ids
$(document).ready(function () {
$('input[id^="quantity_"]').keyup(function () {
var $tr = $(this).closest('tr');
var price = $tr.find('input[id^="price_"]').val();
var quantity = this.value;
var total = (price * quantity) || 0;
$tr.find('input[id^="total_"]').val(total.toFixed(2));
});
});
Demo: Fiddle
I've updated your code in Fiddle. You need to change in your markup a bit.
<tr>
<td>Product Name</td>
<td><input type="hidden" class="price" ... />10</td>
<td><input type="text" class="quantity" ... /></td>
<td><input type="text" class="total" ... /></td>
</tr>
$(document).ready(function(){
$('.quantity').keyup(function(){
var parent = $(this).closest("tr");
var price = $(".price", parent).val();
var quantity = $(".quantity", parent).val();
var total = price * quantity;
$(".total", parent).val(total.toFixed(2));
});
});
I would recommend you to use common class
HTML:
<tr>
<td>Name 5</td>
<td>
<input type="hidden" class="price" value="10.00" />10.00</td>
<td>
<input type="text" class="quantity" />
</td>
<td>
<input type="text" class="total" value="0" />
</td>
</tr>
<tr>
<td>Name 3</td>
<td>
<input type="hidden" class="price" value="130.00" />130.00</td>
<td>
<input type="text" class="quantity" />
</td>
<td>
<input type="text" class="total" value="0" />
</td>
</tr>
Script:
$('.quantity').keyup(function () {
var tr = $(this).closest('tr');
var price = tr.find('.price').val();
var quantity = $(this).val();
var total = price * quantity;
tr.find('.total').val(total.toFixed(2));
});
DEMO
Modify your table:
<table border="1" cellpadding="5px" cellspacing="0" id='table' >
<!-- your rows with inputs -->
<tr>
<td>
<input id='totalSum' value='0' type='text' />
</td>
</tr>
</table>
Make all your 'total' inputs readonly by adding 'readonly' attribute.
js code:
$(document).ready(function(){
$('[name*=quantity]').keyup(function(){
var total = 0;
$('#table tr').each(function(i,item){
var price = parseFloat($(item).find('[name*=price]').val().replace(',','.'));
var quantity = parseInt($(item).find('[name*=quantity]').val());
if(!isNaN(price) && !isNan(quantity)){
total += price*quantity;
}
});
$("#totalSum").val(total.toFixed(2));
});
});

Multiplication of inputs & sum of inputs using JavaScript

I am trying to write an application where we have a HTML table with 4 rows (for simplicity's sake) & 3 columns.
The first 2 columns are inputs & the 3rd will display the result of multiplying these inputs (for each row), the I would like the 3rd column in the final row to calculate the sum of the results in column 3.
I am thinking I need to write a JavaScript function to iterate over the entire table but what I am unsure of is how to label the inputs - does each one need to be different?
<table width="80%" border="0">
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Result</th>
</tr>
<tr>
<td><input id="???" type="text" /></td>
<td><input id="???" type="text" onchange="calculate()" /></td>
<td><input id="result" /></td>
</tr>
<tr>
<td><input id="???" type="text" /></td>
<td><input id="???" type="text" onchange="calculate()" /></td>
<td><input id="result" /></td>
</tr>
<tr>
<td><input id="???" type="text" /></td>
<td><input id="???" type="text" onchange="calculate()" /></td>
<td><input id="result" /></td>
</tr>
<tr>
<td><input id="???" type="text" /></td>
<td><input id="???" type="text" onchange="calculate()" /></td>
<td><input id="result" /></td>
</tr>
</table>
no need to set id. With jquery I would try something like:
function calculate() {
var tr = $(this).closest("tr");
var inputs = tr.find("input");
var input1 = $(inputs[0]);
var input2 = $(inputs[1]);
var resultInput = $(inputs[2]);
resultInput.val(+input1.val()+input2.val()); // +input1.val() is cast input1 to number
}
First of all, give your ID name unique.
You can use parseInt() to calculate the sum or multiplication
var a = parseInt(document.getElementById("id-one").value);
var b = parseInt(document.getElementById("id-two").value);
var sum = a+b;
var mul = a*b;
Don't use inline HTML for javascript. Instead create a selector like:
$('table input').change(function() { }
You can use $(this) inside the function to manipulate the current input changed.

Get values from table of text fields javascript

I have a form which actually is a table of text fields. The html looks like this:
<form>
<table id="table">
<tr>
<th>Player</th>
<th>Number</th>
<th>Con.per.day</th>
<th>P.100.kg</th>
<th>P.day</th>
<th>I.month</th>
</tr>
<tr>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td>Result</td>
</tr>
<tr>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td>Result</td>
</tr>
<tr>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td>Result</td>
</tr>
</table>
<input type="button" name="rank" value="Rank" onClick="rankPlayers(this.form)"/>
</form>
I would like to iterate all fields and get the values at the press of the button, but I get undefined returned in the console log. I don't want to use IDs for each field as I want to do some column operations (add, multiply). My script for the first column looks like this:
function rankPlayers(){
var table=document.getElementById("table");
for(var i=1; i<table.rows.length;i++){
console.log(table.rows[i].cells[0].value);
}
}
Any tips? Thanks
You need to select the input from the cell:
// ------------------------------------v
console.log(table.rows[i].cells[0].firstChild.value);
If you could have siblings (even whitespace) around the inputs, then you can use the .children collection to target the correct element.
// ------------------------------------v
console.log(table.rows[i].cells[0].children[0].value);
You can change your loop to:
var table=document.getElementsByTagName("td");
for(var i=1; i<table.length;i++){
console.log(table[i].firstChild.value);
}
This gets all td elements, loops them, and checks the firstChild value

Categories

Resources