Javascript: why does this produce and ugly string??? I would like currency - javascript

var total = 0;
$(".amount").each(function () {
var value = $(this).val();
value = (value.length < 1) ? 0 : value;
var tmp = parseFloat(value).toFixed(2);
total += tmp;
});
$(".total").text(total);
I am trying to loop through some text boxes and sum up their values. This produces a nasty string. What am I missing?? if I put 8 in the first textbox total text ends up as " 08.000.000.000.00". What am I doing wrong? I would like to format as currency but if not, at least just a two decimal number. Any pointers?

.toFixed converts the object from a Number to a String.
Leave the full values in place and only convert using .toFixed at the very end
$(".total").text(total.toFixed(2));
Alternatively, convert the string back to a number.
total = total + + tmp;

Just FYI, there is an excellent mathematical aggregation plugin for jQuery: jQuery Calculation
Using that plugin may also indirectly solve your issue.
It's usage would reduce your script to:
$('.total').text($('.amount').sum());

You are converting the parseFloat into a string, then adding it to total. Only add .toFixed(2) to the final line, once things have been added.
var total = 0;
$(".amount").each(function() {
var value = $(this).val();
value = (value.length < 1) ? 0 : value;
var tmp = parseFloat(value);
total += tmp;
});
$(".total").text(total).toFixed(2);

Related

thousand and decimal separate in key up event

I used below code to thousand and decimal separate in key up event. But after entering 15 digits value gets 0. what will be the reason ??
<script>
var myinput = document.getElementById('myinput');
myinput.addEventListener('keyup', function() {
var val = this.value;
val = val.replace(/[^0-9\.]/g,'');
if(val != "") {
valArr = val.split('.');
valArr[0] = (parseInt(valArr[0],10)).toLocaleString();
val = valArr.join('.');
}
this.value = val;
});
</script>
<input id="myinput" type="text'>
Problem:
The problem here is that you reached the maximum possible value for Number on parseInt() when it tries to parse the input string value, check the Number.MAX_SAFE_INTEGER MDN Reference for further details.
So all the extra digits you enter, when the number exceeds the Number.MAX_SAFE_INTEGER, will be ignored and transformed to 0. Please check Working with large integers in JavaScript tutorial for more explanation and examples.
So, you can't treat a large number value as a Number in Javsacript because there's a Maximum possible value limit, you need to treat it as a string, so it can exceed this max value.
Solution:
The solution here is to treat this number as a string and use Regex and .replace() method to change its format.
Here's a solution that I wrote before and that I always use to format numbers, it will solve your problem:
var formatNumber = function(input, fractionSeparator, thousandsSeparator, fractionSize) {
fractionSeparator = fractionSeparator || '.';
thousandsSeparator = thousandsSeparator || ',';
fractionSize = fractionSize || 3;
var output = '',
parts = [];
input = input.toString();
parts = input.split(".");
output = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator).trim();
if (parts.length > 1) {
output += fractionSeparator;
output += parts[1].substring(0, fractionSize);
}
return output;
};
Demo:
This is a working Fiddle with your original code.

js function ignores Decimal Numbers

So i made a function that calculate the price by multiplication how many meters i put the problem is when ever i put decimal numbers it ignores it
heres my script
<script>
function getFillingPrice() {
cake_prices = document.getElementById('price').value;
filling_prices = document.getElementById('test2').value;
var t=parseInt(filling_prices);
var x=parseInt(cake_prices);
return t*x;
}
function calculateTotal() {
var total = getFillingPrice();
var totalEl = document.getElementById('totalPrice');
document.getElementById('test3').value =total + " دينار ";
totalEl.style.display = 'block';
}
</script>
You're converting the values to integers when you get them from the DOM.
Change this...
var t=parseInt(filling_prices);
var x=parseInt(cake_prices);
to this...
var t=parseFloat(filling_prices);
var x=parseFloat(cake_prices);
Beside the parsing problem, you could use
an unary plus + and
a default value for non parsable value, like letters or an empty string (falsy values) with a logical OR ||.
cake_price = +document.getElementById('price').value || 0
// ^ unary plus for converting to numbner
// ^^^ default value for falsy values
Together
function getFillingPrice() {
var cake_price = +document.getElementById('price').value || 0,
filling_price = +document.getElementById('test2').value || 0;
return cake_price * filling_price;
}

Using arrays to do basic calculations with negative exponent

