Javascript String indexOf not working as expected - javascript

I must be missing something .. not sure why my JavaScript is failing or not working
var discount = 10;
var newTemp;
if (discount != null) {
if (discount.indexOf("%") > -1) {
newTemp = discount.substring(0, 2) + '%';
} else {
newTemp = discount;
}
} //end of outer if
Above script works when discount = "10.0%"
But fails when discount = 10
maynot be best way, but all I am trying to do is if discount value contains % sign then setting newTemp variable with new value. Else just keep it as is.
Any idea, why control fails when discount value is = 10

because "10%" is a string, therefore it has a indexOf method, and 10 is probably an integer or number.
Try discount.toString().indexOf('%')

It's because you're not appending the '%' in the else branch.
var newTemp;
if (discount != null) {
if (discount.indexOf("%") > -1) {
newTemp = discount.substring(0, 2);
} else {
newTemp = discount;
}
} //end of outer if
newTemp += '%';
also as Hugo said, the number 10 does not have the indexOf method, which is a string method.

Related

Why does if statement not work and make my element disappear using display: none?

I am building a tip calculator and I couldn't make the if statement in my function work it just skips to calculating.
function calculate() {
var bill = parseInt(document.getElementById("bill").value);
var tip = parseInt(document.getElementById("tip").value) * .01;
var persons = parseInt(document.getElementById("persons").value);
if (bill == "" || tip == "") {
alert("Please enter value");
return;
};
if (persons == "" || persons <= 1) {
persons = 1;
document.getElementById("perPerson").style.display = "none";
} else {
}
let totalTipPer = (bill * tip) / persons;
let totalPer = (bill + (tip * 100)) / persons;
let totalTip = bill * tip;
let total = bill + (tip * 100);
totalTipPer = totalTipPer.toFixed(2);
totalPer = totalPer.toFixed(2);
total = total.toFixed(2);
totalTip = totalTip.toFixed(2);
document.getElementById("total-tip/person").innerHTML = totalTipPer;
document.getElementById("total-price/person").innerHTML = totalPer;
document.getElementById("total-tip").innerHTML = totalTip;
document.getElementById("total-price").innerHTML = total;
}
document.getElementById("calculate").onclick = function () {
calculate();
document.getElementById('results').style.display = 'block';
}
I expect the div encapsulating Tip Amount per person and total per person and to not appear when the input value of persons is empty.
Function parseInt returns 'An integer number parsed from the given string. If the first character cannot be converted to a number, NaN is returned.'
if you rpovide an empty value ('') it will return
NaN which is not equal to anything, even itself.
there are several ways to fix this:
check if it is a NaN with Number.isNaN(var)
use an intermediate value like var personsValue and check if it is equal to empty string ''.
use Hybrid suggested solution and assign a 0
value for falsy value('', undefined, n
ull etc...)
The issue is that persons becomes NaN, since if the value is left blank, "" becomes NaN when it is run through parseInt().
The way to fix this is by defaulting it to 0 if the field is left blank.
var persons = parseInt(document.getElementById("persons").value || 0);
as others pointed out parseInt is returning NaN if the field is blank, but this will also happen if the user inputs $5.00 for example.
Here's one way to make sure the value can be converted to a number before doing so.
// This function determines if a JavaScript String can be converted into a number
function is_numeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function calculate() {
// first put the input values into separate variables
billValue = document.getElementById("bill").value;
tipValue = document.getElementById("tip").value;
personsValue = document.getElementById("persons").value;
// use the is_numeric() function above to check if the values can be converted to numeric
if (!is_numeric(billValue) || !is_numeric(tipValue)) {
alert("Please enter values for bill and tip");
return;
}
// the rest of your code here
}
Hope this helps.

Javascript restrict input once 2 decimal places have been reached

