Calculate % discount of price. Javascript - javascript

Trying to build a Javascript %age Discount calculator for my webshop. The problem is that the calculator calculates some products wrong by 2-10%. Please help, whats wrong in the code?
<script type="text/javascript">
$(document).ready(function() {
/*
Least allowed discount to show.
*/
var minDiscount = 15;
$('.gridArticlePrices').each(function() {
/* Get ordinary price */
var oldPrice = $(this).children('.gridArticlePriceRegular').html();
/* Get sale price */
var newPrice = $(this).children('.gridArticlePrice').children('.reducedPrice').html();
if ((oldPrice) && (newPrice)) {
/* Convert to numbers instead of strings */
var oldPrice = parseInt(oldPrice.replace("/[^0-9]/g", ""));
var newPrice = parseInt(newPrice.replace("/[^0-9]/g", ""));
/* Calcuate the precentage, rounded of to 0 decimals */
var discount = Math.round(100 - ((newPrice / oldPrice) * 100));
/* If the precentage is higher than "var min Discount" then write out the discount next to the products price.*/
if (discount >= minDiscount) {
$(this).parent().after("<div class='discount'>-" + discount + "%</div>");
}
}
});
});
</script>

UPDATE:
My original suggestion to use parseFloat was assuming your prices included decimal components. As I see now, they are in fact integers, so parseInt works fine.
The actual issue is your replace() call isn't removing anything. You should remove the quotes around the regex, and then it will remove the extra characters you don't want.
var oldPrice = parseInt(oldPrice.replace(/[^0-9]/g, ""));
var newPrice = parseInt(newPrice.replace(/[^0-9]/g, ""));
Note: If you do need to handle decimal prices, you would need to add "." to you regex (so it doesn't get removed), and use parseFloat instead of parseInt.

Related

Javascript Money Calculations (Inconsistent Results)

I am currently trying to calculate fees that my service charges for sales (8%). The seller can input the amount they want to receive, or want's the buyer to pay (Like Steam does here: http://i.imgur.com/pLFN9px.png). I am currently using this code:
function precise_round(num, decimals) {
var t=Math.pow(10, decimals);
return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}
var elem = $(this);
elem.data('oldVal', elem.val());
elem.bind("propertychange change click keyup input paste", function(event){
if (elem.data('oldVal') != elem.val()) {
elem.data('oldVal', elem.val());
if(elem.attr("id")=="seller-gets") {
var cur = elem.val();
var value = cur*1.08;
$("#buyer-pays").val(precise_round(value), 2);
} else {
var cur = elem.val();
var value = cur*0.92;
$("#seller-gets").val(precise_round(value), 2);
}
}
});
});
The Receive(Left) <--> Pay(Right) conversions are not consistent. (Putting the same number the left produced back into the right gives a different left).
Sorry if this is not clear enough, I can explain it a little better if needed.
Those are inconsistent before you are doing two different things. Say for eg. lets take 5 as the left number.
8% of 5 = .4, So Right number will be 5.4
And if you put 5.4 as the right number 8% of it is .432 not .4. So the left number will be 5.4 - .432 = 4.968 and not 5.
If you want to get back the same number then you have to multiply by 1.08 for left -> right conversion and divide by 1.08 for the vice-versa.
Hope this helps.
Firstly, can you be sure that the values that are passed to the precise_round function are what you expect?
If not, then I think from looking at your code that you need to convert the raw values to float. I have had the same problem with values being one cent wrong, and converting to float fixed it.
var value = cur*1.08;
should be:
var value = parseFloat(cur)*1.08;
and
var value = cur*0.92;
should be:
var value = parseFloat(cur)*0.92;
After that, you can use value.toFixed(2) instead of rounding. Something to try anyway.

Select number then format to 2 decimal places

I am trying to write some code that will do the following;
Add an ID to nth child
Format the number in nth child to 2 decimal places
Apply £ in front of the numbers
Loop until every nth child in a table is done
I have numbers such as this to round of “0.7823076923076923” using the code I have I can get it to round up to "1" but I need it to round to 0.78 I then added “toFixed(2)” and it takes my “1” and puts it to “1.00” but I need It to go to “0.78” once I have that in place I can then look at how I can loop the code, but small steps.
Thanks for all the help.
Code:
<script>
$(document).ready(function(){
$('table>tbody>tr>td:nth-child(5n)').prop('id', 'test');
$('#test').text(function(i,v) {
return Math.round(parseInt(v * 100) / 100).toFixed(2);
});
});
</script>
UPDATE
i got it working!!!
$(document).ready(function(){
$('table>tbody>tr>td:nth-child(5n)').prop('id', 'test');
var test = parseFloat($('#test').text()).toFixed(2);
$('table>tbody>tr>td:nth-child(5n)').empty().append(test);
});
now to make it loop,
Thanks for all the help.
To round a number to n decimal places:
var n = 2;
var number = 0.7823076923076923;
var result = Math.round(number * Math.pow(10,n)) / Math.pow(10,n);
result = result.toFixed(n);
UPDATE:
For a more reusable option, you can define a custom rounding function:
function roundTo (value, n) {
var result = Math.round(value * Math.pow(10,n)) / Math.pow(10,n);
return result.toFixed(n);
}
var foo = roundTo(0.7823076923076923, 2); // 0.78