I'm trying to write a function which outputs the correct result when multiplying a number by a negative power of ten using arrays and split() method. For example the following expressions get the right result: 1x10^-2 = 0.01 1x10^-4 = 0.0001.
Problem comes when the number's length is superior to the exponent value (note that my code treats num as a string to split it in an array as shown in code bellow :
//var num is treated as a string to be splited inside get_results() function
//exponent is a number
//Try different values for exponent and different lengths for num to reproduce the problem
//for example var num = 1234 and var exponent = 2 will output 1.234 instead of 12.34
var num = '1';
var sign = '-';
var exponent = 2;
var op = 'x10^'+sign+exponent;
var re = get_result(num);
console.log(num+op +' = '+ re);
function get_result(thisNum) {
if (sign == '-') {
var arr = [];
var splitNum = thisNum.split('');
for (var i = 0; i <= exponent-splitNum.length; i++) {
arr.push('0');
}
for (var j = 0; j < splitNum.length; j++) {
arr.push(splitNum[j]);
}
if (exponent > 0) {
arr.splice(1, 0, '.');
}
arr.join('');
}
return arr.join('');
}
Demo here : https://jsfiddle.net/Hal_9100/c7nobmnj/
I tried different approaches to get the right results with different num lengths and exponent values, but nothing I came with worked and I came to the point where I can't think of anything else.
You can see my latest try here : https://jsfiddle.net/Hal_9100/vq1hrru5/
Any idea how I could solve this problem ?
PS: I know most of the rounding errors due to javascript floating point conversion are pretty harmless and can be fixed using toFixed(n) or by using specialized third-party librairies, but my only goal here is to get better at writing pure javascript functions.
I am not sure if you want to keep going with the array approach to a solution, but it seems like this could be solved with using the Math.pow() method that already exists.
function computeExponentExpression ( test ) {
var base;
var multiplier;
var exponent;
test.replace(/^(\d+)(x)(\d+)([^])([-]?\d+)$/, function() {
base = parseInt(arguments[1], 10);
multiplier = parseInt(arguments[3], 10);
exponent = parseInt(arguments[5], 10);
return '';
} );
console.log( base * Math.pow(multiplier, exponent));
}
computeExponentExpression('1x10^-4');
computeExponentExpression('1x10^2');
computeExponentExpression('4x5^3');
The problem is where you push the decimal point .
instead of
arr.splice(1, 0, '.');
try this:
arr.splice(-exponent, 0, '.');
See fiddle: https://jsfiddle.net/free_soul/c7nobmnj/1/

control random number with javascript

This is my intent,
Generate random number
Store in variable
Clear variable
Generate new number greater than previous
Store in variable
I understand
(Math.floor(Math.random()*100)+1)
For 1-100 but not sure how to accomplish what I want exactly.
The following will generate a random number and then find the next random number it finds that is greater than it (or equal to it if it is greater than or equal to 99):
var num = Math.floor(Math.random()*100)+1;
alert(num); //current number
var newNum;
while((newNum = Math.floor(Math.random()*100)+1) < num && newNum < 100);
alert(newNum); //new number > num (or == num if num >= 99)
use
var ran_val = 1;
// ... some code goes here
ran_val = (Math.floor(Math.random()*100) + ran_val)
if you have no upper limit on the random numbers,
ran_val = (Math.floor(Math.random()*(100-ran_val)) + ran_val)
otherwise.
fwiw, the random numbers you emulate this way are no longer uniformly distributed.
var numb1 = Math.floor(Math.random()*100)+1, //Generate random number
numb2 = 0;
while (numb2<numb1) {
numb2 = Math.floor(Math.random()*100)+2; // Generate new number greater than previous
}
FIDDLE
You need to have a global variable and a function that handles the random number generation.
You can do something like this:
var num = 1;
function generaterandom(){
num = Math.floor(Math.random()*100)+num;
}

How do I stop parseFloat() from stripping zeroes to right of decimal

I have a function that I'm using to remove unwanted characters (defined as currency symbols) from strings then return the value as a number. When returning the value, I am making the following call:
return parseFloat(x);
The problem I have is that when x == "0.00" I expect to get 0.00 (a float with two decimals) back. What I get instead is simply 0.
I've also tried the following:
return parseFloat(x).toFixed(2);
and still get simply 0 back. Am I missing something? Any help would be greatly appreciated.
Thank you!!
parseFloat() turns a string into a floating point number. This is a binary value, not a decimal representation, so the concept of the number of zeros to the right of the decimal point doesn't even apply; it all depends on how it is formatted back into a string. Regarding toFixed, I'd suggest converting the floating point number to a Number:
new Number(parseFloat(x)).toFixed(2);
this should work:
return parseFloat(x).toFixed(2);
you can test it by running this in firebug:
var x = '0.00';
alert(parseFloat(x).toFixed(2));
simple:
function decimalPlaces(float, length) {
ret = "";
str = float.toString();
array = str.split(".");
if (array.length == 2) {
ret += array[0] + ".";
for (i = 0; i < length; i++) {
if (i >= array[1].length) ret += '0';
else ret += array[1][i];
}
} else if (array.length == 1) {
ret += array[0] + ".";
for (i = 0; i < length; i++) {
ret += '0'
}
}
return ret;
}
console.log(decimalPlaces(3.123, 6));
For future readers, I had this issue as I wanted to parse the onChange value of a textField into a float, so as the user typed I could update my model.
The problem was with the decimal place and values such as 12.120 would be parsed as 12.12 so the user could never enter a value like 12.1201.
The way I solved it was to check to see if the STRING value contained a decimal place and then split the string at that decimal and then count the number of characters after the place and then format the float with that specific number of places.
To illustrate:
const hasDecimal = event.target.value.includes(".");
const decimalValue = (hasDecimal ? event.target.value.split(".") : [event.target.value, ""])[1];
const parsed = parseFloat(event.target.value).toFixed(decimalValue.length);
const value = isNaN(parsed) ? "" : parsed;
onEditValue(value);
Here is dynamic version of floatParser for those who need
function customParseFloat(number){
if(isNaN(parseFloat(number)) === false){
let toFixedLength = 0;
let str = String(number);
// You may add/remove seperator according to your needs
[".", ","].forEach(seperator=>{
let arr = str.split(seperator);
if( arr.length === 2 ){
toFixedLength = arr[1].length;
}
})
return parseFloat(str).toFixed(toFixedLength);
}
return number; // Not a number, so you may throw exception or return number itself
}

Categories