Decrease integer working, identical increase integer is not [duplicate] - javascript

This question already has answers here:
Why does JavaScript handle the plus and minus operators between strings and numbers differently?
(7 answers)
Closed 5 years ago.
Increase and decrease should add or subtract 0.1 to the current value. They are setup the same. For some reason decrease works (1.0 becomes 0.9, 0.8, etc.) but increase does not (1.0 becomes 1.00.1) as if it's concatenating a string.
I have tried with parseInt and parseFloat with no luck on increase new_value = current_value + 0.1 but decrease does work new_value = current_value - 0.1
I would expect both to either work on not work the way this is setup.
HTML:
<button data-direction="increase">increase</button>
<button data-direction="decrease">decrease</button>
<input value="1.0" />
JS:
$(function() {
var button = $('button');
button.click(function() {
var button = $(this);
var direction = button.data('direction');
var input = $('input');
var current_value = parseFloat( input.val() ).toFixed(1);
var new_value;
if (direction=='increase') {
new_value = current_value + 0.1;
} else {
new_value = current_value - 0.1;
}
input.val(new_value);
});
});
Fiddle:
https://jsfiddle.net/6s6w8fyd/

.toFixed(1) converts the Number into a String.
When adding a number to a string, the number is implicitly converted into a string, thus adding the '0.1' string to the end.
Subtracting doesn’t work on strings so it behaves a little differently: the string will be implicitly converted into a number.
You want to call .toFixed after adding or subtracting.

You're approach for this 'problem' is way too complex and can be brought back to very simple code. First change the values of your data-direction.
<button data-direction="1">increase</button>
<button data-direction="-1">decrease</button>
If you always follow the rule that everything that comes from the view (html) is a string and needs to be cast before any calculation takes place, then your always safe.
Your javascript becomes:
$(function() {
var button = $('button');
var curr_value = 1; // Set it to what you want your starting value to be
button.click(function() {
var button = $(this);
// direction is an integer now: 1 or -1
var direction = parseInt(button.data('direction'));
// Not 'safe' to directly parse it from the input,
// in case someone types in non numeric values.
// Do a check or - even better - make sure non-numeric values can't be
// entered.
var f = $('input');
// check here
var input = parseFloat(f); // input is a number here
// Set the new curr_value
curr_value = curr_value + (input * direction);
input.val(curr_value);
});
});
To be safe with this I would build in checks for the value that is typed in etc... But leave that up to you. Hope it helps...

