using if statements with input values jquery - javascript

I have a short script that calculates a number by multiplying input values. That script works fine but now I want to add if statements. For example:
HTML:
<label>Width</label><input type="text" id="width" />
<br>
<label>Length</label><input type="text" id="length" />
<br>
<label>Total</label><input type="text" id="total"/>
JavaScript:
var w = $('#width').val();
var l = $('#length').val();
var total1 = 2;
var total2 = 3;
if((w * l) > 5){
total = total1 * (w + l);
parseInt($('#total').val('total'));
}
if((w * l) < 5){
totalnew = total2 * (w + l);
parseInt($('#total').val(totalnew));
}
So if (#width x #length) > 5, the value of (#width x #length) would be multiplied by a certain number, in this case "2".
Tried to figure it out on jsfiddle.
Here is the code that works without the if statements: http://jsfiddle.net/e45SJ/
How can I implement what I am looking to achieve with the if statements with the code I already have?
EDIT: How can I add more than one if statement? I tried this: http://jsfiddle.net/m2LxV/2/

There are multiple problems
You need to do the calculation in a change handler which will get called when length/height is changed
You are doing a string concatenation when you do w + l because both w and l are string values
l + w is 5 then none of your if conditions are satisfied.
parseInt($('#total').val('total')) just assigns the value total to the element and the parseInt does not make any sense
You need to use a change handler
jQuery(function () {
var total1 = 2;
var total2 = 3;
$('#width, #length').change(function () {
var w = +$('#width').val();
var l = +$('#length').val();
var total;
if ((w * l) > 5) {
total = total1 * (w + l);
} else {
total = total2 * (w + l);
}
$('#total').val(total);
})
})
Demo: Fiddle

Since the question asked to use your code to make the modification thats what I did. Not much has changed here and I commented any parts that might seem difficult.
function calculate()
{
//Parse the string value into an integer
var w = parseInt($('#width').val());
var l = parseInt($('#length').val());
var total1 = 2;
var total2 = 3;
//Perform IF
//suggestion to use an If {} Else
if((w * l) > 5)
{
//Set an internal value of total
var total = total1 * (w + l);
//Update the label's value to total
$('#total').val(total);
}
if((w * l) < 5)
{
//Same logic as above
var total = total2 * (w + l);
$('#total').val(total);
}
}
//Simple button event for testing
$('button').click(function()
{
calculate();
});
http://jsfiddle.net/LLu5s/
Some things to keep in mind
This is a great case to use an IF ELSE logic block
$('#total').val('total') translates to > Select the input element and set its value the string string value of "total"
parseInt() will convert the string value to integer. So even though you selected the value from width and length its of type string. so performing (w + l) will actually result in combining the two strings together, not adding numbers.

Related

Am I using the proper predicate for my lambda?

I've been working on this program for a few hours, and I finally got it to output - NaN. I dont know how this could be, I'm pushing a product of real numbers into the array... Somebody help! What did I miss? The problem is to find the largest product produced by 13 adjacent digits within the 1000 digit number assigned to _1000digits.
// what is the largest product of 13 adjacent digits within this 1000 digit number
function largestProduct() {
_1000digits = 7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450;
separateDigits = _1000digits.toString().split("");
products = [];
var a = 0;
var b = 1;
var c = 2;
var d = 3;
var e = 4;
var f = 5;
var g = 6;
var h = 7;
var i = 8;
var j = 9;
var k = 10;
var l = 11;
var m = 12;
while (m <= 999) {
products.push(
separateDigits[a] *
separateDigits[b] *
separateDigits[c] *
separateDigits[d] *
separateDigits[e] *
separateDigits[f] *
separateDigits[g] *
separateDigits[h] *
separateDigits[i] *
separateDigits[j] *
separateDigits[k] *
separateDigits[l] *
separateDigits[m]
);
a++;
b++;
c++;
d++;
e++;
f++;
g++;
h++;
i++;
j++;
k++;
l++;
m++;
}
products.sort((a, b) => a - b);
console.log(products.pop());
}
largestProduct();
Short:
To work with such huge numbers you'll want to use a special data structure, like BigInt.
Long:
There are a few issues with your code, the first one is trying to store such a huge number in a variable without any treatment. A JavaScript number can only store values up to 25^3 - 1, your number is a lot bigger than that.
If you run:
_1000digits = 7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
console.log(_1000digits)
You'll see the output is "Infinity" because that's such a huge number JavaScript doesn't know how to store it entirely.
You're also not checking if the numbers you're accessing actually exist, so if you put a smaller number in _1000digits you'll end up multiplying by undefined, which will result in NaN:
_1000digits = 700
separateDigits = _1000digits.toString().split("")
var f = 5
console.log(separateDigits[f])

Calculating Pi in JavaScript using Gregory-Leibniz Series

I have to calculate value of Pi using Gregory-Leibniz series:
pi = 4 * ((1/1 - 1/3) + (1/5 - 1/7) + (1/9 - 1/11) + ...)
I want to write a function in JavaScript that would take the number of digits that needs to be displayed as an argument. But I'm not sure if my way of thinking is fine here.
This is what I got so far:
function pi(n) {
var pi = 0;
for (i=1; i <= n; i+2) {
pi = 4 * ((1/i) + (1/(i+2)))
}
return pi;
}
How do I write the pi calculation so it calculates values till n?
You could use an increment of 4 and multiply at the end of the function with 4.
n is not the number of digits, but the counter of the value of the series.
function pi(n) {
var v = 0;
for (i = 1; i <= n; i += 4) { // increment by 4
v += 1 / i - 1 / (i + 2); // add the value of the series
}
return 4 * v; // apply the factor at last
}
console.log(pi(1000000000));
You may also do as follows; The function will iterate 10M times and will return you PI with n significant digits after the decimal point.
function getPI(n){
var i = 1,
p = 0;
while (i < 50000000){
p += 1/i - 1/(i+2);
i += 4;
}
return +(4*p).toFixed(n);
}
var myPI = getPI(10);
console.log("myPI #n:100M:", myPI);
console.log("Math.PI :", Math.PI);
console.log("The Diff :", Math.PI-myPI);

JavaScript function "X - Y = Z" returns Y as Z value

I'm trying to apply a discount to a selection in JavaScript, but for some reason, my code is returning the total to subtract as the total price:
selectone = parseInt(selectone);
var textarea = document.getElementById('discount');
var word = '15off';
var textValue=textarea.value;
if (textValue.indexOf(word)!=-1)
{
var discval = parseFloat(selectone);
var num = parseInt(discval);
var retval = num - (num * .15);
} else {
var retval = 0
}
var total = selectone - retval;
document.getElementById("rettotal").innerHTML = "Price starts from £" + total;
}
For example, if something costs £100 and a 15% discount is applied, the total will be '£15' instead of '£100' ('retval' instead of 'total')
Is there something I've missed in this, or is something missing?
I've not done maths in JavaScript much so a bit over my head!
Many thanks
You've logic problem in math part.
You want to get amount after discount.
You're doing it:
var retval = num - (num * .15); // 100 - (100 * .15) = 85
But after You're removing discount from amount:
var total = selectone - retval; // 100 - 85 = 15
So here is the fix:
var price = parseFloat(selectone);
var discount = (textValue.indexOf('15off') != -1)?
price * .15
: 0;
var total = price - discount; // 100 - 15 = 85
or just be simple (if discount applies once):
var total = parseFloat(selectone);
if(textValue.indexOf('15off') != -1) {
total *= .85;
}
let's be flexible (applying multiple discounts to price):
var textValue = 'take this 15off and this 10off';
var price = parseFloat(1000);
var total = price;
total-= (textValue.indexOf('15off') != -1)?
price * .15
: 0;
console.log(total);
total-= (textValue.indexOf('10off') != -1)?
price * .15
: 0;
console.log(total);
Because... math.
selectone = parseInt(selectone);
...
var discval = parseFloat(selectone); // doesn't change the things, it's an int already
var num = parseInt(discval); // so num is essentially discval, which is selectone
var retval = num - (num * .15); // here you get 85% of num...
...
var total = selectone - retval; // here you get 15% back
The fix is to remove num - from retval, so as var retval = num * .15;
The code you've shown could be compressed to this:
var textarea = document.getElementById('discount');
var total = parseFloat(selectone)*(1-0.15*textarea.value.includes("15off"));
document.getElementById("rettotal").innerHTML = "Price starts from £" + total;
Or, if you have problems with includes() not being supported by your browser (in case it's IE), you could also use match():
var total = parseFloat(selectone)*(1-0.15*(textarea.value.match("15off")|0));
You have a JavaScript operator precedence and meaning problem there. That's syntax mistake on your part.
In an expression like this:
x - y = z
You are thinking that:
z = x - y //but it's not.
What you are really saying is:
y = z and x = x - z

JavaScript calculating wrong percentage in two inputs

I have the following inputs:
cost, where I type in a currency value, like 6,23, profit, where I type in a percentage value like 29,21 and value where the sum of the both values is show.
JavaScript does the math and returns me in value the value from cost + the currency value of the percentage typed in profit, in which case the result is 8,05 (6,23 + 29,21%).
But if try to do the same, but informing the value instead of profit, as the same 8,05, so JavaScript would return me the profit of 29,21, but it returns me 36,44.
Does anyone know what it can be?
Here is my code:
$(document).ready(function () {
$(".valor").on("input", function () {
// Margem
var valor = $(this).val();
var valorCorrigido = parseFloat(adicionarPontos(valor));
var valorFloat = parseFloat(valorCorrigido) || 0.0;
// Custo
var valorCusto = $('#custo').val();
var valorCustoCorrigido = parseFloat(removerPontos(valorCusto));
var valorCustoFloat = parseFloat(valorCustoCorrigido) || 0.0;
// Calculo
var calculo = (parseFloat(valorFloat) - parseFloat(valorCustoFloat)) / parseFloat(valorCustoFloat) * 100;
var inputMargem = $(this).attr("margem");
$("#" + inputMargem).val(calculo.toFixed(2)).trigger('blur');
});
// Faz o calculo do valor com base na margem
$(".margem").on("input", function () {
// Margem
var valorMargem = $(this).val();
var valorMargemCorrigido = parseFloat(adicionarPontos(valorMargem));
var valorMargemFloat = parseFloat(valorMargemCorrigido) || 0.0;
// Custo
var valorCusto = $('#custo').val();
var valorCustoCorrigido = parseFloat(removerPontos(valorCusto));
var valorCustoFloat = parseFloat(valorCustoCorrigido) || 0.0;
// Cálculo
var calculo = (parseFloat(valorCustoFloat) * parseFloat(valorMargemFloat) / 100) + parseFloat(valorCustoFloat);
var inputValor = $(this).attr("valor");
var resultadoMonetario = calculo.toFixed(2).toString();
resultadoMonetario = resultadoMonetario.replace(".", ",");
$("#" + inputValor).val(resultadoMonetario).trigger('blur');
});
function removerPontos(valor){
valor = valor.replace(".","");
valor = valor.replace(",",".");
return valor;
}
function adicionarPontos(valor){
if(valor.length == 1){
return valor;
}
else{
if(valor.length == 2){
return valor;
}
else{
// The problem was here
valor = valor.replace(",","");
var inteiro = valor.substring(0,valor.length - 2);
var decimal = valor.substr(2);
return inteiro + "." + decimal;
}
}
}
});
$('input').mask('00.000.000,00', {
reverse: true
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.13.4/jquery.mask.js"></script>
Custo:
<input type='text' id='custo' class='custo valores' name='custo'>
<br>
<br> Valor:
<input type='text' id='valor1' class='valor valores' name='valor1' margem='margem1'> Margem:
<input type='text' id='margem1' class='margem valores' name='margem1' valor="valor1">
<br> Valor:
<input type='text' id='valor2' class='valor valores' name='valor2' margem='margem2'> Margem:
<input type='text' id='margem2' class='margem valores' name='margem2' valor="valor2">
The calculations appear to be incorrect because decimal separators in JavaScript are not localized.
6,23 * 29,21 // 21
6.23 * 29.21 // 181.97830000000002
parseFloat(6,23); // 6
parseFloat(6.23); // 6.23
You can use Number.prototype.toLocaleString() or a currency formatting plugin to format the values for display, but your custo, valor, and margem values should be formatted with a . decimal separator when you do your calculations.
If your total profit equation is total = cost + (cost * profit).
Then your profit % equation should be profit = (total - cost) / cost.
Here are two functions that provide you with what you need. You might be interested to use them instead of calculating in line like how you do in your question.
function getProfitTotal(cost, profit) {
cost = parseFloat(cost, 10);
profit = parseFloat(profit, 10) / 100;
return cost + (cost * profit);
}
function getProfitMargin(cost, total) {
cost = parseFloat(cost, 10);
total = parseFloat(total, 10);
return (total - cost) / cost * 100;
}
Thus getProfitMargin(6.23, getProfitTotal(6.23, 21.23) ); will output 21.23. Just use .toFixed(2) before setting the value in your text field.
On a side note, you should only reset your field's value if the value is NaN. As of now, I am personally unable to write decimals in the example you provided because of this.
Also, all numbers have to be dot-separated. Just parse and format your numbers with a globalization library, as your current functions are not working correctly as described earlier.
So seems that the problem was in this part of the code:
valor = valor.replace(",","");
var inteiro = valor.substring(0,valor.length - 2);
var decimal = valor.substr(2);
return inteiro + "." + decimal;
After changing it to this worked fine:
var inteiro = valor.substring(0,valor.length - 2);
var decimal = valor.substring(valor.length - 2, valor.length);

Creating a slider between two numbers

So I've been working on re-producing the slider found here https://www.skylight.io/ ( Scroll down to find the price slider ).
So far Ive managed to create something similiar, but some numbers are hard coded, making it difficult to change and not very re-usable.
I've been researching around and I think I need to use Math.log() and Math.exp() together to achieve something like in the link above but I'm not sure.
Heres a jsfiddle of what I have so far https://jsfiddle.net/7wrvpb34/.
I feel that its the maths part of this problem that is halting me I think, so any help would be greatly appreciated.
Javascript code below:
var slider = document.getElementById("slider")
var sliderFill = document.getElementById("slider-fill")
var knob = document.getElementById("knob")
var mouseDown;
var mousePos = {x:0};
var knobPosition;
var minPrice = 20;
var price = 0;
var minRequests = 50;
var requests = 50 + ",000";
var incrementSpeed = 2;
var incrementModifier = 20;
var incrementValue = 1;
var minMillionCount = 1;
var millionCount = 1;
var previousRequestAmount = 0;
document.getElementById("price").innerHTML = price;
document.getElementById("requests").innerHTML = requests;
highlightTable(1);
document.addEventListener('mousemove', function(e) {
if(mouseDown) {
updateSlider(e);
}
})
function updateSlider(event) {
mousePos.x = event.clientX - slider.getBoundingClientRect().left;
mousePos.x -= knob.offsetWidth / 2;
console.log(mousePos.x);
if(mousePos.x < 0) {
knob.style.left = "0px";
sliderFill.style.width = "0px";
price = 0;
requests = 50 + ",000";
document.getElementById("price").innerHTML = price;
document.getElementById("requests").innerHTML = requests;
return
}
if(mousePos.x > slider.offsetWidth - 20) {
return
}
sliderFill.style.width = mousePos.x + 10 + "px";
knob.style.left = mousePos.x + "px";
//Increase requests by using X position of mouse
incrementSpeed = mousePos.x / incrementModifier;
requests = minRequests + (mousePos.x * incrementSpeed);
//Round to nearest 1
requests = Math.round(requests / incrementValue) * incrementValue;
if (requests >= 1000){
var m = requests/ 1000;
m = Math.round(m / 1) * 1;
//Problem, lower the modifier depending on requests
incrementModifier = 20 * 0.95;
document.getElementById("requests").innerHTML = m + " million";
//Adjust Prices
if(( requests >= 1000) && (requests < 10000)) {
var numOfMillions = requests / 100;
//Round to closest 10.
//10 * number of millions
var rounded = Math.round(numOfMillions / 10) * 10;
price = minPrice + rounded;
highlightTable(3);
}
//Adjust Prices
if(requests >= 10000) {
var numOfMillions = requests / 1000;
var rounded = Math.round(numOfMillions / 1) * 1;
var basePrice = minPrice * 6;
price = basePrice + rounded;
highlightTable(4);
}
} else {
incrementModifier = 20;
document.getElementById("requests").innerHTML = requests + ",000"
if(requests < 100) {
highlightTable(1);
price = 0;
} else {
highlightTable(2);
price = 20;
}
}
previousRequestAmount = requests;
document.getElementById("price").innerHTML = price;
}
knob.addEventListener('mousedown', function() {
mouseDown = true;
});
document.addEventListener('mouseup', function() {
mouseDown = false;
});
function highlightTable(rowNum) {
var table = document.getElementById("payment-table")
for(var i = 0; i < table.rows.length; ++i) {
var row = table.rows[i]
if(i == rowNum) {
row.style.background = "grey"
} else {
row.style.background = "white";
}
}
}
Thank you for your time.
If you want it to be reusable you need to create a mathematical function that assigns a result to the number of requests. I will give you a very easy example.
If you want a different result for 1,10,100,100,10000 etc
var d = Math.log10(requests);
if(d<1){
doSomething();
}else if(d<2){
doSomethingElse();
} //etc
This way if you want to change the specific values that create certain results, all you need to do is change the function.
This only works if your tiers of requests follow a math function, if they don't you need to hard code it.
However if say they don't follow a math function, but you know how you would like them to change based on a value then you can do this.
var changingValue = 4;
if(requests < 400*changingValue){
doSomthing();
}else if(requests <= 400*changingValue*changingValue){
doSomethingElse();
}else{// the requests is greater than any of the above
doTheOtherThing();
}
Edit:
For the second one you need to make sure that each condition if always larger than the other from top to bottom.
The description "increasingly increasing" matches an arbitrary number of functions. I assume you also want it to be continuous, since you already have a non-continuous solution.
TL;DR
Use an exponential function.
Generic approach
Assuming imin and imax are the minimal and maximal values of the slider (i for input) and omin and omax are the minimal and maximal values to be displayed, the simplest thing I can think of would be a multiplication by something based on the input value:
f(x)
{
return omin + (omax - omin) * g((x - imin) / (imax - imin));
}
This will pass 0 to g if x == imin and 1 if x == imax.
The return value r of g(y) should be
r == 0 for y == 0
r == 1 for y == 1
0 < r < y for 0 < y < 1
The simplest function that I can think of that fulfills this is an exponential function with exponent > 1.
An exponent of 1 would be a linear function.
An exponent of 2 would be make the middle of the slider display one fourth of the maximum price instead of half of it.
But you really need to find that exponent yourself, based on your needs.

Categories

Resources