Sum all html fields money values - javascript

I have a function to sum values with same ID; jsFiddle. This works, but not if is a decimal value, like a money value. (10,05 + 1.005,10, example)
$('#button-cart').on('click', function() {
var MaxSelectionNum = "7";
var sum = 0;
// Loop through all inputs with names that start
// with "option-quantity" and sum their values
$('input[name^="option-quantity"]').each(function()
{
console.log(parseInt($(this).val()));
sum += parseInt($(this).val()) || 0;
});
if (sum < MaxSelectionNum)
{
$(".errorQuantity").html("Please select 7 meals").show();
}
else
{
$(".errorQuantity").html("You have select greater than 7: meal count: " + sum).show();
}
});
How can we fix it?

Use parseFloat instead of parseInt when dealing with decimal values.
parseInt() function parses a string argument and returns an integer or NaN. If not NaN, the returned value will be the integer representation of the string passed in.
parseFloat() function parses a string argument and returns a floating point number or Nan(If the string expression cannot be converted to a numerical value).
Here is a working sample.

You must use parseFloat:
just replace your current code with the following one:
$('#button-cart').on('click', function() {
var MaxSelectionNum = "7";
var sum = 0;
// Loop through all inputs with names that start
// with "option-quantity" and sum their values
$('input[name^="option-quantity"]').each(function()
{
console.log(parseFloat($(this).val()));
sum += parseFloat($(this).val()) || 0;
});
if (sum < MaxSelectionNum)
{
$(".errorQuantity").html("Please select 7 meals").show();
}
else
{
$(".errorQuantity").html("You have select greater than 7: meal count: " + sum).show();
}
});
This gonna help you :)

I've updated your script a bit (js lines 10-16)
https://jsfiddle.net/La18Lcns/10/
If you want to use number taplate such as
1.142,32
23.456,5
1.500
First you need to conver it to float format
1142.32
23456.5
1500
Than you use parseFloat() instead ParseInt()

$('#button-cart').on('click', function()
{
var MaxSelectionNum = "7";
var sum = 0;
// Loop through all inputs with names that start
// with "option-quantity" and sum their values
$('input[name^="option-quantity"]').each(function()
{
console.log(parseFloat($(this).val()));
sum += parseFloat($(this).val()) || 0;
});
if (sum < MaxSelectionNum)
{
$(".errorQuantity").html("Please select 7 meals").show();
}
else
{
$(".errorQuantity").html("You have select greater than 7: meal count: " + sum).show();
}
});

Related

Jquery selecting text between parentheses in an array