$(function() {
function decimal(number, boo){
number = parseFloat(number);
return +((boo) ? (number + 0.1):(number - 0.1)).toFixed(1);
}
var input = $('input');
$('button').click(function() {
var direction = $(this).data('direction');
var inputvalue = input.val();
input.val(decimal(inputvalue, direction=="increase"));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-direction="increase">increase</button>
<button data-direction="decrease">decrease</button>
<input value="1.0" />

Related

Calculating 2 values from fields but it's not working properly

I am calculating 2 fields on a form with values but it seems in some cases it's not working. Here's my javascript. I am adding $oneTimeCostField and $recurringTotalCostField to get the value into the $totalRetailAmountField. Here's the result I am getting when I add say 1,555.00 + 566.00 = the value is 567.00 (?). Any idea what I'm doing wrong? In some cases it works correctly when the values are lower. Thanks, just stumped
var $recurringCostField = $('#am_attribute_campaign_addon_monthly_cost_value');
var $recurringTotalCostField = $('#am_attribute_campaign_addon_total_monthly_cost_value');
var $totalRetailAmountField = $('#am_oie_string_total_monthly_cost_value');
var $oneTimeCostField = $('#am_attribute_campaign_addon_one_time_cost_value');
function calcVal() {
var num1 = $oneTimeCostField.val();
var num2 = $recurringTotalCostField.val();
var result = parseFloat(num1) + parseFloat(num2);
if (!isNaN(result)) {
$totalRetailAmountField.val(result.toFixed(2));
}
}
calcVal();
$oneTimeCostField.on("keydown keyup", function() {
calcVal();
});
$recurringTotalCostField.on("keydown keyup", function() {
calcVal();
});
You need to remove the commas before parsing:
var result = parseFloat(num1.replace(/,/g, '')) + parseFloat(num2.replace(/,/g, ''));
similiar question on this link
Remove commas from the string using JavaScript
That is because parseFloat() converts the string "1,555.00" to the number 1.
To convert it to a proper floating point number, it needs to include a single dot only.
console.log(parseFloat("1.555"));

How to stop JavaScript removing the 0 from a number after the decimal point?

I am using JQuery to do some calculations on some items that a user selects. One of the items which is priced at £13.95, when 2 are selected gives £27.90. However, the result is always displayed as £27.9, the sum removes the last 0.
How can I stop the Javascript doing this? Here is the code I am using - #pucMoH contains 13.95 as a string, which is then converted to a float:
var MoHCost = parseFloat($('#pucMoH').text()).toFixed(2);
var SelectedVal = parseFloat($(this).val()).toFixed(2);
var SelectedSum = MoHCost * SelectedValInt;
The answer is in your question; toFixed(2):
var MoHCost = parseFloat($('#pucMoH').text()).toFixed(2);
var SelectedVal = parseFloat($(this).val()).toFixed(2);
var SelectedSum = (MoHCost * SelectedValInt).toFixed(2);

Why is this not a clear integer type and how to make it clear?

I have this code:
wallboard.data.Timer = function () {
$("div[data-value]").each(function () {
var time = $(this).attr("data-value");
if (time > 0) {
time += 1000;
$(this).attr("data-value", time).text(TimeToText(time));
}
});
}
The function TimeToText() simply takes a millisecond value and output it as hour:seconds (00:00).
The attribute data-value contains a millisecond value and is stores in the variable time.
This is my "debug" output:
var time = $(this).attr("data-value"); time = 4376
if (time > 0) { is true as 4376 is larger than 0
time += 1000; after this "time" is 43761000 - her it starts concatenating the text "4376" and "1000" and this is the proof that the JavaScript engine thinks time is a string type.
How do I make it clear that time should be an integer type?
var time = $(this).attr("data-value");
var timeInt = parseInt(time) + 1000;
You can use coercion trough the unary +, or just wrap it in a parseInt with a base of 10.
wallboard.data.Timer = function () {
$("div[data-value]").each(function () {
var time = parseInt($(this).attr("data-value"), 10);
if (time > 0) {
time += 1000;
$(this).attr("data-value", time).text(TimeToText(time));
}
});
}
Also, you could have searched for "javascript string to number" and you would find billions of results.
EDIT: Why not interpret numeric strings as numbers automatically? Because that would be a very unpleasant deviation from the convention: in JS you try to modify as little as possible your outputs. If you then wanted to actually concatenate two numeric strings together, you'd have to do lots of hacks to do it:
Instead of var a = "1000" + "10" to get "100010", you would have to do something like this
var a = ["1000", "zz10"].join(""); // note the "zz", so it's not plain numeric.
a = a.replace("zz", ""); // replace "zz" with nothing.
// now `a` would be "100010"
You need to convert the string retrieved with attr() into a number, e.g.
var time = +($(this).attr("data-value"));
You can use unary plus operator to convert the string attribute value to a number(you can also use parseInt())
var time = +$(this).attr("data-value");
You should convert the string to integer before adding it with 1000.
var time = parseInt($(this).attr("data-value"));

missing zero in cents on one field javascript

there is one form field that is missing the zero in the cents. the form field is total.
the others are ok ( total_t and total_tax work fine ). i have tried a few things but it either stops working or just doesnt add the zero on the end of the calculation.
example being if a product is 0.20 it shows as 0.2 and misses the zero on the end in the total field. but the tax and after tax work fine
<script>
$('document').ready(function(){
$('.input-qty').on('input', function(){
var total = 0;
var qty = $(this).val();
var price_single = $(this).parent().parent().parent().find('.input-price-single').val();
$(this).parent().parent().parent().find('.input-price-total').val(parseFloat(qty * price_single).toFixed(2));
$('.input-price-total').each(function(){
total += Number($(this).val());
});
total_t = Number(parseFloat(total).toFixed(2));
total_tax = parseFloat((total_t * 0.10) + total_t).toFixed(2);
$('.input-total').val(total_t);
$('.input-total-tax').val(total_tax);
});
});
</script>
so i guess it would be this section here:
$(this).parent().parent().parent().find('.input-price-total').val(parseFloat(qty * price_single).toFixed(2));
$('.input-price-total').each(function(){
total += Number($(this).val());
There are a few things 'wrong' with your code. (And it's all in your comment section too).
I'll try to fix them putting the answers together (but the credits really go to the people who suggested it.)
<script>
$('document').ready(function(){
$('.input-qty').on('input', function(){
var total = 0;
var qty = $(this).val();
var parent = $(this).parent().parent().parent();
var price_single = $(parent).find('.input-price-single').val();
$(parent).find('.input-price-total').val((qty * price_single).toFixed(2));
$('.input-price-total').each(function(){
total += Number($(this).val());
});
$('.input-total').val(total.toFixed(2));
$('.input-total-tax').val((total * 1.10).toFixed(2));
});
});
</script>
I don't have the corresponding HTML for this, so I can't try it on a fiddle or anything, so this is solely from the top of my head. (Untested)
Your error rests in the lines:
total_t = Number(parseFloat(total).toFixed(2));
$('.input-total').val(total_t);
In these lines, you assign the result of your total-calculation parsed to a float, parsed to a string and then cast to a number (and that's where the real problem sits).
That means, instead of assigning a string (with the correct amount of digits) to the field, you're assigning a variable of type 'number', which assumes the formatting it deems as 'right'.
Now, if you don't want to take all my corrections (after all they're quite a few and also untested), you might roll with something like:
total_t = Number(parseFloat(total));
$('.input-total').val(total_t.toFixed(2));
This should fix your problem.

Simple JS function using text inputs and parseInt, returns NaN

Can anyone help me figure out why I keep getting a NaN result?
function showShares() {
var tot = document.getElementById('total').innerHTML;
var pri = document.getElementById('price').innerHTML;
var per = document.getElementById('percent').innerHTML;
var shar = parseInt(tot, 10) * parseFloat(per) / parseFloat(pri);
document.getElementById("shares").innerHTML=Math.round(shar);
}
<td><text id="price"><%= StockQuote::Stock.quote(current_user.fund1).last %></text></td>
<td><text id="shares"></text></td>
<td><text id="percent">.50</text></td>
<p class="alignright1"><input type="text" id="total" size="8"></input>
<br><a href onclick="showShares()">here</a>
The stock quote is returning an integer in the cell ie. 25.38. it returns the same NaN if I remove the embedded ruby and place a simple integer ie. 50. The same is true if I replace the input with a number.
Thank You
Try this :
function showShares() {
var tot = document.getElementById('total').innerHTML;
var pri = document.getElementById('price').innerHTML;
var per = document.getElementById('percent').innerHTML;
var shar = parseInt(tot, 10) * parseFloat(per, 10) / parseInt(pri, 10);
document.getElementById("shares").innerHTML=Math.round(shar);
}
The percent value is a float (digit with comma) and must be interpreted by the JS engine like a float ;)
You are trying to get a value from an input element with this code,
document.getElementById('total').innerHTML
That's not the way to get the value from the input. You should use this code,
document.getElementById('total').value

Categories

Resources