Number showing as NaN in <input> when set with jQuery .val() [closed] - javascript

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to set the value of an input field with jQuery val()
$('[name="paytype1"]').change(function(){
var total = big_total();
total = parseFloat(total);
total = total.toFixed(2);
console.log(total);
if(isNaN(total)) {
alert(total);
}
$('[name="pay1amt"]').val(total);
})
And all that is being shown in the browser is NaN.
Running console.log(total) shows a number, e.g. 61.00, and no alert is being triggered.
The big_total() function is returning the number correctly (it calculates from numbers in other input fields).
function big_total() {
var big_total = 0;
$('.total').each(function(i){
big_total = big_total + parseFloat($(this).val());
});
big_total = big_total.toFixed(2)
return big_total;
}
The inputs with the class total are being added to the page dynamically by jQuery after an ajax call. This is the html that is inserted:
<div class="grid_12 alpha omega line-items">
<div class="grid_1">CH02<input type="hidden" name="item_code[]" value="CH02">
<input type="hidden" name="item_id[]" value="1458">
</div>
<div class="grid_3">
DVA Regular consult
<input type="hidden" name="item_desc[]" value="Subsequent consultation">
<input type="hidden" name="type[]" value="Service">
</div>
<div class="grid_1">
<input type="text" size="3" name="qty[]" value="1" class="qty" max-length="3">
</div>
<div class="grid_2">
<input type="text" size="7" name="sub_total[]" value="61.00" class="sub-total">
</div>
<div class="grid_1">
<select name="tax[]">
<option value="$taxitems[ID]">0%</option>
<option value="$taxitems[ID]">10%</option>
</select>
</div>
<div class="grid_2">
<input type="text" size="7" name="total[]" value="61.00" class="total" readonly="">
</div>
<div class="grid_1 omega">
<div class="remove_stock_line"><img src="images/collapse.png"></div>
</div>
</div>
This is the drop down triggering the function:
<div class="grid_8 alpha omega">
<div class="grid_3 alpha">
<select name="paytype1" class="pay_type">
<option default="" value="nill"></option>
<option value="cash">cash</option>
<option value="HICAPs">HICAPs</option>
<option value="EFTPOS">EFTPOS</option>
<option value="Visa">Visa</option>
<option value="Mastercard">Mastercard</option>
<option value="American Express">American Express</option>
<option value="Other card">Other card</option>
<option value="EFT">EFT</option>
<option value="Cheque">Cheque</option>
</select>
</div>
<div class="grid_3 omega">
<input type="text" size="10" name="pay1amt" value="" onclick="select();" class="pay_values">
</div>
</div>
Thoughts?

There is nothing wrong with this function. But since we cannot see your full source code and you haven't shared your big_total function we can only speculate. From my personal experience I see only two possible scenarios.
big_total() returns a non-numeric value or has leading non-numeric character like $4339, because parseFloat() ignores trailing non-numeric characters except period(.) eg: 83483a;lsdfad will not give you an error. But since you don't see any error in the console or an alert, this scenario can be ruled out.
The only other explanation is that, some other part of the code is overwriting the value set by this function.
If I were you I would follow these steps to debug.
I would replace:
var total = big_total()
with:
var total = 1234.56;
If you see the result in $('[name="pay1amt"]') then the problem is in big_total. If you still see NaN then I would look elsewhere in the code to see where the value is getting overwritten.
This is not related to the question but is very important.
Do not use the variable name big_total inside the function big_total(). Javascript does not differentiate between functions and variables when storing and retrieving them from the stack. Parenthesis directs the interpreter to execute the function while the absence of parenthesis directs the interpreter to reference it as a variable (without executing it).
//Try this code
function hi(){
//without parenthesis it is treated as a variable
alert('without ()\n\n'+hi);
return 6;
}
//with parenthesis it is executed as a function
alert('With () \n'+ hi());