I currently have a number input script that behaves similar to a calculator with the way numbers are displayed, but I want to stop the adding of additional numbers to the series after two numbers past the decimal point.
Here is what I have so far, though the limiting doesn't occur correctly.
It should work like this:
1.25 - Allowed
12.5 - Allowed
125.5 - Allowed
125.55 - Allowed
123.555 - Not Allowed
rText = document.getElementById("resultText");
function selectNumber(num) {
if (!rText.value || rText.value == "0") {
rText.value = num;
}
else {
this part works...
rText.value += num;
}
}
}
but this part doesn't work... Any ideas???
if (rText.value.length - (rText.value.indexOf(".") + 1) > 2) {
return false;
} else {
rText.value += num;
}
}
}
var validate = function(e) {
var t = e.value;
e.value = (t.indexOf(".") >= 0) ? (t.substr(0, t.indexOf(".")) + t.substr(t.indexOf("."), 3)) : t;
}
<input type="text" id="resultText" oninput="validate(this)" />
Save the previous value in some data attribute and if it exceeds 2 decimal places then restore the previous value
The 2 decimal places can be checked using Math.round(tis.value*100)/100!=tis.value
Note:
I have used oninputto validate even in copy paste scenarios
function restrict(tis) {
var prev = tis.getAttribute("data-prev");
prev = (prev != '') ? prev : '';
if (Math.round(tis.value*100)/100!=tis.value)
tis.value=prev;
tis.setAttribute("data-prev",tis.value)
}
<input type="number" id="rText" oninput="restrict(this);" />
I love to use Math.floor and toFixed() to resolve my decimal issues.
Here is a example:
var value = 123.5555
var roundedNumber = (Math.floor(value * 100) / 100).toFixed(2)
roundedNumber will be "123.55" as a string. So if you want as a number just add:
var value = 123.5555
var roundedNumber = Number((Math.floor(value * 100) / 100).toFixed(2))
and now you have value as a number and fixed to up 2 decimal places.
Just copy paste this method and call this method on your respective button on which button you have to check this decimal validation.
function CheckDecimal(inputtxt)
{
var decimal= /^[-+]?[0-9]+\.[0-9]+$/;
if(inputtxt.value.match(decimal))
{
alert('Correct, try another...')
return true;
}
else
{
alert('Wrong...!')
return false;
}
}

JS calculation issue