jQuery remove all characters but numbers and decimals

var price = "$23.03";
var newPrice = price.replace('$', '')
This works, but price can also be such as:
var price = "23.03 euros";
and many many other currencies.
Is there anyway that I could leave only numbers and decimal(.)?
var newPrice = price.replace(/[^0-9\.]/g, '');
No jQuery needed. You will also need to check if there is only one decimal point though, like this:
var decimalPoints = newPrice.match(/\./g);
// Annoyingly you have to check for null before trying to
// count the number of matches.
if (decimalPoints && decimalPoints.length > 1) {
// do whatever you do when input is invalid.
}
var newprice = price.replace( /\D+$/, '');

jquery event is not working properly

i have a Invoice form and a jquery function.
In Invoice if i enter the quantity greater then the available quantity then i have to alert the user.
My problem is: Let the max quantity is 5, if i input data as 7 (single digit>max avail quantity) then my code is working fine. But if i enter two digigist number eg. 17(two digists>max avail quantity) then my alert box is not coming.
I mean onkeyup my function is working only with single digit.
How can i make it happening? Please help.
$('input[name="quantity"]').keyup(function()
{
//problem is here
var $tr = $(this).closest("tr");
var unitprice = $tr.find('input[name^="unitprice"]').val();
var q = $tr.find('input[name^="quantity"]').val();
var cq = $tr.find('input[name^="checkquantity"]').val();
if(q>cq)
{
alert("Error: Quantity value exceeds then available quantity..Max Quantity is "+cq);
//this works fine only if single digit is entered in textbox quantity
}
//----below are some other stuffs -these are working fine
$tr.find('input[name^="sprice"]').val($(this).val() * unitprice);
var totalPrice = 0;
$('input[name="sprice"]').each(function()
{
totalPrice += parseFloat(this.value);
$('[name=subtotal]').val(totalPrice);
});
});
--------------
------------
// Form containing the above textboxes
<input type="submit" id="submitbtnId" value="Save"/>`
q > cq is comparing 2 strings, which is not what you want. You're trying to compare the numerical value of those strings.
Use this instead:
if ( +q > +cq)
{
// alert your error
}
Note that by prefixing the variables with the + sign, you're converting them to a number.
Better yet, convert them to a number as soon as you get the values:
var $tr = $(this).closest("tr");
var unitprice = +$tr.find('input[name^="unitprice"]').val();
var q = +$tr.find('input[name^="quantity"]').val();
var cq = +$tr.find('input[name^="checkquantity"]').val();
if ( q > cq )
{
alert("Error: Quantity value exceeds then available quantity..Max Quantity is " + cq);
}
You need to use parseInt() to ensure you are comparing integers, not strings:
if (parseInt(q, 10) > parseInt(cq, 10)) {
/* Rest of your code */
}
Your values are compared as string. If you want to compare Numbers, either use:
parseInt() or parseFloat()
or
[..].val() * 1, but this will return 'NaN' if its no digit, while parseInt() and parseFloat() will return 0

My result in my jQuery gives NaN

I am getting NaN as result and its beacuse my jquery is multiplying numbers that look like "204,3 * 3"
How can I deal with it?
I cant change the price, so what can I do?
"234 * 2" works fine as soon as the number have ',' I get NaN.
<script type="text/javascript">
$('.quantity').keyup(function () {
var parent = $(this).parent(),
price = parent.find('.price').html(),
quantity = parent.find('.quantity').val(),
result = price * quantity;
parent.find('.price2').html(result);
});
</script>
<span class="price">69,9</span>
<input type="text" class="quantity">
<span class="price2">69,9</span>
<span class="total">Total:</span>
<div class="line2"></div>
Check my JSfiddle everything is there
Any kind of help is appreciated
Javascript uses North American number formatting, which means the , is used as a thousands seperator and the . is used decimal separator.
You have two solutions to your problem:
Teach your users to enter numbers like 1000.25
Write a routine to turn 1.000,25 into 1000.25
String.prototype.replace would be your friend on the second choice.
You are multiplying two strings here and not numbers..
Convert them using parseInt with radix
OR
Convert them using parseFloat
Change this line
result = price * quantity;
TO
result = parseInt(price,10) * parseInt(quantity,10);
OR
result = parseFloat(price) * parseFloat(quantity);
You're trying to multiply strings...use the parseFloat() and a replace() method as shown in your jsFiddle update here
$('.quantity').keyup(function () {
var parent = $(this).parent(),
price = parent.find('.price').html().replace(',', '.'),
quantity = parent.find('.quantity').val().replace(',','.'),
result = parseFloat(price) * parseFloat(quantity);
parent.find('.price2').html(result);
});

Categories