Counting values from td's in jQuery - javascript

I have a problem with jQuery script. I'm trying to make a simple counting loop, for each tr. I got a table like below, and I want to select the second td, multiply it by two and add to the third td and display the result in the fourth td.
https://codepen.io/adeowsky/pen/YEgVKG
I'm trying to make it with the for each loop like below ->
<script>
(function($) {
$('.sp-league-table tbody tr').each( function() {
var pct = this.find('.data-pct').text();
console.log(pct);
//var pct = $('').hasClass('data-pct').text();
//console.log(pct);
var winy = $('.data-w').text();
var losy = $('.data-l').text();
/*var pkt = (winy*2) + (losy*2);
$('.data-pct').text(pkt);*/
});
})( jQuery );
</script>
But it doesn't work for me, where is the reason?

You are selecting all the elements with the class, not the one in the current row.
var tr = $(this);
var pCell = tr.find(".data-pct")
var wCell = tr.find('.data-w')
var lCell = tr.find('.data-l')

There are a couple of problems
Your table does not have the required class
you're not targeting the specific row's cells
You should explicitly parse the string values to integers
you've commented out the bit that does the calculation:
$(function(){
$('.sp-league-table tbody tr').each( function() {
var pct = $('.data-pct',this).text();
var winy = parseInt($('.data-w',this).text(),10);
var losy =parseInt($('.data-l',this).text(),10);
var pkt = (winy*2) + (losy*2);
$('.data-pct',this).text(pkt);
});
})
Updated: https://codepen.io/anon/pen/NwJjaO
Live example:
$(function(){
$('.sp-league-table tbody tr').each( function() {
var pct = $('.data-pct',this).text();
var winy = parseInt($('.data-w',this).text(),10);
var losy =parseInt($('.data-l',this).text(),10);
var pkt = (winy*2) + (losy*2);
$('.data-pct',this).text(pkt);
});
})
table, tr, td, th {
border: 1px solid #000;
border-collapse: collapse;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="sp-league-table">
<thead>
<tr>
<th>Name</th>
<th>W</th>
<th>L</th>
<th>PCT</th>
</thead>
<tr>
<td>Name 1</td>
<td class="data-w">12</td>
<td class="data-l">0</td>
<td class="data-pct">x</td>
</tr>
<tr>
<td>Name 2</td>
<td class="data-w">9</td>
<td class="data-l">3</td>
<td class="data-pct">x</td>
</tr>
</table>
<table class="sp-league-table">
<thead>
<tr>
<th>Name</th>
<th>W</th>
<th>L</th>
<th>PCT</th>
</thead>
<tr>
<td>Name 1</td>
<td class="data-w">12</td>
<td class="data-l">0</td>
<td class="data-pct">24</td>
</tr>
<tr>
<td>Name 2</td>
<td class="data-w">6</td>
<td class="data-l">5</td>
<td class="data-pct">17</td>
</tr>
</table>

Related

How to create a JavaScript loop that adds DOM properties to attributes?

I have a table with cells that are not contentEditable. However, using a JavaScript loop or function, I would like to make them so.
I understand that it is very simple to do this manually for each cell, and this would probably be easier for a table with only a few cells, but I would like to quicken this process with a loop/function for the table could become much larger, and the time spent manually setting each cell to be contentEditable would be tedious.
Below is a quick example that displays a table calculator, un-editable at present. But using a loop or function, I'd like to make every cell in the right column set to .contentEditable = true in the DOM. I imagine that the parameters would look something like (var i = 0; l != rows.length; i < l; i+2), but I'm struggling with what the statements following the argument would have to be for the loop/function to work. Any help would be much appreciated!
function myFunction() {
var jack2 = document.getElementById("jack").innerText;
var john2 = document.getElementById("john").innerText;
var joe2 = document.getElementById("joe").innerText;
var total2 = (parseInt(jack2) || 0) + (parseInt(john2) || 0) + (parseInt(joe2) || 0);
document.getElementById("total").innerHTML = total2;
}
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid gray;
border-collapse: collapse;
font-family: Arial;
margin: 5px;
}
<table>
<caption>Weight Calculator</caption>
<tr class="cell">
<th>Person</th>
<th>Weight (kg)</th>
</tr>
<tr class="cell">
<td>Jack</td>
<td id="jack" oninput="myFunction()">1</td>
</tr>
<tr class="cell">
<td>John</td>
<td id="john" oninput="myFunction()">2</td>
</tr>
<tr class="cell">
<td>Joe</td>
<td id="joe" oninput="myFunction()">3</td>
</tr>
<tr class="cell">
<td>Total</td>
<td id="total"></td>
</tr>
</table>
Get all cell in the tabel that have a left neigbour (the header is not effected because there are th and not td). Add to each of these cells your attribute.
Edited: For getting the totalsum add an eventlistener on each td that calls the calc-function if the content changes.
function myFunction() {
let weightCells = document.querySelectorAll("table tr:not(:last-child) td ~ td");
weightCells.forEach(td => {
td.setAttribute('contentEditable', true);
td.addEventListener ("change", calcSum());
});
}
function calcSum() {
let sum=0;
let weightCells = document.querySelectorAll("table tr td ~ td");
let count = weightCells.length-1;
for (i=0; i<count; i++) {
sum += parseInt(weightCells[i].innerHTML) || 0;
}
weightCells[count].innerHTML = sum;
}
myFunction();
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid gray;
border-collapse: collapse;
font-family: Arial;
margin: 5px;
}
<table>
<caption>Weight Calculator</caption>
<tr class="cell">
<th>Person</th>
<th>Weight (kg)</th>
</tr>
<tr class="cell">
<td>Jack</td>
<td id="jack" oninput="myFunction()">1</td>
</tr>
<tr class="cell">
<td>John</td>
<td id="john" oninput="myFunction()">2</td>
</tr>
<tr class="cell">
<td>Joe</td>
<td id="joe" oninput="myFunction()">3</td>
</tr>
<tr class="cell">
<td>Total</td>
<td id="total"></td>
</tr>
</table>
You can select the whole table, then use querySelectorAll to get all rows then for each rows change the contenteditable for the second td like this
codepen
let table = document.getElementById('table')
let rows = table.querySelectorAll('tr')
rows.forEach(row => {
let tds = row.querySelectorAll('td')
// all the cells of the row
if (tds.length > 0) { // if it is not the header
tds[1].contentEditable = true
// change the contenteditable
}
})
(you need to add an id to your table in case you have more than one table)
<table id="table">
...
</table>