I have a simple vat calculator, but there is something funny with one of the calculation. The problem is in the last column, saying moms. e=a + d * 0.25 is correct, but the code below is not. It shows a too big number when calculating.
JS Code:
$(document).ready(function() {
$('#submit').click(function() {
//get cost and check value
var cost = $('#cost').val();
var check = $('#checkBox');
if (cost != null && cost != "") {
if (cost < 350) {
//c = a * 1
$('#total').val(cost);
$('#toll').val("");
$('#moms').val("");
} else {
if (check.is(':checked')) {
//c = a* 1.107* 1.25
$('#total').val((cost * 1.107 * 1.25).toFixed(2));
//d = a * 0.107
$('#toll').val((cost * 0.107).toFixed(2));
} else {
$('#total').val((cost * 1.25).toFixed(2));
$('#toll').val("");
$('#moms').val("");
}
if ($('#toll').val() != null && $('#toll').val() != "") {
//e = (a + d) * 0.25
var moms = (cost + $('#toll').val()) * 0.25;
$('#moms').val(moms.toFixed(2));
}
}
}
})
});
The value of input elements will always be a string. In most of your code, you're using the "cost" value in such a way that it will be implicitly converted to a number. However, the + operator is different, and will preferentially perform string concatenation to addition.
If you explicitly force the cost to be a number when you initialize it, things should work better:
var cost = +$('#cost').val();
That leading unary + operator will force the string value to be treated as a number. Now, of course, if the string doesn't look like a good number, then cost will be set to NaN, so you should check for that:
if (!isNaN(cost)) {
That can replace your current check to see if cost is not empty.
edit Sorry, you'll also need to convert the value of $('#toll').val() so that line would look like:
var moms = (cost + +$('#toll').val()) * 0.25;
The JavaScript + operator really likes strings.

JS Variable is outputting as isNaN when I need a number

Here is the assignment so it's clear what I'm trying to do.
Write a program that calculates the price of a hotel room based on three factors. First, how many will be in one room: 1-2, 3-4, or 5-6? No more than six are allowed in a room. Second, are the guests members of AAA? Third, do they want a room with a view? The rate is calculated as follows:
Basic room rate is:
1-2 people = $50/night
3-4 people = $60/night
5-6 people = $70/night
There is a discount for AAA members off of the basic room rate per night:
1-2 people = 15%
3-4 people = 10%
5-6 people = 5%
A room with a view costs 10% more per night after all other calculations are performed.
The program should prompt the user for all the inputs, perform the calculations and output the total cost per night. It is suggested to use at least some nested if/else structures to calculate the cost.
Debuggers like firebug and JSLint haven't been any help and I suspect I'm just doing something completely wrong, though I haven't had trouble with "nested if" logic assignments before. Regardless I am a complete and utter newby.
When I test by inputting 1 for numberOfGuests, N for tripleAStatus, and N for roomView, finalRate is returning as isNaN (I know this means not a number), and I can't figure out why.
//Variable Declaration
var numberOfPeople;
var tripleAStatus;
var roomView;
var discountRate;
var roomRate;
var finalRate;
var discountPercent;
//Input
numberOfPeople = prompt("How many guests will their be? 6 Maximum.");
tripleAStatus = prompt("Are you a AAA Member? Y/N.");
roomView = prompt("Would you like your room to have a view?");
//Logic
if ((numberOfPeople <= 2) && (numberOfPeople > 0)) {
roomRate = 50;
discountPercent = .15;
} else if ((numberOfPeople <= 4) && (numberOfPeople > 2)) {
roomRate = 60;
discountPercent = .10;
} else if ((numberOfPeople <= 5) && (numberOfPeople > 4)) {
roomRate = 70;
discountPercent = .5;
} else {
alert("Your number of guests must be at least 1 and no more than 6");
}
if (tripleAStatus = "Y") {
discountRate = roomRate - (roomRate * discountRate);
} else if (tripleAStatus = "N") {
discountRate = roomRate;
} else {
alert("You need to answer with either Y or N");
}
if (roomView = "Y") {
finalRate = (discountRate) + ((discountRate) * .10);
} else if (roomView = "N") {
finalRate = discountRate;
} else {
alert("You need to answer with either Y or N");
}
//Output
document.write("Total cost per night is " + "$" + finalRate);
It looks like
discountRate = roomRate - (roomRate * discountRate);
Should read
discountRate = roomRate - (roomRate * discountPercent);
Which is why you're getting NaN in finalRate; discountRate hasn't been defined at this point, so your code actually reads discountRate = 1 - (1 * undefined).
As other posters have mentioned, you also need to change your conditionals to use == or ===; = is an assignment operator, so rather than checking if tripleAStatus is "Y", you're actually checking if "Y" evaluates to true (which it always will).
tripleAStatus = 'N';
if (tripleAStatus = 'Y') {
// tripleAStatus is now "Y", and the code inside this if will always be executed
}
Working changes: http://jsfiddle.net/5ZVkE/
In your If statements, you are assigning values by using single "=". Since the assignment always occurs, it will return true. In order to compare values, you need to use double "==" in the if statement. like this:
if (tripleAStatus == "Y") {
discountRate = roomRate - (roomRate * discountRate);
} else if (tripleAStatus == "N") {
discountRate = roomRate;
} else {
alert("You need to answer with either Y or N");
}
Replace the single '=' in your 'if' statements with '=='. You're currently using assignment operators instead of equality.
e.g.:
if (tripleAStatus == "Y") ...
You are using assignments instead of equality operators in your if statements. i.e. change
if (tripleAStatus = "Y")
to
if (tripleAStatus == "Y")
Please use ===!! this way, the type in the statement isn't casted and therefor more strictly checked if its the same type.
if (tripleAStatus === "Y") {
discountRate = roomRate - roomRate * discountRate;
} else if (tripleAStatus === "N") {
discountRate = roomRate;
}
/e -> & its faster!
prompt() returns a STRING not a NUMBER.
Use parseInt() with numberOfPeople.
And the other problem, you copied and pasted the wrong variable names in your formulas. Look at how you are using discountRate instead of discountPercent.

javascript format price

I wish to format a variable to a price format where if it is for example $90 then leave out the decimal which it already does anyway. But if the value is $44.5 then I want to format it as $44.50. I can do it in php not javascript.
PHP example:
number_format($price, !($price == (int)$price) * 2);
The code I want to format:
$(showdiv+' .calc_price span').html(sum_price);
var price = 44.5;
var dplaces = price == parseInt(price, 10) ? 0 : 2;
price = '$' + price.toFixed(dplaces);
PHPJS has that code for you: http://phpjs.org/functions/money_format:876
Also provided by #Daok How can I format numbers as money in JavaScript?
Try this
function priceFormatter(price)
{
//Checks if price is an integer
if(price == parseInt(price))
{
return "$" + price;
}
//Checks if price has only 1 decimal
else if(Math.round(price*10)/10 == price)
{
return "$" + price + "0";
}
//Covers other cases
else
{
return "$" + Math.round(price*100)/100;
}
}

Categories

Resources