this is working
function big_total() {
var bg_total = 0;
$('.total').each(function(i){
bg_total = bg_total + parseFloat($(this).val());
});
big_total = bg_total.toFixed(2)
return bg_total;
}
$(document).ready(function(){
$("[name='paytype1']").change(function(){
var total = big_total();
total = parseFloat(total);
total = total.toFixed(2);
console.log(total);
if(isNaN(total)) {
alert(total);
}
$('input[name="pay1amt"]').val(total);
});
});
UPDATE
in your big_total() function, $('.total') element is only a class of an input which occurrence is one. why are you using $.each for it
$('.total').each(function(i){
big_total = big_total + parseFloat($(this).val());
});
//you can just replace the use of .each above to this in the big_total function, except you have special reason for that
bg_total = bg_total + parseFloat(".total").val());
<input type="text" size="7" name="total[]" value="61.00" class="total" readonly="">
When you said in the question And all that is being shown in the browser is NaN. Running console.log(total) shows a number, e.g. 61.00, and no alert is being triggered.
NaN will only be shown to when the value of the input with class .total starts with non-numeric. that is only when you should expect the if(isNaN(total)) {alert(total);} to work.
yes the console.log(total) is showing the value 61.00 because The big_total() function is returning the number correctly, but this is what i dont know if you have taken care of (it calculates from numbers in other input fields)
Apart from these your problem should be solved.

Related

onclick function getInc not defined

I am creating my first web app and have run in to an issue pretty early on!
I have created a function which extracts the information that the user keys into the HTML input field. The way it should work is that when the user enters their income and clicks the submit button, the income is stored in a variable for me to use throughout the rest of my JavaScript code.
Looking at the console log, the function is coming up as 'not defined'.
I appreciate the code is probably not very clean but I just want to get it working as it's my first small project!
Any ideas where I am going wrong?
Here's the HTML:
<div class="row input-1">
<label for="Gross Annual Salary">£</label>
<input type="number" name="Gross Annual Salary" id="Ann-Sal" placeholder="Gross Annual Salary" required>
<input type="button" class="submit-btn" value="Submit" onclick="getInc();">
</div>
Here's the JavaScript:
function getInc() {
var inc = document.getElementById("Ann-Sal");
}
I remove semiclon from onclick end and it works
<div class="row input-1">
<label for="Gross Annual Salary">£</label>
<input type="number" name="Gross Annual Salary" id="Ann-Sal" placeholder="Gross Annual Salary" required>
<input type="button" class="submit-btn" value="Submit" onclick="getInc()">
</div>
<script>
function getInc() {
console.log('works');
var inc = document.getElementById("Ann-Sal");
}
</script>
<script>
function getInc() {
console.log('works');
var inc = document.getElementById("Ann-Sal");
}
</script>
<div class="row input-1">
<label for="Gross Annual Salary">£</label>
<input type="number" name="Gross Annual Salary" id="Ann-Sal" placeholder="Gross Annual Salary" required>
<input type="button" class="submit-btn" value="Submit" onclick="getInc()">
</div>
First of all make sure you have your <script> after the body (ie: put it after the last closing <div>), secondly if you want to what the user typed in you should get the elements value. When you set inc equal to document.getElementById("Ann-Sal"); you are giving it the DOM element instead of the it's value instead you should put:
function getInc() {
var inc = document.getElementById("Ann-Sal");
}
Then you will get the value the user inputted to the code.
Also, a tip use addEventListener() instead of the onclick attribute, it's better practice.
Ok, so I tried to fix it myself using some of Tom O's code above here:
var buttonEl = document.querySelector('input[type="button"]');
var inputEl = document.getElementById("Ann-Sal");
var annInc;
function clickHandler() {
annInc = parseFloat(inputEl.value);
console.log(annInc);
}
buttonEl.addEventListener('click', clickHandler);
HTML:
<div class="row input-1">
<label for="Gross Annual Salary">£</label>
<input type="number" name="Gross Annual Salary" id="Ann-Sal" placeholder="Gross Annual Salary" required>
<input type="button" class="submit-btn" value="Submit">
</div>
This didn't work. There was no error message but nothing was logged to the console when submitting an income into the input field.
I then reconfigured the Javascript code to this:
var buttonEl = document.querySelector('input[type="button"]');
var inputEl = document.getElementById("Ann-Sal");
var annInc;
function clickHandler() {
if (!inputEl.value.length) {
console.error('A salary is required!');
return;
}
annInc = parseFloat(inputEl.value);
console.log(annInc);
}
buttonEl.addEventListener('click', clickHandler);
This then worked. I didn't use the if statement to validate the users input previously because I used 'required' in the input element within my HTML code which basically does the same thing right? So i'm guessing the reason why the code wasn't working because the 'return' statement wasn't used?
Would someone be kind enough to explain to me why the return statement enabled this to work?
I'm sure for some of you experienced guys, my lack of understanding must be painful for you! I am super determined to get my head around this though.
Many thanks
Besides the other answers, I just wanna point it out that is missing the .value in your function, otherwise, you won't get the value.
function getInc() {
var inc = document.getElementById("Ann-Sal").value
}