How to loop through a table and get the td elements to follow a condition

I just want make so it the tr hides when the td does not follow the requirements, tried with jQuery and JavaScript, don't know what's wrong.
$(document).ready(function(){
$("td").each(function() {
var id = $(this).attr("price_search");
if (id > value4 && id < value5) {
$(this).hide;
}
else {
$(this).hide;
}
});
});
You can do this.
Hope this will help you.
$(document).ready(function() {
var value4 = 2;
var value5 = 4;
$("td").each(function() {
var id = $(this).attr("price_search");
if (id > value4 && id < value5) {
$(this).hide();
} else {
$(this).show();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td price_search="3">10</td>
<td price_search="2">20</td>
<td price_search="3">30</td>
</tr>
</table>
I am going to go out on a limb here and make broad assumptions on content not in the question.
Your .hide; is invalid syntax
You are missing value for two variables value4 and value4 which frankly are not well named variables at all. I will make an assumption that those are better named and that they come from somewhere during the page rendering.
I make an assumption that you have something you want to filter/hide by those upper/lower price points.
I make the assumption the attribute might contain values that need to be parsed (not a number as they are)
var lowerPricePoint = .45;
var upperPricePoint = 5.25;
$(function() {
$("td").filter('[price_search]').each(function() {
// parse out a price from perhaps formatted values
let price = Number.parseFloat($(this).attr("price_search").replace(/\$|,/g, ''));
// toggle visibility of the row
$(this).closest('tr').toggle(price > lowerPricePoint && price < upperPricePoint);
});
});
td {
border: solid black 1px;
padding: 0.4em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<table>
<tr>
<td>Wear it</td>
<td price_search="123.13">Shoes</td>
</tr>
<tr>
<td>Drive it</td>
<td price_search="$23,123.13">Car</td>
</tr>
<tr>
<td>Drink it</td>
<td price_search="3.13">Beet Juice</td>
</tr>
<tr>
<td>Eat it</td>
<td price_search="12.13">Can of expensive corn</td>
</tr>
<tr>
<td>Cheap</td>
<td price_search="35">Radish</td>
</tr>
<tr>
<td>Use it</td>
<td price_search="1.45">Paper towel</td>
</tr>
<tr>
<td>Plain</td>
<td price_search="$1.87">Butter</td>
</tr>
<tr>
<td>Herb</td>
<td price_search="$2.45">Butter</td>
</tr>
<tr>
<td>Cheap</td>
<td price_search="15">Gum</td>
</tr>
</table>

How can I get only one column value from html table?

I have a html table that shows a list of users ID, Name and E-mail. When my user clicks in any row, I get the id number of that row and send to my backend. So, I did this:
//Making the table
var trs = document.getElementsByTagName('tr');
for (var i = 0; i < trs.length; i++) {
trs[i].onclick = clickHandler;
}
Function that handles the click:
function clickHandler(event) {
var numb = this.innerText.match(/\d/g);
numb = numb.join("");
window.location.replace("chooseParticipant.php?id="+numb);
}
Table Example:
<div id="table">
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>E-mail</th>
</tr>
</thead>
<tbody>
<td>7</td>
<td>Test User</td>
<td>testuser123#example.com</td>
</tbody>
</table>
</div>
What happens then? If an user have numbers in their e-mail, the "numb" variable gets these numbers too. I don't know how to filter only the id number. Did someone have any ideas?
You could assign a class to you tag.
Something like below:-
<td class="id">7</td>
And in the javascript code you could fetch all the elements with class "id".
And then perform your click handler on each one.
var trs = document.getElementsByClassName('id');
I hope this helps.
Try this code snippet which use data-* attribute
document.addEventListener('DOMContentLoaded', function(e) {
var trs = document.querySelectorAll('#table tbody tr');
var repeater = Array.prototype.slice;
repeater.call(trs).forEach(function(tr) {
tr.addEventListener('click', function(e) {
var data = tr.querySelector('td[data-id]').dataset;
console.log('id=', data.id);
});
});
});
tbody {
cursor: pointer;
}
<div id="table">
<table border="1" cellspacing="0" cellpadding="3">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>E-mail</th>
</tr>
</thead>
<tbody>
<tr>
<td data-id="7">7</td>
<td>Test User 1</td>
<td>testuser1231#gmail.com</td>
</tr>
<tr>
<td data-id="8">8</td>
<td>Test User 2</td>
<td>testuser1232#gmail.com</td>
</tr>
<tr>
<td data-id="9">9</td>
<td>Test User 3</td>
<td>testuser1233#gmail.com</td>
</tr>
</tbody>
</table>
</div>

How to find the corresponding th to a given td?

Basically the same question as How can I get the corresponding table header (th) from a table cell (td)? but not jQuery specific.
From a given <td> is there an easy way to find the corresponding <th>?
<table width="100%" id="stock">
<tr>
<th>Name</th>
<th>Type</th>
<th>Quantity</th>
<th>Options</th>
</tr>
<tr>
<td>foo</td>
<td id="target">bar</td>
<td>-1</td>
<td>...</td>
</tr>
I'd like something doing this:
document.getElementById('target').correspondingTH // would return HTMLObject <th>Type</th>
An ideal answer might contain both a jQuery way to do it and a vanilla one but I'm personally looking for a vanilla one.
Pure JavaScript's answer.
var index = Array.prototype.indexOf.call(your_td.parentNode.children, your_td)
var corresponding_th = document.querySelector('#your_table_id th:nth-child(' + (index+1) + ')')
As posted here in the more jQuery specifc question: https://stackoverflow.com/a/37312707/1524913
HTML table model gives easier solution. jquery in this case is more sophisticated. I tested following table:
<table style="width:100%" id="stock">
<tbody>
<tr>
<td>foo</td>
<td id="target">bar</td>
<td>-1</td>
<td>...</td>
</tr>
<tr>
<td>foo</td>
<td id="target">bar</td>
<td>-1</td>
<td>...</td>
</tr>
</tbody>
<tr>
<td>foo</td>
<td id="target">bar</td>
<td colspan="2">-1</td>
<!--<td>...</td>-->
</tr>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Quantity</th>
<th>Options</th>
</tr>
</thead>
</table>
Script without jquery is simple and straightforward.
window.onload = function () {
var tbl = document.getElementById('stock');
var tds = document.getElementsByTagName('td');
for (var i = 0, td; td = tds[i]; ++i) {
td.onclick = function () {
var tr = this.parentNode;
console.log(tbl.rows[0].cells[this.cellIndex].innerHTML);
}
}
}
jquery also is useful.
$(document).ready(function () {
$('#stock td').click(function () {
console.log($(this).parents('table').find('tr:first-child').children('th:nth-child(' + (this.cellIndex + 1) + ')').html());
});
});
<thead> can be placed at the top, at the bottom, and between rows. thead inside tbody is obvious error but browser fixes it. Scripts work in any case.
I think you need to step through the TH colSpans to exactly match the TD
Try
function getHeadCell(td) {
var index = Array.prototype.indexOf.call(td.parentNode.children, td);
var table = td;
while (table && table.tagName != 'TABLE') table = table.parentNode;
var cx = 0;
for (var c = 0; cx <= index; c++) cx += table.rows[0].cells[c].colSpan;
return table.rows[0].cells[c - 1];
}
See https://jsfiddle.net/Abeeee/upt75s2x/34/ for a working example

Adding a row that is writable in HTML

I have made a table that can add a row. But I want the row to be writable. When the user clicks the addRow a new row will appear and the user can input a text on it. Can someone help me to do it? Thankyou so much.
the code is in the jsFiddle.
jsFiddle
Here is the solution in jsFiddle
http://jsfiddle.net/96oqxz9z/
All you need to add is a simple line:
$('#tbl1').append("<TR><TD></TD><TD><input type=\"text\"></TD></TR>");
Try this
Check here
function addRow() {
$('#addmore').append('<tr><td><input type="text" value="1"></td><td><input type="text" value="2"></td></tr><tr><td> </td></tr>')
};
$(document).on('click', '#add', function() {
var row = '<tr><td><input type="text" /></td></tr>';
$(this).closest('table').append(row);
})
td {
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td id="add">add row </td>
</tr>
</table>
try using this:
function addRow() {
"use strict";
var table = document.getElementById("tbl1");
var row=table.insertRow(table.rows.length);
console.log(row);
var td1=row.insertCell(0);
var td11 = document.createElement("span");
td1.appendChild(td11);
var td2=row.insertCell(1);;
var td22 = document.createElement("input");
td22.type = "text";
td2.appendChild(td22);
td11.innerHTML = document.getElementById("a").innerHTML;
td2.value = document.getElementById("b").innerHTML;
row.appendChild(td1);
row.appendChild(td2);
table.children[0].appendChild(row);
}
<input type="button" onclick="addRow()" value="Add Row"/>
<TABLE id="tbl1">
<TR>
<TH></TH>
<TH id="a">Principal Name</TH>
<TH id="b">Principal Titles</TH>
</TR>
<TR>
<TD></TD>
<TD>Director Of Manager</TD>
</TR>
<TR>
<TD></TD>
<TD>President</TD>
</TR>
<TR>
<TD></TD>
<TD>Treasurer</TD>
</TR>
</TABLE>

Categories

Resources