I have an array based on selected values from multiple select boxes:
Term 03 (-1000),1 (+1000),Price (+3000),1 (+1500),--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--
Comma-separated. As you can see, some values have text in parentheses. I need to take these values in parentheses and sum them, therefore the + and - characters should remain.
Values (+1000), (+3000), (-1000) represent changes of price: + indicates the product will be more expensive, - represents the product will be cheaper. The result of this should be a number that indicates change of the price - e.g. 1500 - the product will cost more than basic price, or e.g. -3000 - the product will be cheaper.
Thanks in advance.
Tom
You have comma-separated values, with numbers in them to extract. Start by splitting the input to an array, then for each item, extract the value using regexp for example:
/\(([+-])(\d+)\)/ //will search for a sign (+/-) and a number between parenthesis
applied to an item will result in an array having the sign in second position and the number in 3rd position
/\(([+-])(\d+)\)/.exec('Term 03 (-1000)') //--> ['Term 03 (-1000)', '-', '1000']
Use reduce to sum the all with consideration to the sign:
var changes = str.split(',').reduce(function(sum, item){
var matches = /\(([+-])(\d+)\)/.exec(item);
if(matches) {
return sum + (matches[1] === '-' ? -1 : 1) * parseInt(matches[2]);
} else {
return sum;
}
}, 0));
P.S.: If you have already an array, you can remove the .split(',') part.
If you are not great with regular expressions I've made a version that does not "use" them, this way it's more readable and easier to see what's going on and how it goes about doing it. Not to say you should not use regular expressions.
For this algorithm we are basically looking through each item, checking if they have valid parentheses, then if we have + we add the value inside the parentheses, otherwise if we have - we subtract (assuming those are the only two you can have):
for(items in array) {
var firstPar = array[items].indexOf("(");
var secondPar = array[items].indexOf(")");
// Check of the item has parentheses and are like this (...)
if( (firstPar > 0 && secondPar > 0) && (secondPar > firstPar) ) {
// Get the number from the string
var value = array[items].substring(firstPar+2, secondPar);
value = parseInt(value); // To Number
if( array[items].charAt(firstPar+1) == '+')
ProductPrice += value; // If "+" add
else
ProductPrice -= value;// If "-" subtract
}
}
Example Here
Maybe something like this:
var sum = 0;
csv.replace(/\([^)]+\)/gi, function (str) { sum += parseInt(str,10); return str; }
Didn't test code. Anyway idea is to use regex to loop all parenthesis and then inside replace function, convert matched string to integer and add it to sum.
I managed to get this to work with the rather cumbersome code below. It does work with both positive and negative integers.
var result = arr.map(function (el) {
if (el.indexOf('(') > -1 && el.indexOf(')') > -1) {
return Number(el.match(/\(([\+\- 0-9]*)\)/g)[0].replace(/[\(\) ]/g , ''));
}
}).filter(function (el) {
if (typeof el !== undefined) {
return el;
}
}).reduce(function (p, c) {
return p + c;
});
DEMO
Try
var arr = "Term 03 (-1000),1 (+1000),Price (+3000),1 (+1500),--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--".split(",")
, sum = 0;
arr.map(function(v, k) {
// cast `v` value as `Number` , e.g., `[-1000, 1000, 3000, 1500]`
var n = Number(v.replace(/\w+[^\(+\d+\)]|[\(|\)]/g, "")) || null;
// add `n` Number's at `sum` , e.g., `-1000 + 1000 + 3000 + 1500` = `4500`
sum += n
});
// console.log(sum); // `4500`
var arr = "Term 03 (-1000),1 (+1000),Price (+3000),1 (+1500),--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--".split(",")
, sum = 0;
arr.map(function(v, k) {
// cast `v` value as `Number` , e.g., `[-1000, 1000, 3000, 1500]`
var n = Number(v.replace(/\w+[^\(+\d+\)]|[\(|\)]/g, "")) || null;
// add `n` Number's at `sum` , e.g., `-1000 + 1000 + 3000 + 1500` = `4500`
sum += n
});
document.write(sum) // `4500`
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

How to check if a digit is used in a number multiple times