In Javascript why is appending to TextArea field failing in one case but not the other

I have a javascript function that takes a value from a select and append its to the end of a textarea field (mask) whenever a new selection is made from the select
function addToEditMask(select, mask)
{
var selectedValue = document.getElementById(select).value;
document.getElementById(mask).append(" + "+selectedValue);
}
This function is used by two different elements on the same page as follows:
<div class="form-group">
<label for="edit_filename_mask_mask" id="edit_filename_mask_masklabel">
Mask
</label>
<textarea type="text" id="edit_filename_mask_mask" name="edit_filename_mask_mask"
aria-describedby="edit_filename_mask_masklabel" class="form-control" rows="10" cols="80"></textarea>
</div>
<div class="form-group">
<label for="editMaskVarList" id="editMaskVarListlabel">
Mask Fields
</label>
<select class="mb-2 form-control custom-select" id="editMaskVarList" onchange="addToEditMask('editMaskVarList', 'edit_filename_mask_mask');">
<option>
acoustic (Acoustic)
</option>
.....
and
<div class="form-group">
<label for="add_filename_mask_mask" id="add_filename_mask_masklabel">
Mask
</label>
<textarea type="text" id="add_filename_mask_mask" name="add_filename_mask_mask"
aria-describedby="add_filename_mask_masklabel" class="form-control" rows="10" cols="80"></textarea>
</div>
<div class="form-group">
<label for="addMaskVarList" id="addMaskVarListlabel">
Mask Fields
</label>
<select class="mb-2 form-control custom-select" id="addMaskVarList" onchange="addToEditMask('addMaskVarList', 'add_filename_mask_mask');">
<option>
acoustic (Acoustic)
</option>
......
In each case the select and the mask are both within a Bootstrap modal dialog. But it only works for the second case (add_filename_mask_mask) not the first case (edit_filename_mask_mask)
I added some debugging to ensure
function addToEditMask(select, mask)
{
var selectedValue = document.getElementById(select).value;
document.getElementById(mask).append(" + "+selectedValue);
alert('Adding to mask:'+mask+':'+scriptvar+':'+document.getElementById(mask).value);
}
that the function was actually being called in both cases and all the variables a renamed correctly. Yet although there are no webconsole errors and the append() method doesnt report any error the value of mask doesnt change for edit_filename_mask_mask
I cannot create a SSCE since there seems to be no difference between the working and non working version. The only difference of note is that when modal dialog is first displayed edit_filename_mask_mask has a value but add_filename_mask_mask does not. However edit_filename_mask_mask continues to fail if I blank out edit_filename_mask_mask , and add_filename_mask_mask when has value.
What happens if you try some safety checks ?
function addToEditMask(select, mask)
{
var selectedValue = document.getElementById(select).value || "";
var textarea = document.getElementById(mask);
textarea.value = (textarea.value || "") + " + " + selectedValue;
}
Variable name is "selectedValue" and you call to "selectValue"

Sort by or re-order, instead of hiding/showing

