javascript get a total for a table column NaN error - javascript

I am getting a NaN error. the code was copied from a fiddle which works perfectly. Here is the code.
<tbody>
<tr>
<td><input type="checkbox" name="payment_id[]" id="payment_id_" value="6" class="box" checked="checked" /></td>
<td>2015-08-26 20:43:50 UTC</td>
<td>1000002043</td>
<td class = "amount">25.0</td>
<td>CHK</td>
<td></td>
<td></td>
<td>5</td>
<td>Show</td>
<td>Edit</td>
<td><a data-confirm="Are you sure?" rel="nofollow" data-method="delete" href="/payments/6">Destroy</a></td>
</tr>
<% end %>
</tbody>
<td>Total</td><td><div id="total"></div></td>
Here is the jquery
$(function() {
$('.box').change(function(){
var total = 0;
$('.box:checked').each(function(){
total+=parseFloat($(this).parent().next('td').find('.amount').text());
});
$('#total').text(total);
});
});
I am getting a NaN in the total element.

Let's break down your jQuery chain:
$(this) // ,box
.parent() // The <td>
.next('td') // The next <td> in the sequence
.find('.amount') // Tries to find an element with class `amount` inside the <td>
.text() // Empty, because the previous element doesn't exist
What you'll need to do is append the .amount onto your selector and use nextAll instead, like so:
$(this).parent().nextAll("td.amount").text()
If you had multiple amount classes, you'd need to make sure you only picked the first one like so:
$(this).parent().nextAll("td.amount:first").text()
Example:
$('.box').change(function(){
var total = 0;
$('.box:checked').each(function(){
total+=parseFloat($(this).parent().nextAll('td.amount').text());
});
$('#total').text(total);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td><input type="checkbox" name="payment_id[]" id="payment_id_" value="6" class="box" checked="checked" /></td>
<td>2015-08-26 20:43:50 UTC</td>
<td>1000002043</td>
<td class = "amount">25.0</td>
<td>CHK</td>
<td></td>
<td></td>
<td>5</td>
<td>Show</td>
<td>Edit</td>
<td><a data-confirm="Are you sure?" rel="nofollow" data-method="delete" href="/payments/6">Destroy</a></td>
</tr>
</tbody>
</table>
<div id="total"></div>

Considering the amount is entered once per row I jumped back to row and found the td.amount in the row.
(function($) {
$('.box').change(function(){
var total = 0;
$('.box:checked').each(function(){
total += parseFloat($('td.amount', $(this).closest('tr')).text());
});
$('#total').text(total);
});
})(jQuery);

There is a referencing error. Use:
$(function() {
$('.box').change(function(){
var total = 0;
$('.box:checked').each(function(){
total+=parseFloat($(this).closest('tr').find('td.amount').text());
});
$('#total').text(total);
});
});

Related

Trying to get element and store them in array using jquery

I have an html structure like this :
<tr>
<td>NC</td>
<td><%= #subscriptions.where("users.ranking = 'NC'").count %></td>
<td><input type="checkbox" name="my-checkbox" class="checkbox-ranking" id="bite" data-size='small'></td>
</tr>
<tr>
<td>40</td>
<td><%= #subscriptions.where("users.ranking = '40'").count %></td>
<td><input type="checkbox" name="my-checkbox" class="checkbox-ranking" data-size='small' ></td>
</tr>
<tr>
<td>30/5</td>
<td><%= #subscriptions.where("users.ranking = '30/5'").count %></td>
<td><input type="checkbox" name="my-checkbox" class="checkbox-ranking" data-size='small' ></td>
</tr>
I need to write a script that each time a checkbox is checked gets the innerhtml of the first <td></td> of each <tr></tr> where the checkbox is checked and returns it as an array.
Here's what I came up with :
$(document).ready(function(){
$('.checkbox-ranking').on('change', function() {
var rankings = $('.checkbox-ranking:checked').map(function() {
return $(this).parent().parent().parent().parent().children().first().html();
}).get().join(',');
alert(rankings);
});
});
I must add that I installed the gem bootstrap-switch to have ON/OFF switch button and that is what my checkboxes are. I noticed that I switch on my button, it doesnt pass to checkedin the html code, so I guess that's why my code isnt working: the script doesnt actually detects the on change event.
Any other ideas ?
Ok, now this works
$(document).ready(function(){
$('.checkbox-ranking').on('change', function() {
var rankings = $('.checkbox-ranking:checked').map(function() {
return $(this).parent().parent().find('td:first-child').html();
}).get().join(',');
alert(rankings);
});
});
and jsfiddle: https://jsfiddle.net/btrauybx/2/
Try using closest() and first():
$(function() {
$('input.checkbox-ranking').on('change', function(e) {
var ranks = $('input.checkbox-ranking:checked').map(function() {
return $(this).closest('tr').children().first().text();
}).get();
alert(ranks.join(','));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tr>
<td>NC</td>
<td>
<%=# subscriptions.where( "users.ranking = 'NC'").count %>
</td>
<td>
<input type="checkbox" name="my-checkbox" class="checkbox-ranking" id="bite" data-size='small'>
</td>
</tr>
<tr>
<td>40</td>
<td>
<%=# subscriptions.where( "users.ranking = '40'").count %>
</td>
<td>
<input type="checkbox" name="my-checkbox" class="checkbox-ranking" data-size='small'>
</td>
</tr>
<tr>
<td>30/5</td>
<td>
<%=# subscriptions.where( "users.ranking = '30/5'").count %>
</td>
<td>
<input type="checkbox" name="my-checkbox" class="checkbox-ranking" data-size='small'>
</td>
</tr>
</table>
You can also use eq(0) instead of first().

select dynamically muiltiple element from a html table

I want to select value from a dynamically list coming from database with javascript. My table <td> and <tr> are create dynamically from a database. I manage the "id" attribute with 0, 1 in front of its with a for loops. Also like "id" of the select's button
<tr>
<td id="pres0">Bear</td>
<td id="cod0">ddfd</td>
<td id="id0">23</td>
<td><input type="button" value="select" id="id-but-select0"></td>
</tr>
<tr>
<td id="pres1">Cat</td>
<td id="cod1">AZ</td>
<td id="id1">121</td>
<td><input type="button" value="select" id="id-but-select1"></td>
</tr>
<!-- the total count of the select of the database -->
<input id="nbra" type="hidden" value="2">
What i want is that when i put on the select button, i have an alert which show the value of the id of each td in javascript or jquery
I'd suggest:
function showCellValues(e) {
// preventing any default actions:
e.preventDefault();
// caching the 'this' for later use (potentially):
var self = this,
// creating a variable to traverse the DOM (in the while loop to follow):
cell = self,
// working out whether we need to use textContent or innerText to retrieve
// a node's text:
textProp = 'textContent' in document ? 'textContent' : 'innerText';
// while the cell element is not a <td> element:
while (cell.tagName.toLowerCase() !== 'td') {
// we assign the current parentNode to the cell variable,
// and then go again:
cell = cell.parentNode;
}
// an empty array to hold the key-value pairs:
var keyValues = [];
// converting the NodeList of the parentNode's child elements to an Array,
// iterating over that array with Array.prototype.forEach():
[].slice.call(cell.parentNode.children, 0).forEach(function (el) {
// we only want to get values from the siblings (not the cell
// containing the clicked <input />:
if (el !== cell) {
// if the cell is not the current el, we push a string
// to the keyValues array:
keyValues.push(el.id + ': ' + el[textProp]);
}
});
// showing the output; use alert, or return or whatever here to your
// requirements:
console.log(keyValues.join(', '));
}
// converting the NodeList of all inputs of type=button *and* value=select that
// are within a <td> element into an array, and iterating over that array:
[].slice.call(document.querySelectorAll('td > input[type="button"][value="select"]'), 0).forEach(function(button){
// binding the 'click' event-handler function (showCellValues):
button.addEventListener('click', showCellValues);
});
function showCellValues(e) {
e.preventDefault();
var self = this,
cell = self,
textProp = 'textContent' in document ? 'textContent' : 'innerText';
while (cell.tagName.toLowerCase() !== 'td') {
cell = cell.parentNode;
}
var keyValues = [];
[].slice.call(cell.parentNode.children, 0).forEach(function (el) {
if (el !== cell) {
keyValues.push(el.id + ': ' + el[textProp]);
}
});
console.log(keyValues.join(', '));
}
[].slice.call(document.querySelectorAll('td > input[type="button"][value="select"]'), 0).forEach(function(button){
button.addEventListener('click', showCellValues);
});
<table>
<tbody>
<tr>
<td id="pres0">Bear</td>
<td id="cod0">ddfd</td>
<td id="id0">23</td>
<td>
<input type="button" value="select" id="id-but-select0" />
</td>
</tr>
<tr>
<td id="pres1">Cat</td>
<td id="cod1">AZ</td>
<td id="id1">121</td>
<td>
<input type="button" value="select" id="id-but-select1" />
</td>
</tr>
</tbody>
</table>
References:
Array.prototype.forEach().
Array.prototype.join().* Array.prototype.push().
Array.prototype.slice().
Element.tagName.
Function.prototype.call().
String.prototype.toLowerCase().
This will do it:
<!DOCTYPE HTML>
<html>
<head>
<title>Show id values</title>
<script language="javascript">
function showValue(nodeID){
var myVar = document.getElementById(nodeID).parentNode.parentNode.childNodes;
var myTxt = "";
for(i=0; i<myVar.length; i++){
if(myVar[i].id){
if(myVar[i].id != ""){
myTxt += myVar[i].id + '\n';
}
}
}
alert(myTxt);
}
</script>
</head>
<body>
<table>
<tr>
<td id="pres0">Bear</td>
<td id="cod0">ddfd</td>
<td id="id0">23</td>
<td><input type="button" value="select" id="id-but-select0" onclick="showValue(this.id)" /></td>
</tr>
<tr>
<td id="pres1">Cat</td>
<td id="cod1">AZ</td>
<td id="id1">121</td>
<td><input type="button" value="select" id="id-but-select1" onclick="showValue(this.id);" /></td>
</tr>
</table>
<!-- the total count of the select of the database -->
<input id="nbra" type="hidden" value="2">
</body>
</html>
You can add an on-click event to your buttons and then access that td's siblings for their properties, say id, text etc.
<tr>
<td id="pres0">Bear</td>
<td id="cod0">ddfd</td>
<td id="id0">23</td>
<td><input type="button" value="select" id="id-but-select0" onclick="makeAlert(this)"></td>
</tr>
<tr>
<td id="pres1">Cat</td>
<td id="cod1">AZ</td>
<td id="id1">121</td>
<td><input type="button" value="select" id="id-but-select1" onclick="makeAlert(this)"></td>
</tr>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
function makeAlert(divObj){
var tds = $(divObj).parent().siblings();
tds.each(function( index ) {
alert($( this ).attr('id') );
});
}
</script>
<html>
<head>
</head>
</body>
<table border="1">
<tr>
<td id="pres0">Bear</td>
<td id="cod0">ddfd</td>
<td id="id0">23</td>
<td><input type="button" value="select" id="id-but-select0"></td>
</tr>
<tr>
<td id="pres1">Cat</td>
<td id="cod1">AZ</td>
<td id="id1">121</td>
<td><input type="button" value="select" id="id-but-select1"></td>
</tr>
</table>
<!-- the total count of the select of the database -->
<input id="nbra" type="hidden" value="2">
<script src="http://code.jquery.com/jquery.min.js"></script>
<script>
$(function(){
$('table input[type=button][value="select"]').click(function(){
$(this).closest('table').find('tr').each(function(){
alert($(this).find('td:eq(2)').html());
});
})
})
</script>

jQuery not working on Intranet site

I am attempting to have jQuery total form data on an internal form. I have used the current code on jsfiddle.net and it worked on there with jQuery 1.6.4.
I have tried multiple different jQuery versions. But I am new to jQuery/javascript in general so I have no idea where to proceed from here.
Any help would be much appreciated!
<script type="text/javascript" src="jquery-1.6.4.js">
var $form = $('#apple-order'),
$summands = $form.find('.apple'),
$sumDisplay = $('#total');
$form.delegate('.apple', 'change', function ()
{
var sum = 0;
$summands.each(function ()
{
var value = Number($(this).val());
if (!isNaN(value)) sum += value;
});
$sumDisplay.text(sum);
});
</script>
<table width="300" border="0" align="center" cellpadding="0" cellspacing="1" id="apple-order">
<tr>
<td>
<form name="apple" method="post" action="insert.php">
<tr>
<td colspan="3" align="center"><strong>Caramel Apple Order Form</strong></td>
</tr>
<tr>
<td>Employee Name</td>
<td>: </td>
<td><input name="name" type="text"></td>
</tr>
<tr>
<td>Plain Caramel Apple</td>
<td>: </td>
<td><input name="plain" type="text" class="apple"></td>
</tr>
<tr>
<td>w/ Snickers</td>
<td>: </td>
<td><input name="snickers" type="text" class="apple"></td>
</tr>
<tr>
<td>w/ Butterfinger</td>
<td>: </td>
<td><input name="butter" type="text" class="apple"></td>
</tr>
<tr>
<td>w/ Mini M&Ms</td>
<td>: </td>
<td><input name="mini" type="text" class="apple"></td>
</tr>
<tr>
<td>w/ Pretzels</td>
<td>: </td>
<td><input name="pretzel" type="text" class="apple"></td>
</tr>
<tr>
<td colspan="3" align="center"><strong>Apples w/ Toppings come with Chocolate Drizzle</strong></td>
</tr>
<tr>
<td colspan="3" align="center">Total: <span id="total"></span></td>
</tr>
<tr>
<td colspan="3" align="center"><input type="submit" value="SUBMIT"> </td>
</tr>
</tr>
</table>
Your <script> tags are laid out incorrectly. You need to separate the tags that load external libraries from inline scripts, as I have shown below. You should also load your Javascript at the bottom of the page, after your HTML is declared.
<script type="text/javascript" src="jquery-1.6.4.js"></script>
<script>
var $form = $('#apple-order'),
$summands = $form.find('.apple'),
$sumDisplay = $('#total');
$form.delegate('.apple', 'change', function ()
{
var sum = 0;
$summands.each(function ()
{
var value = Number($(this).val());
if (!isNaN(value)) sum += value;
});
$sumDisplay.text(sum);
});
</script>
You are attempting to access elements before they exist. Wrap your code in a DOM ready handler. Additionally, if you have a script element with a src attribute, you can't put code in it. You need two script tags:
<script type="text/javascript" src="jquery-1.6.4.js"></script>
<script>
$(function () {
var $form = $('#apple-order'),
// etc
});
</script>
By default, jsfiddle wraps your code in an onLoad handler, which can be confusing.
Declare all your libraries first
<script type="text/javascript" language="javascript" src="jquery-1.6.4.js"></script>
...
then start coding in another place
<script>
// do something
</script>
I think the problem is that you're not actually importing jQuery. Try adding the following before your script:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
This will download jQuery from Google's CDN.

if input field has a value found in array, do this (jQuery/Javascript)

I've got a page with a handful of input fields.
I need to find the fields with an array of values, and if so, .remove() the closest('tr')
The markup is similar to this
<table>
<tr>
<td>
<input type="text" value="this">
</td>
</tr>
<tr>
<td>
<input type="text" value="that">
</td>
</tr>
<tr>
<td>
<input type="text" value="them">
</td>
</tr>
</table>
I need to find "this" and "that", and if they are there, remove their <tr> container (and themselves) so I'd end up with:
<table>
<tr>
<td>
<input type="text" value="them">
</td>
</tr>
</table>
I've tried this:
jQuery(document).ready(function($){
var badfields = ['this', 'that'];
var fieldvalue = $('input[type="text"]').val();
if($.inArray(fieldvalue, badfields) > -1){
$(this).closest('tr').remove();
}
});
but it doesn't seem to want to work?
You need to iterate over all the fields using .each, so something like this:
$('input[type="text"]').each(function() {
var fieldvalue = $(this).val();
if ($.inArray(fieldvalue, badfields) > -1) {
$(this).closest('tr').remove();
}
});
Example: jsfiddle
You can be very concise sometimes with jQuery. jQuery has content selectors you can use for this type of purpose:
$("input[type=text][value=this], [value=that]").parents("tr").remove();
since you don't necessarily know this or that beforehand, you can do something like this:
var badfields = ['this', 'that'];
$(badfields).each(function(i) {
$("input[type=text][value=" + this + "]").parents("tr").remove();
});
You can use each to iterate through the selector. this in your inArray scope is not the element you were looking for.
DEMO: http://jsfiddle.net/
html:
<table>
<tr>
<td>
<input type="text" value="this">
</td>
</tr>
<tr>
<td>
<input type="text" value="that">
</td>
</tr>
<tr>
<td>
<input type="text" value="them">
</td>
</tr>
</table>
js:
jQuery(document).ready(function($){
var badfields = ['this', 'that'];
$('input[type="text"]').each(function(){
if( $.inArray(this.value, badfields) > -1 ){
$(this).closest('tr').remove();
}
});
});

Change the value of a text box to its current order in a sortable tab

Edit: I have solved this by myself. See my answer below
I have set up a nice sortable table with jQuery and it is quite nice. But now i want to extend it.
Each table row has a text box, and i want i am after is to, every time a row is dropped, the text boxes update to reflect the order of the text boxes. E.g. The text box up the top always has the value of '1', the second is always '2' and so on.
I am using jQuery and the Table Drag and Drop JQuery plugin
Code
Javascript:
<script type = "text/javascript" >
$(document).ready(function () {
$("#table-2").tableDnD({
onDrop: function (table, row) {
var rows = table.tBodies[0].rows;
var debugStr = "Order: ";
for (var i = 0; i < rows.length; i++) {
debugStr += rows[i].id + ", ";
}
console.log(debugStr)
document.forms['productform'].sort1.value = debugStr;
document.forms['productform'].sort2.value = debugStr;
document.forms['productform'].sort3.value = debugStr;
document.forms['productform'].sort4.value = debugStr;
},
});
});
</script>
HTML Table:
<form name="productform">
<table cellspacing="0" id="table-2" name="productform">
<thead>
<tr>
<td>Product</td>
<td>Order</td>
</tr>
</thead>
<tbody>
<tr class="row1" id="Pol">
<td>Pol</td>
<td><input type="textbox" name="sort1"/></td>
</tr>
<tr class="row2" id="Evo">
<td>Evo</td>
<td><input type="textbox" name="sort2"/></td>
</tr>
<tr class="row3" id="Kal">
<td>Kal</td>
<td><input type="textbox" name="sort3"/></td>
</tr>
<tr class="row4" id="Lok">
<td>Lok</td>
<td><input type="textbox" name="sort4"/></td>
</tr>
</tbody>
</table>
</form>
Hardnrg in #jquery ended up solving it for me.
It involved adding an id="" to each input:
<form name="productform">
<table cellspacing="0" id="table-2" name="productform">
<thead>
<tr><td>Product</td> <td>Order</td></tr>
</thead>
<tbody>
<tr class="row1" id="Pol"> <td>Pol</td> <td><input id="Pol_field" type="textbox" name="sort1"/></td> </tr>
<tr class="row2" id="Evo"> <td>Evo</td> <td><input id="Evo_field" type="textbox" name="sort2"/></td> </tr>
<tr class="row3" id="Kal"> <td>Kal</td> <td><input id="Kal_field" type="textbox" name="sort3"/></td> </tr>
<tr class="row4" id="Lok"> <td>Lok</td> <td><input id="Lok_field" type="textbox" name="sort4"/></td> </tr>
</tbody>
</table>
</form>
And add this js to the OnDrop event:
for (var i=0; i < rows.length; i++) {
$('#' + rows[i].id + "_field").val(i+1);
}
Easy peasy!
Hmmm..
I think you want to do something like this:
$("input:text", "#table-2").each( function(i){ this.value=i+1; });
The $().each() function's info is here: http://docs.jquery.com/Core/each

Categories