Example: We have the number 1122. I would like to check that if given number contains the digit 1 more than once. In this case, it should return true.
I need the code to be flexible, it has to work with any number, like 3340, 5660, 4177 etc.
You can easily "force" JS to coerce any numeric value to a string, either by calling the toString method, or concatenating:
var someNum = 1122;
var oneCount = (someNum + '').split('1').length;
by concatenating a number to an empty string, the variable is coerced to a string, so you can use all the string methods you like (.match, .substring, .indexOf, ...).
In this example, I've chosen to split the string on each '1' char, count and use the length of the resulting array. If the the length > 2, than you know what you need to know.
var multipleOnes = ((someNum + '').split('1').length > 2);//returns a bool, true in this case
In response to your comment, to make it flexible - writing a simple function will do:
function multipleDigit(number, digit, moreThan)
{
moreThan = (moreThan || 1) + 1;//default more than 1 time, +1 for the length at the end
digit = (digit !== undefined ? digit : 1).toString();
return ((someNum + '').split(digit).length > moreThan);
}
multipleDigit(1123, 1);//returns true
multipleDigit(1123, 1, 2);//returns false
multipleDigit(223344,3);//returns 3 -> more than 1 3 in number.
Use javascript's match() method. Essentially, what you'd need to do is first convert the number to a string. Numbers don't have the RegExp methods. After that, match for the number 1 globally and count the results (match returns an array with all matched results).
​var number = 1100;
console.log(number.toString().match(/1/g).length);​
function find(num, tofind) {
var b = parseInt(num, 10);
var c = parseInt(tofind, 10);
var a = c.split("");
var times = 0;
for (var i = 0; i < a.length; i++) {
if (a[i] == b) {
times++;
}
}
alert(times);
}
find('2', '1122');
Convert the number to a string and iterate over it. Return true once a second digit has been found, for efficiency.
function checkDigitRepeat(number, digit) {
var i, count = 0;
i = Math.abs(number);
if(isNaN(i)) {
throw(TypeError('expected Number for number, got: ' + number));
}
number = i.toString();
i = Math.abs(digit);
if(isNaN(i)) {
throw(TypeError('expected Number for digit, got: ' + digit));
}
digit = i.toString();
if(digit > 9) {
throw(SyntaxError('expected a digit for digit, got a sequence of digits: ' + digit));
}
for(i = 0; i < number.length; i += 1) {
if(number[i] === digit) {
count += 1;
if(count >= 2) { return true; }
}
}
return false;
}
In the event that you want to check for a sequence of digits, your solution may lie in using regular expressions.
var myNum = '0011';
var isMultipleTimes = function(num) {
return !!num.toString().match(/(\d)\1/g);
}
console.log(isMultipleTimes(myNum));
JavaScript Match
Using #Aspiring Aqib's answer, I made a function that actually works properly and in the way I want.
The way it works is:
Example execution: multDig('221','2')
Split the number (first argument) to an array where each element is one digit.Output: ['2','2','1']
Run a for loop, which checks each of the array elements if they match with the digit (second argument), and increment the times variable if there is a match.Output: 2
Check inside the for loop if the match was detected already to improve performance on longer numbers like 2211111111111111
Return true if the number was found more than once, otherwise, return false.
And finally the code itself:
function multDig(number, digit){
var finalSplit = number.toString().split(''), times = 0;
for (i = 0; i < finalSplit.length; i++){
if (finalSplit[i] == digit){
times++
}
if (times > 1){
return true;
}
}
return false;
}

math.round vs parseInt

Have a quick JS question. What is the difference between math.round and parseInt?
I made a JS script to sum the inverses of prompted numbers:
<script type="text/javascript">
var numRep = prompt("How many repetitions would you like to run?");
var sum = 0;
var count = 0;
var i = 1; //variable i becomes 1
while (i <= numRep) {// repeat 5 times
var number = prompt("Please enter a non zero integer");
if(number==0){
document.write("Invalid Input <br>");
count++;
}
else{
document.write("The inverse is: " + 1/number + "<br>");
sum = sum + (1/parseInt(number)); //add number to the sum
}
i++; //increase i by 1
}
if (sum==0){
document.write("You did not enter valid input");}
else { document.write("The sum of the inverses is: " + sum); //display sum
}
</script></body></html>
and it uses parseInt. If I wanted to makeit use math.round, is there anything else I need to do so that It knows to limit the number of decimal places accordingly?
In other words, does math.round have to be formatted in a certain way?
The two functions are really quite different.
parseInt() extracts a number from a string, e.g.
parseInt('1.5')
// => 1
Math.round() rounds the number to the nearest whole number:
Math.round('1.5')
// => 2
parseInt() can get its number by removing extra text, e.g.:
parseInt('12foo')
// => 12
However, Math.round will not:
Math.round('12foo')
// => NaN
You should probably use parseFloat and Math.round since you're getting input from the user:
var number = parseFloat(prompt('Enter number:'));
var rounded = Math.round(number);
Math.round will round the number to the nearest integer. parseInt will assure you that the value is a number
So what you will need is something like this:
number = parseInt(number);
if ( isNan(number) || number == 0 ){
document.write("Invalid Input <br>");
count++;
}
This will assure you that the use has put in a number
Math.round expects a number, parseInt expects a string.
Use parseInt('12345', 10) for parsing 10-based numbers.
http://www.javascripter.net/faq/convert2.htm

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
}

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

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);

Categories