Im trying to achieve the following: Add the numbers from two table columns, perform the following operation on them ($price2 - $price1)/$price1 * 100 and then add the result to the top of the table in a special div.
<div id="mydiv">Percentage Gain/Loss</div>
<table id="mytable">
<tbody>
<tr>
<th>price1</th><th>price2</th>
</tr>
<tr>
<td>10</td><td>30</td>
</tr>
<tr>
<td>5</td><td>10</td>
</tr>
<tr>
<td>15</td><td>5</td>
</tr>
</tbody>
</table>
So the desired operation would populate #mydiv with the results of ((30+10+5) - (10+5+15))/(10+5+15)*100 What would be the best way to achieve this? Also, if price2 should happen to be lower than price1 the output should be negative (I guess something like -Math.abs would work).
You can use getElementsByTagName to get the html elements that contain your prices and then do the computations.
var sum1 = 0, sum2 = 0;
var table = document.getElementById('mytable');
var rows = table.getElementsByTagName('tr'); // restrict the search to one table
for (var i=0, length = rows.length; i<length; i++) {
var tds = rows[i].getElementsByTagName('td');
if (tds.length >= 1) {
var val1 = +tds[0].innerHTML; // unary plus converts the value to Number
var val2 = +tds[1].innerHTML;
sum1 += val1;
sum2 += val2;
}
}
document.getElementById('mydiv').innerHTML = (sum2 - sum1) / sum1 * 100 + '';
Working JsFiddle: http://jsbin.com/IqARONE/1/edit
I would just put classes to each td, something like:
<tr>
<th>price1</th><th>price2</th>
</tr>
<tr>
<td class="price1">10</td><td class="price2">30</td>
</tr>
<tr>
<td class="price1">5</td><td class="price2">10</td>
</tr>
<tr>
<td class="price1">15</td><td class="price2">5</td>
</tr>
Then, in your JavaScript, use the getElementsByClassName method to get an array of price1 tags and a second array of price2 tags, then use the parseInt method to get the actual value inside each tag and compute the wanted value. You then put this value using something like $('#mydiv').html(total). Hope this helps.
Related
Good afternoon, below is the code in it I am getting fields from my table. The 0 field contains a checkbox, how can I find out if it is checked or not(true or false)? You need to change this line: console.log (td.item (f));
var table = document.getElementsByClassName("table-sm");
for (var i = 0; i < table.length; i++) {
var tr = table.item(i).getElementsByTagName("tr");
for (var j = 0; j < tr.length; j++) {
var trr = tr.item(j);
var td = tr.item(j).getElementsByTagName("td");
for (var f = 0; f < td.length; f++) {
if (f === 0) console.log(td.item(f));
console.log(td.item(f).innerText);
}
}
}
Firstly, please learn about JavaScript Table API is much better than just making complex for-loops.
Next time please add full code (HTML/JavaScript) so people can help you.
Now let's fix your code.
Suppose we have this table
<table class="table-sm" id="myTable">
<thead>
<tr>
<th>Checkbox</th>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" name="selected[]" checked /></td>
<td>1</td>
<td>Mohammed</td>
</tr>
<tr>
<td><input type="checkbox" name="selected[]" /></td>
<td>2</td>
<td>Ali</td>
</tr>
</tbody>
</table>
and we want to get the first item of each rows, and check whether the checkbox is checked or not.
We can do it easly using JS Table APIs.
Get the table by it's ID.
var table = document.getElementById("myTable");
Get the table rows
I use Array.from() to convert HTMLCollection to normal array, so I can use Array APIs (Like .forEach).
var rows = Array.from(table.rows);
Loop into table rows, and get cells of each row.
rows.map((row) => {
var cells = Array.from(row.cells);
// TODO add logic here.
});
Get the firstChild of first cell.
rows.map((row) => {
var cells = Array.from(row.cells);
if (Array.isArray(cells) && cells.length > 0) {
var firstChild = cells[0].firstChild;
console.log(firstChild.checked);
}
});
Live Example
I have multiple tables in a dOM tree and I want to calculate the count of cells in every table.
code:
function tree() {
var table = document.getElementsByTagName('table');
for (var p = 0, tr; tr= table[p]; p++) {
for (var i =0, row; row = tr.rows[i]; i++) {
console.log(row.cells.length)
}
}
}
console.log(tree())
html:
<table>
<tr>
<td>First</td>
<td>row</td>
</tr>
<tr>
<td>and</td>
<td>second</td>
</tr>
</table>
<table>
<tr>
<td>First</td>
<td>row</td>
</tr>
</table>
In the first there are 4 cells and second there are 2 cells I want to print out the cells with largest count in a table. Hence the o/p will be:
4
my above js code, returns the total length of all the cells in a table. How can I traverse through the tables in a tree and find the largest count of cells?
thx!
Use querySelectorAll() to simplify this.
The below code will output 4 as in your OP. It's a simple modification to get the table with the most cells, which I suspect is what you meant (it's unclear).
// Get your list of all tables in the document.
const tables = document.querySelectorAll('table');
// Map list of tables to list of number of <td> elements.
const lengths =
Array.from(tables)
.map(table => table.querySelectorAll('td').length)
// Get the max of the list of lengths and log to console.
const max = Math.max(...lengths);
console.log(max);
<table>
<tr>
<td>First</td>
<td>row</td>
</tr>
<tr>
<td>and</td>
<td>second</td>
</tr>
</table>
<table>
<tr>
<td>First</td>
<td>row</td>
</tr>
</table>
You can try this to if you want :
const maxTdTable = ()=>{
var object;
var maxCol = 0;
$('table').each(function(element){
$(element).each(function(elem){
max = $(elem).childNodes.length;
maxCol = max>=maxCol ? max : maxCol ;
});
});
return {element : object,max : maxCol};
}
I'm a beginner with code,
I'm trying to run on this table and get the text from each .winner class and push it to an Array, so instead of getting:
["aa","aa","dd"]
I'm getting
["aaaadd","aaaadd","aaaadd"]
$(document).ready(function(){
var arr = [];
var winner = $('.winner').text() ;
for ( i = 0; i < $('table').length ; i++ ) {
arr.push(winner);
}
console.log(arr);
});
HTML:
<table>
<tr>
<td>#</td>
<td class="winner">aa</td>
<td>bb</td>
<td>cc</td>
<td>dd</td>
</tr>
</table>
<table>
<tr>
<td>#</td>
<td class="winner">aa</td>
<td>bb</td>
<td>cc</td>
<td>dd</td>
</tr>
</table>
<table>
<tr>
<td>#</td>
<td class="winner">dd</td>
<td>cc</td>
<td>bb</td>
<td>aa</td>
</tr>
</table>
I guess something is wrong with my for loop
var arr = [];
$('table .winner').each(function () {
arr.push($(this).text());
})
Example
or version without class .winner
$('table').each(function () {
arr.push($(this).find('tr').eq(0).find('td').eq(1).text());
});
Example
$('table .winner') - returns 3 td's with class .winner
$(this).text() - get text from current element.
In your example $('.winner').text() returns text "aaaadd", then you get $('table').length (will be 3) and three times push the same text to arr
The sentence
var winner = $('.winner')
will give you an array of objects, so you need to loop each of them and call text() method for each one.
With this:
var winner = $('.winner').text();
You are getting a combined texts from all the td elements marked as winner (see docs here).
Then, for each table, to push this value to the array:
for ( i = 0; i < $('table').length ; i++ ) {
arr.push(winner);
}
This is actually not necessary.
What you want is probably:
var winners = $('.winner');
for (var i = 0; i < winners.length(); ++i) {
arr.push(winners.eq(i).text());
}
Here is the following table code and I want to store all TD values into an Array.
<tr class="item-row">
<td class="item-name"><textarea>Item</textarea></td>
<td class="description"><textarea>Item</textarea></td>
<td><textarea class="cost">$0.00</textarea></td>
<td><textarea class="qty">0</textarea></td>
<td><span class="price">$0.00</span></td>
</tr>
<tr class="item-row">
<td class="item-name"><textarea>Item</textarea></td>
<td class="description"><textarea>Item</textarea></td>
<td><textarea class="cost">$0.00</textarea></td>
<td><textarea class="qty">0</textarea></td>
<td><span class="price">$0.00</span></td>
</tr>
For this I have written this following code:
function checkForm() {
var table = document.getElementsByClassName("item-row");
var arr = new Array();
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
arr.push(row.cells[j].val);
}
}
}
But this gives me no output...I am new to javascript so may be am missing something in big time.
Your code is almost right, the thing is that rows property work for tables not for trs so you have to take a table instead of the tr directly.
The other thing is that getElementsByClassName returns an array of your elements so you have to use [index] to get your element.
The last thing is that to get the value for the cell you can't use val, so use firstChild to get the child and value to get the value as in the code, or better as #pawel suggest directly cell.textarea :)
Try with this code:
function checkForm() {
var table = document.getElementsByClassName("yourTable")[0];
var arr = new Array();
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
arr.push(row.cells[j].firstChild.value);
}
}
console.log(arr);
}
<table class="yourTable">
<tr class="item-row">
<td class="item-name"><textarea>Item</textarea></td>
<td class="description"><textarea>Item</textarea></td>
<td><textarea class="cost">$0.00</textarea></td>
<td><textarea class="qty">0</textarea></td>
<td><span class="price">$0.00</span></td>
</tr>
<tr class="item-row">
<td class="item-name"><textarea>Item</textarea></td>
<td class="description"><textarea>Item</textarea></td>
<td><textarea class="cost">$0.00</textarea></td>
<td><textarea class="qty">0</textarea></td>
<td><span class="price">$0.00</span></td>
</tr>
</table>
<input type="button" onclick="checkForm();" value="check form"/>
Hope this helps,
What you have is a good first effort for being new to JavaScript, but, yes, there are quite a few items that need updating. :)
Here is what you would need to do what you are trying to do:
function checkForm() {
var rows = document.getElementsByClassName("item-row");
var arr = new Array();
for (i = 0; i < rows.length; i++) {
var cols = rows[i].getElementsByTagName("td");
for (j = 0; j < cols.length; j++) {
arr.push(cols[j].textContent);
}
}
}
You need to cycle through each row . . . the easiest way to do this by going from i = 0 to i < rows.length in your for loop.
Once you have a row, you need to gather all of the columns in the row, by finding all of the <td> elements (var cols = rows[i].getElementsByTagName("td"););
Then, you loop through each of those, just like you did with the rows (j = 0 to j < cols.length
Finally, to get the text contained in each td, you use the textContent property . . . values (i.e., the value property) are used only for <input> elements
There were a couple of syntax errors in there, too (you used , instead of ;, when building your for loop and you used val instead of value, when attempting to get the td content), but that was all that I saw.
Edit: I'm also assuming that you just did not paste your <table> tags in when you added your HTML, but, if you didn't your <tr> tags must be inside a <table.
Edit 2: My solution also skips the looking at the tags inside the <td> elements, since they are not standard (4 contain <textarea> inputs and the 5th a <span>). If you want to go down one more level of detail, you could use .value on the textareas and (again) .textContent on the <span>. By using .textContent one level up, you are ignoring all HTML tags insid the <td> tags and returning only the text.
Hi I have html structure with table. I want to sort td according to their value. I trying it but cant find the logic to make it happen. My function is
<head>
<script type="text/javascript">
function sorting(){
var sortvalue= document.getElementsByTagName('td');
for(i=0; i<sortvalue.length;i++){
var val= sortvalue[i].value
}
}
</script>
</head>
<body>
<table width="500" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>5</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>1</td>
</tr>
</table>
click to sort
</body>
If you plan to do more than just organize those numbers: those saying you should use a plugin are correct. It'd take more effort than it's worth to try to make your own table sorter.
If all you want to do is sort those numbers (small to large):
function sorting() {
td = document.getElementsByTagName("td");
sorted = [];
for (x = 0; x < td.length; x++)
sorted[x] = Number(td[x].innerHTML);
sorted.sort();
for (x = 0; x < sorted.length; x++)
td[x].innerHTML = sorted[x];
}
Largest to smallest:
function sorting() {
td = document.getElementsByTagName("td");
sorted = [];
for (x = 0; x < td.length; x++)
sorted[x] = Number(td[x].innerHTML);
sorted.sort().reverse();
for (x = 0; x < sorted.length; x++)
td[x].innerHTML = sorted[x];
}
Assuming that you're putting the script under your link, or adding it on domready:
function sorting(){
var tbl = document.getElementsByTagName('table')[0];
var store = [];
for(var i=0, len=tbl.rows.length;i<len; i++){
var row = tbl.rows[i];
var sortnr = parseFloat(row.cells[0].textContent || row.cells[0].innerText);
if(!isNaN(sortnr)) store.push([sortnr, row]);
}
store.sort(function(x,y){
return x[0] - y[0];
});
for(var i=0, len=store.length; i<len; i++){
tbl.appendChild(store[i][1]);
}
store = null;
}
link here: http://jsfiddle.net/UMjDb/
For your example you can make an array of the cell data from the node list and sort that array, and then replace the cells data with the sorted data. Simpler than moving elements.
<head>
<script type= "text/javascript">
function sorting(){
var T= [], tds= document.getElementsByTagName('td');
for(var i= 0;i<tds.length;i++){
T.push(tds[i].firstChild.data);
}
T.sort(function(a, b){
return a-b
});
for(var i= 0;i<tds.length;i++){
tds[i].replaceChild(document.createTextNode(T[i]), tds[i].firstChild);
}
}
</script>
</head>
<body>
<table width= "500" border= "0" cellspacing= "0" cellpadding= "0">
<tr>
<td>5</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>1</td>
</tr>
</table>
click to sort
</body>
i giving a jquery solution, hope this post helps you.
var tdData = Array();
$(document).ready(function(){
$('td').each(function(i){
tdData [i] = $(this).text();
});
});
function sorting(){
var sortedData = tdData.sort();
$('td').each(function(i){
$(this).text(sortedData[i]);
} );
}
complete solution: link
step 1: find all td's
step 2: fetch their values
step 3: sort them on their values
step 4: put them back into their parent in the correct order. This can simply be done with an $(parent).html("").append(sortedNodes) (if you use jQuery that is).
As #FelixKling points out below, the .html("") is not strictly necessary other than for code clarity since "If you have nodes that already exist in the tree, then .append will remove them first from their current location and add them to the new parent"
You need to re-organise the table.
The simplest approach would be to use a plugin like this one for jQuery
You need to modify the DOM, they would be different way to do that, like grabbing all the data, removing all the rows and adding them back in the right order.
It could be improved better using detach and reattaching.