I'm trying to refactor my Javascript/Jquery to use a select option and hidden input value in order to sort the divs on the page.
Currently, my JS works but it's hiding all divs whose hidden input has a value of 0. I want to keep the logic, but instead of hiding, just reorder the divs.
So if the user selects Recently_ordered from the select box, then any div whose hidden input has a value of 1 would show first and all with 0 would show after. Basically, all items remain on page but reorder slightly.
here's the working script that currently hides:
<script type="text/javascript">
$(function(){
$('#filterText').on('change', function() {
var currentVal = $(this).val();
$(".group-container").show();
if (currentVal == 'recently_ordered') {
$('.group-container input[name="reorder"]').each(function (index, value){
if($(this).val() == "0"){
$(this).parent('.group-container').hide();
}
});
}
});
});
</script>
And the basic structure of the HTML:
#foreach ($orderFormData->pgroups as $pgroup)
<div class="group-container">
<input type="hidden" name="topseller" value="{{$pgroup->topseller}}" />
<input type="hidden" name="reorder" value="{{$pgroup->reorder}}"/>
Grab the .group-container elements as array, sort it according to their reorder value and append them to the DOM in the order of the array.
The snippet is really verbose but should give enough informations to follow the code.
The functions used in this snippet should all have a link to the official documentation or the description in the Mozilla Development Network in the comments.
The "groups" in the DOM have the mentioned hidden input fields and an additional <p> element which shows the value of the topseller and reorder fields which should make it easier to follow the changes from the script.
$(function() {
$("#filterText").on("change", function() {
var container = $(".container"), // get the surrounding container, used for appending the sorted groups
groups = $(".group-container").get(), // grab the "groups" and make them a regular array
// .get() -> https://api.jquery.com/get/
currentVal = this.value; // the value of the selected option
groups
// first we have to sort them in the "correct" order
// Array.prototype.sort() -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
.sort(function(left, right) {
var topsellerValueLeft = parseInt(left.querySelector('input[name="topseller"]').value, 10), // get the value of the topseller field and make it a number
topsellerValueRight = parseInt(right.querySelector('input[name="topseller"]').value, 10), // get the value of the topseller field and make it a number
// Element.prototype.querySelector -> https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector
// parseInt() -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
// parseInt($(left).find('input[name="topseller"]').val(), 10)
// parseInt($(right).find('input[name="topseller"]').val(), 10)
// would yield the same result, but we don't need two full-blown jQuery objects just to get the value
reorderValueLeft,
reorderValueRight;
// in case of "recently ordered" we sort the groups on their reorder value
if (currentVal === "recently_ordered") {
reorderValueLeft = parseInt(left.querySelector('input[name="reorder"]').value, 10); // get the value of the reorder field and make it a number
reorderValueRight = parseInt(right.querySelector('input[name="reorder"]').value, 10); // get the value of the reorder field and make it a number
// we have to check the reorder value only when the values are different
if (reorderValueLeft !== reorderValueRight) {
return reorderValueRight - reorderValueLeft; // sort descending -> 1 ... 0
}
}
// either we are not supposed to sort the items by their reordered value
// or they have the same reordered value
// hence we will then sort them on their topseller value
// this time in ascending order
return topsellerValueLeft - topsellerValueRight;
})
// now we append the elements to the DOM in the same order as we find them in the array
// this will "remove" the groups one by one from the DOM and append it at their correct new spot
// Array.prototype.forEach() -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
.forEach(function(group) {
container.append(group); // .append() -> https://api.jquery.com/append/
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="filterText">
<option value="default">default</option>
<option value="recently_ordered">recently ordered</option>
</select>
<br />
<div class="container">
<div class="group-container">
<p>1 | 1</p>
<input type="hidden" name="topseller" value="1" />
<input type="hidden" name="reorder" value="1" />
</div>
<div class="group-container">
<p>2 | 0</p>
<input type="hidden" name="topseller" value="2" />
<input type="hidden" name="reorder" value="0" />
</div>
<div class="group-container">
<p>3 | 1</p>
<input type="hidden" name="topseller" value="3" />
<input type="hidden" name="reorder" value="1" />
</div>
<div class="group-container">
<p>4 | 0</p>
<input type="hidden" name="topseller" value="4" />
<input type="hidden" name="reorder" value="0" />
</div>
</div>
(or on jsfiddle.net)

Javascript calculate / update total onclick multiple form elements

Im helping a friend building a basic site. My javascript skills leaves much to be desired so I am learning I started with Javascript instead of Jquery library (sidenote: should I just go with Jquery from the start...?)
So I have the following:
Form with 3 radio buttons value low(1), medium(2), high(3)
Slider with amount
Select with duration.
The formula is calculated by user selecting risk (radio btns) amount (slider) duration (dropdowm)
When the user changes risk, or amount, or duration the total should get updated, and a button displayed.
So I came up with the following javascript:
JAVASCRIPT:
function getReturn(){
var risk = document.forms[0];
var years = document.getElementById("investmentDuration").value;
var slideAmount = document.getElementById("slideAmount").value;
var txt;
var returns;
var i;
for(i = 0; i < risk.length; i++){
if(risk[i].checked){
txt = risk[i].value;
//for
if(txt == 1){
returns = (slideAmount * 0.06)*years;
returns = Math.ceil(returns); // NO decimals
}
if(txt == 2){
returns = slideAmount * 0.11;
returns = Math.ceil(returns)*years; // NO decimals
}
if(txt == 3){
returns = slideAmount *0.17;
returns = Math.ceil(returns)*years; // NO decimals
}
}//if
}//for
I then added the getReturn() function to each element in the form...
I get the following when I try and run it, here is my JS FIDDLE
ERROR: getReturn() is not defined
HTML (note the on click function on each element)
<h2>SELECT INVESTMENT RISK LEVEL</h2>
<section>
<div>
<input type="radio" id="control_01" onclick="getReturn()" name="risk" value="1" checked>
<label for="control_01">
<h2>LOW RISK</h2>
<p>Slow & Steady. An Product Focused On Low Risk But Long term Gains</p>
</label>
</div>
<div>
<input type="radio" id="control_02" name="risk" onclick="getReturn()" value="2">
<label for="control_02">
<h2>MEDIUM</h2>
<p>Prepare For Glory. Medium To High Returns, Over A Medium To Long Period.</p>
</label>
</div>
<div>
<input type="radio" id="control_03" name="risk" onclick="getReturn()" value="3">
<label for="control_03">
<h2>High Risk</h2>
<p>Hardcore Investor. Tailored Based Package Focused on High Returns Over Short Periods</p>
</label>
</div>
</section>
<h4 style="color: black;">INVESTMENT AMOUNT:</h4>
<input type="range" id="slideAmount" name="slideAmount" onchange="getReturn()" value="6500" step="25" min="1000" max="10000">
<p>Number Of Years</p>
<select name="investmentDuration" id="investmentDuration" onclick="getReturn()">
<option value="1" selected>1 Year</option>
<option value="2">2 Years</option>
<option value="3">3 Years</option>
<option value="4">4 Years</option>
<option value="5">5 Years</option>
</select>
UPDATE
I got it to work however I feel
Having a onclick() / onchange = function() on each element seems inefficient.
I feel the code is prone to bugs if the page should get larger and expanded on.
Any constructive criticism and / or advice appreciated on how I can work and improve on this. Many Thanks
You get the
getReturn() is not defined
error because your code is inside an onLoad event (that is the default in jsfiddle)
You need to change this setting as shown in the image so that your function is in the global scope and thus callable from the DOM.
Then you also need to add the #returns element in your html.
A final improvement might be to use the oninput event on the range element so that is updates while you slide
All fixes: https://jsfiddle.net/gaby/o1zmvmL9/2/

Javascript onchange function not working on select tag

I made 2 input fields and 1 select field and I applied onchange() function to select tag which calls javascript and that script make calculation and show it in other two fields
but it is not working for some syntax or logic reasons. please take a look at my code ,any help would be appreciated.
<html>
<head>
<script type="text/javascript">
function update() {
var x = document.getElementsByName("n_person").value;
document.getElementsByName("m_income").value= x*5;
document.getElementsByName("y_income").value= x*4;
}
</script>
</head>
<body>
<div class="elist"> <span class="b_text"><span>*</span>Level 1:</span>
// here is select tag where I put onchage function <select class="ifield" name="n_person" onChange="update()">
<option value="" selected="selected">Choose no. of person referred</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
// These are teh input where resultant value will appear <input type="text" value="" placeholder="Your weekly Income..." name="m_income" id="weekly_income" class="field" readonly required />
<input type="text" value="" placeholder="Your day Income..." name="y_income" id="day_income" class="field" readonly required/>
</div>
<!--elist-->
</body>
</html>
See this fiddle
Updated JS
function update() {
var x = document.getElementsByName("n_person")[0].value;
document.getElementsByName("m_income")[0].value = x * 5;
document.getElementsByName("y_income")[0].value = x * 4;
}
The problem with your JS was you was not targetting the correct HTML elements using getElementsByName.
Please read more about it here
The method getElementsByName returns, as its name indicates, a list of elements with the specified name and not just one. In your case, the names are unique to the document and the method will return a list with just one value, but you'll still need to index this list. Therefore, you must change this:
var x = document.getElementsByName("n_person").value;
to
var x = document.getElementsByName("n_person")[0].value;
Do this also for the other uses of getElementsByName and your code will work.

Categories

Resources