Custion javascript calculation increases 10 levels instead of increasing 1? - javascript

So I have this custom code I'm working on as a pet project, and I've been bug testing it and I thought I had finally gotten it to a point where I could clone it with other options, but apparently not? So when you give enough xp in current xp to roll over to level two, for example, level 1 requires 180 XP to roll over to level 2, and then it takes 360 for level 3, however... if I put in current existing xp is 180 and new xp gains as 0 it jumps up to level 11. I've included a picture for a visual of this error, it also does this for level 2 and I would assume all levels. Can anyone help me fix this weird error? This is the first time I've tried to code something in javascript before so I appreciate any assistance as a newbie to the language!
EDIT: As it turns out testing the code itself doesn't produce the right results either, I did fix the typo mentioned, and it still doesn't produce the right results in a normal scenario and I'm not sure why either.
Image example
https://i.imgur.com/gGNkPQY.png
The javascript itself
var xpToLevel = [180, 360, 540, 720, 900, 1080, 1260, 1440, 1620, 1800, 1980, 2160, 2340, 2520, 2700, 2880, 3060, 3240, 3420, 3600, 3780, 3960, 4140, 4320, 4500, 4680, 4860, 5040, 5220, 5400, 5580, 5760, 5940, 6120, 6300, 6480, 6660, 6840, 7020, 7200, 7380, 7560, 7740, 7920, 8100, 8280, 8460, 8640, 8820, 9000, 9180, 9360, 9540, 9720, 9900, 10080, 10260, 10440, 10620, 10800, 10980, 11160, 11340, 11520, 11700, 11880, 12060, 12240, 12420, 12600, 12780, 12960, 13140, 13320, 13500, 13680, 13860, 14040, 14220, 14400, 14580, 14760, 14940, 15120, 15300, 15480, 15660, 15840, 16020, 16200, 16380, 16560, 16740, 16920, 17100, 17280, 17460, 17640, 17820
],
xpToNext,
newXp,
currentLevel,
currentXp,
currentSpareXp,
goalLevel,
levelBaseXp,
nextLevelXp,
totalXp,
spareXp,
xpToGoal,
trainerBattle,
officialWin,
officialLoss,
wildPokemon = '<p>Enter your current level, Current XP, and new XP to add in. The new level and new remaining XP will be displayed.</p><p><b>Your Level:</b> <input class="forminput" type="number" min="1" max="100" onKeyUp="inputFullLevel(this, this.value)" id="currentLevel"><br> <b>Current XP:</b> <input class="forminput" type="number" min="0" max="17820" onKeyUp="inputSpareXp(this, this.value)" id="currentXp"><br><b>New XP:</b> <input class="forminput" type="number" min="1" max="17820" onKeyUp="inputXp(this, this.value)" id="newXp"></p><button class="forminput" type="button" onclick="runWildPokemon()">Calculate</button>';
function switchCalc() {
var c = document.getElementById("calc_select"),
calcActive = c.options[c.selectedIndex].value;
document.getElementById("calc-desc").innerHTML = eval(calcActive);
document.getElementById("calc-results").innerHTML = '';
}
function runWildPokemon(){
currentLevel = document.getElementById("currentLevel").value;
currentXp = document.getElementById("currentXp").value;
newXp = document.getElementById("newXp").value;
const cb = document.getElementById('xpShare');
const cb2 = document.getElementById('luckyEgg');
console.log(cb.checked);
xpToNext = xpToLevel[currentLevel - 1];
newTotalXp = parseInt(newXp) + parseInt(currentXp);
newTotalXp *= 0.5;
if (document.getElementById("xpShare").checked == true) {
newTotalXp *= 0.5;
}
if (document.getElementById("luckyEgg").checked == true) {
newTotalXp *= 1.5;
}
newTotalXp = Math.trunc(newTotalXp);
while(currentXp >= xpToNext) {
currentXp = currentXp - xpToNext;
currentLevel = currentLevel + 1;
xpToNext = xpToLevel[currentLevel - 1];
}
document.getElementById("calc-results").innerHTML = '<b>Level:</b> ' + currentLevel +' <b>XP:</b> ' + '[' + newTotalXp + '/' + xpToNext + ']';
}
function inputXp(field, input) {
if (input > 17820) {
field.value = 17820;
}
if (input < 0) {
field.value = 0;
}
}
function inputSpareXp(field, input) {
if (input > 17819) {
field.value = 17819;
}
if (input < 0) {
field.value = 0;
}
}
function inputFullLevel(field, input) {
if (input > 100) {
field.value = 100;
}
if (input <= 0) {
field.value = 1;
}
}
function inputLevel(field, input) {
if (input > 99) {
field.value = 99;
}
if (input <= 0) {
field.value = 1;
}
}
The HTML
<div id="calculator">
<span id="calcActive" class="wildPokemon"> <b>Select Encounter Type:</b><br> <select class="forminput" id="calc_select" onChange="switchCalc()" style="margin-bottom: 10px;text-align:center;">
<option selected="selected" value="wildPokemon">Wild Pokemon</option>
<option value="trainerBattle">Trainer/Social</option>
<option value="officialWin">Official Battle Win</option>
<option value="officialLoss">Official Battle Loss</option>
</select>
<input type="checkbox" id="xpShare" name="xpShare" value="xpShare">
<label for="xpShare"><b>XP Share</b></label>
<input type="checkbox" id="luckyEgg" name="luckyEgg" value="luckyEgg">
<label for="luckyEgg"><b>Lucky Egg</b></label><br>
</span><br>
<div id="calc-desc">
<p>Enter your current level, Current XP, and new XP to add in. The new level and new remaining XP will be displayed.</p><p><b>Your Level:</b> <input class="forminput" type="number" min="1" max="100" onKeyUp="inputFullLevel(this, this.value)" id="currentLevel"><br> <b>Current XP:</b> <input class="forminput" type="number" min="0" max="17820" onKeyUp="inputSpareXp(this, this.value)" id="currentXp"><br><b>New XP:</b> <input class="forminput" type="number" min="1" max="17820" onKeyUp="inputXp(this, this.value)" id="newXp"></p><button class="forminput" type="button" onclick="runWildPokemon()">Calculate</button>
</div><p>
</p>
<div id="calc-results">
</div>
</div>
The CSS
#calculator{
width: 300px;
background: var(--back1);
margin: auto;
padding: 10px;
border: 10px solid var(--outline);
}
#calc-desc {font-family: 'Dosis', sans-serif;}
#calc-results b{
font-family: 'Dosis', sans-serif;
font-size: 25px;
}
#calc-results {
display:flex;
justify-content: space-evenly;
font-size: 25px;}

It is simply a typo!
You search for the element with id currentLevel
currentLevel = document.getElementById("currentLevel").value;
But in your HTML it's named currentlevel
<input class="forminput" type="number" min="1" max="100" onKeyUp="inputFullLevel(this, this.value)" id="currentlevel">
JavaScript is case sensitive! Thus, you never get the current level's value for your computation.

I would suggest using a function to calculate the XP to upgrade instead of a huge array and your current incrementation method. The XP to reach level up is just 180 * current level. Therefore, calculate the XP it takes to get to a level as 90*(n^2+n).
Then just add together the XP to get to the current level, and the new XP (after the luckyEgg and xpShare stuff), and then calculate the level that the new XP corresponds to.
Something like:
currentLevel = document.getElementById("currentLevel").value;
currentLevel = parseInt(currentLevel);
currentXp = document.getElementById("currentXp").value;
newXp = document.getElementById("newXp").value;
const cb = document.getElementById('xpShare');
const cb2 = document.getElementById('luckyEgg');
const curXp = 90*((currentLevel*currentLevel)+currentLevel);
newTotalXp = parseInt(newXp) + parseInt(currentXp);
newTotalXp *= 0.5;
if (document.getElementById("xpShare").checked == true) {
newTotalXp *= 0.5;
}
if (document.getElementById("luckyEgg").checked == true) {
newTotalXp *= 1.5;
}
newTotalXp = Math.trunc(newTotalXp);
const newLevelXp = newTotalXp + curXp;
return Math.floor((((newLevelXp/90)+2) ** 0.5) - 1);

Related

Incremental of input type="number"

How to allow user to increase number in input type="number" by 10 via clicking the up down arrow, at the same time also allowing the user to enter random numbers (e.g. 33) instead of just accepting numbers like 30, 40 only?
Note: this input type="number" cannot accept negative numbers, max value is 100.
You can use min, max attribute along with step
<input type="number" step="10" min="0" max="100"/>
Updated with #Navnath Jadhav's suggestion.
You'll need a custom implementation for this.
The below adds an increment and deincrement button next to the input field and hides the default number arrows.
let deincrement = document.getElementById("deincrement");
let increment = document.getElementById("increment");
let number = document.getElementById("number");
let step = 10;
let max = 100;
let min = 0;
number.oninput = () => {
number.value = number.value>max ? max : number.value<min ? min : number.value;
};
increment.addEventListener("click", () => {
if (parseInt(number.value) + step >= max) {
number.value = max;
return;
}
number.value = parseInt(number.value) + step;
})
deincrement.addEventListener("click", () => {
if (parseInt(number.value) - step <= min) {
number.value = min;
return;
}
number.value = parseInt(number.value) - step;
})
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
<button type="button" id="deincrement">-</button>
<input type="number" value="33" id="number" min="0" max="100"/>
<button type="button" id="increment">+</button>

Javascript: Calculation of the amount when changing the value of the third input

I have three fields that are calculated: coef, cost of materials, and manufacturing cost.
First, calculate its coef * cost of materials, result in manufacturing cost input.
The calculation of the total amount is the cost of materials * manufacturing cost, but I need the ability to change the amount of Manufacturing cost and get the total result
How to do this?
My code:
function sum(el) {
let coefEl = document.getElementById('coef');
let entrPriceEl = document.getElementById('enterence_price');
let extraEl = document.getElementById('extra');
let priceEl = document.getElementById('price');
let extraresultEl;
let result;
if (el.id === "enterence_price" || el.id === "extra" || el.id === "coef") {
extraextraresultEl = parseFloat(coefEl.value) * parseFloat(entrPriceEl.value);
extraEl.value = extraextraresultEl;
result = (parseFloat(entrPriceEl.value) * parseFloat(coefEl.value) + parseFloat(extraEl.value));
if (!isNaN(result)) {
priceEl.value = result.toFixed(2);
}
} else if (el.id === "enterence_price" || el.id === "extra" || el.id === "coef") {
result = parseFloat(entrPriceEl.value) * parseFloat(extraEl.value);
if (!isNaN(result)) {
priceEl.value = result;
}
}
}
<label>Coefficient<br></label>
<input type="text" value="2" id="coef" onkeyup="sum(this);">
<br>
<label>The cost of materials<br></label>
<input type="text" value="2000" id="enterence_price" onkeyup="sum(this);">
<br>
<label>Manufacturing cost<br></label>
<input type="text" id="extra" onkeyup="sum(this);">
<br>
<label>Sum<br></label>
<input type="text" id="price" onkeyup="sum(this);">
<br>
You need to apply a different function on mf cost input, because if you will use the same function, it will never let you alter the value, because its value also getting generated from the same function you write for above 2 values
if you need something else, pls feel free to comment
let coefEl = document.getElementById('coef');
let entrPriceEl = document.getElementById('enterence_price');
let extraEl = document.getElementById('extra');
let priceEl = document.getElementById('price');
function sum(el) {
let extraresultEl;
if (el.id === "enterence_price" || el.id === "extra" || el.id === "coef") {
extraextraresultEl = parseFloat(coefEl.value) * parseFloat(entrPriceEl.value);
extraEl.value = extraextraresultEl;
result = (parseFloat(entrPriceEl.value) * parseFloat(coefEl.value) + parseFloat(extraEl.value));
if (!isNaN(result)) {
priceEl.value = result.toFixed(2);
}
} else if (el.id === "enterence_price" || el.id === "extra" || el.id === "coef") {
result = parseFloat(entrPriceEl.value) * parseFloat(extraEl.value);
if (!isNaN(result)) {
priceEl.value = result;
}
}
}
function canBeChnaged(el){
var coefVal = parseInt(coefEl.value);
var costofMatVal = parseInt(entrPriceEl.value);
var mfCostVal = parseInt(extraEl.value);
var finalSum = (coefVal * costofMatVal) + mfCostVal;
priceEl.value = finalSum.toFixed(2);
}
<label>Coefficient<br></label>
<input type="text" value="2" id="coef" onkeyup="sum(this);">
<br>
<label>The cost of materials<br></label>
<input type="text" value="2000" id="enterence_price" onkeyup="sum(this);">
<br>
<label>Manufacturing cost<br></label>
<input type="text" id="extra" onkeyup="canBeChnaged(this);">
<br>
<label>Sum<br></label>
<input type="text" id="price" onkeyup="sum(this);">
<br>
A more succinct way is to is to wrap everything into a <form> then listen for the input event. The input event will trigger a call to an event handler (in the example below it is function calc(e)) whenever the user enters data in a form control (in this case all <input>s of <form>). Use properties of HTML elements like type and step to control and validate user input. References to previously mentioned topics are located after the example below.
Details are commented in example below
// Register the <form>
const form = document.forms[0];
// Register all form controls of <form>
// In this case all <input> and <output>
const data = form.elements;
// Run function calc() if any valid user input is entered in <form>
form.oninput = calc;
// Pass the event
function calc(e) {
// Convert any valid user input of the <input>s into a real number
const c = parseFloat(data.cof.value);
const m = parseFloat(data.mat.value);
const l = parseFloat(data.lab.value);
// Reference the <output>
const s = data.sum;
// Realistic formula
const t = (c * m) + l;
// Display the value of output as the result of formula
s.value = t.toFixed(2);
}
:root,
input,
output {
font: 400 6vh/10vh Consolas;
}
label,
input,
output {
display: inline-block;
}
label {
width: 9ch;
}
input,
output {
height: 1.5ch;
width: 12ch;
text-align: right;
}
#cof {
width: 6ch;
text-align: center;
color: blue;
}
<form>
<label>Markup</label>
<input id="cof" type="number" value="2">
<br>
<label>Materials</label>
<input id='mat' type="number" value="0.00" step=".01">
<br>
<label>Labor</label>
<input id='lab' type="number" value='0.00' step=".01">
<hr>
<label>Total: </label>
<output id='sum'>0.00</output>
</form>
Reference
HTMLFormControlCollection
HTMLFormElement
<input> Element

Auto substract both values from 100

I created two input fields where they should substract from each other keeping a max value at 100.
Currently it substracted value is shown in the second value. I want it to be interchangeable. Irrespective of whether I put in first or second input field, the answer shows in the other.
Could someone help?
function updateDue() {
var total = parseInt(document.getElementById("totalval").value);
var val2 = parseInt(document.getElementById("inideposit").value);
// to make sure that they are numbers
if (!total) { total = 0; }
if (!val2) { val2 = 0; }
var ansD = document.getElementById("remainingval");
ansD.value = total - val2;
var val1 = parseInt(document.getElementById("inideposit").value);
// to make sure that they are numbers
if (!total) { total = 0; }
if (!val1) { val1 = 0; }
var ansD = document.getElementById("remainingval");
ansD.value = total - val1;
}
<input type="hidden" id="totalval" name="totalval" value="100" onchange="updateDue()">
<div>
Enter Value:
<input type="text" name="inideposit" class="form-control" id="inideposit" onchange="updateDue()">
</div>
<div>
Substracted:
<input type="text" name="remainingval" class="form-control" id="remainingval" onchange="updateDue()">
</div>
The simple way to achieve this would be to group the inputs by class and attach a single event handler to them. Then you can take the entered value from 100, and set the result to the field which was not interacted with by the user. To do that in jQuery is trivial:
$('.updatedue').on('input', function() {
var total = parseInt($('#totalval').val(), 10) || 0;
var subtracted = total - (parseInt(this.value, 10) || 0);
$('.updatedue').not(this).val(subtracted);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="hidden" id="totalval" name="totalval" value="100" />
<div>
Enter Value:
<input type="text" name="inideposit" class="updatedue form-control" id="inideposit" />
</div>
<div>
Subtracted:
<input type="text" name="remainingval" class="updatedue form-control" id="remainingval" />
</div>
You can easily validate this so that outputs < 0 and > 100 can be discounted, if required.
Edit your code as below
function updateDue(box) {
var total = parseInt(document.getElementById("totalval").value);
if(box == 1){
var val = parseInt(document.getElementById("inideposit").value);
// to make sure that they are numbers
if (!total) { total = 0; }
if (!val) { val = 0; }
var ansD = document.getElementById("remainingval");
ansD.value = total - val;
}else if(box == 2){
var val = parseInt(document.getElementById("remainingval").value);
// to make sure that they are numbers
if (!total) { total = 0; }
if (!val) { val = 0; }
var ansD = document.getElementById("inideposit");
ansD.value = total - val;
}
}
<input type="hidden" id="totalval" name="totalval" value="100" onchange="updateDue(0)">
<div>
Enter Value:
<input type="text" name="inideposit" class="form-control" id="inideposit" onchange="updateDue(1)">
</div>
<div>
Substracted:
<input type="text" name="remainingval" class="form-control" id="remainingval" onchange="updateDue(2)">
</div>

Code I have written for Burger, Coca and Salad price calculation doesn't work

I have written a code to calculate Burger, Coca and Salad price. The code should return a number (or a factor) based on the number or each ordered item. I can't figure out which part of the code is not right. it doesn't work when I change the number of items.
var BurgNum = document.getElementById('Bnum').value,
CocNum = document.getElementById('Cnum').value,
SalNum = document.getElementById('Snum').value,
Totalprice;
function getValue(n) {
return n >= 2 && n < 5 ? n * 0.9 : n == 0 ? 0 : n == 1 ? 1 : n - 1;
}
var XBurgNum = getValue(BurgNum);
var XCocNum = getValue(CocNum);
var XSalNum = getValue(SalNum);
Totalprice = XBurgNum * 10 + XCocNum * 5 + XSalNum * 4
document.getElementById('price').value = Totalprice;
<html>
How many Burgers you want to order? <input type="number" id="Bnum" value="0" onchange="getValue(n);"></input>
<br> How many Cocas you want to order? <input type="number" id="Cnum" value="0" onchange="getValue(n);"></input>
<br> How many Salads you want to order? <input type="number" id="Snum" value="0" onchange="getValue(n);"></input>
<br> Price: <input type="number" id="price" readonly="readonly"></input>
</html>
You are calling a function onchange which returns a value, but does nothing with it. Instead, your onchange function can get the values needed for the calculation and update the price accordingly.
var burg = document.getElementById('Bnum'),
coc = document.getElementById('Cnum'),
sal = document.getElementById('Snum'),
totalPrice = 0;
document.getElementById('price').value = totalPrice;
var updatePrice = function() {
var burgNum = burg.value,
cocNum = coc.value,
salNum = sal.value;
var xNums = [];
[burgNum, cocNum, salNum].forEach(function(n, i) {
xNums[i] = (n >= 2 && n < 5) ? n * 0.9 : n == 0 ? 0 : n == 1 ? 1 : n - 1;
});
totalPrice = xNums[0]*10 + xNums[1]*5 + xNums[2]*4;
document.getElementById('price').value = totalPrice;
}
How many Burgers do you want to order?
<input type="number" id="Bnum" value ="0" onchange="updatePrice()"/><br>
How many Cocas do you want to order?
<input type="number" id="Cnum" value ="0" onchange="updatePrice()"/><br>
How many Salads do you want to order?
<input type="number" id="Snum" value="0" onchange="updatePrice()"/><br>
Price:
<input type="number" id="price" readonly="readonly"/>
That is because you are not calling right statement on 'onchange' event. You just call the getVAlue(n) function which does nothing except return a value that you also use for
var XBurgNum = getValue(BurgNum);
var XCocNum = getValue(CocNum);
var XSalNum = getValue(SalNum);
But you are not updating the output on change event.
Try this, It will help you...
function getValue(val)
{
var BurgNum = parseInt(document.getElementById('Bnum').value);
var CocNum = parseInt(document.getElementById('Cnum').value);
var SalNum = parseInt(document.getElementById('Snum').value);
BurgNum = (BurgNum>=2 && BurgNum<5)?BurgNum*0.9:(BurgNum<2)?BurgNum:BurgNum-1;
CocNum = (CocNum>=2 && CocNum<5)?CocNum*0.9:(CocNum<2)?CocNum:CocNum-1;
SalNum = (SalNum>=2 && SalNum<5)?SalNum*0.9:(SalNum<2)?SalNum:SalNum-1;
Totalprice = BurgNum*10 + CocNum*5 + SalNum*4;
document.getElementById('price').value = (Totalprice>0 && Totalprice!=='NaN')?Totalprice:0;
}
<html>
How many Burgers you want to order? <input type="number" id="Bnum" value ="0" onChange="getValue(this.value);"></input>
<br>
How many Cocas you want to order? <input type="number" id="Cnum" value ="0" onChange="getValue(this.value);"></input>
<br>
How many Salads you want to order? <input type="number" id="Snum" value="0" onChange="getValue(this.value);"></input>
<br>
Price: <input id="price" readonly="readonly"></input>
</html>
Happy Coding...

Getting Cm to ft values and displaying in other element gives reference error

I have the conversion math correct(looked it up here), but getting the value from the element that displays the height in cm, then parse it to ft/inch and display it on(on click) the right hand span does not work, i get a reference error(converter not defined).
I cannot figure out why it is undefined, is it because of hoisting or can the parseInt function not have the parameters as they are?
Here is the function
var displayInches = document.getElementById("heightInches");
displayInches.addEventListener("click", function() {
toFeet(converter);
});
function toFeet(converter) {
var heightOutputCM = document.getElementById("yourHeight");
var converter = parseInt(heightOutputCM.value);
var realFeet = converter * 0.3937 / 12;
var feet = Math.floor(realFeet);
var inches = Math.round((realFeet - feet) * 12);
return feet + "and" + inches;
}
Here is the link:
https://codepen.io/damianocel/pen/ZyRogX
HTML
<h1>Alcohol blood level calculator</h1>
<fieldset>
<legend>Your Indicators</legend><br>
<label for="height" class="margin">Height:</label>
<span class="leftlabel" id=""><span id="yourHeight"></span>Cm</span>
<input type="range" id="UserInputHeight" name="height" min="0" max="200" step="1" style="width: 200px">
<span id="heightInchesSpan" class="rightlabel"><span id="heightInches"></span>Ft</span>
<br>
<label for="" class="margin">Gender:</label>
<span class="leftlabel">Male</span>
<input type="range" id="salary" name="salary" min="0" max="1" style="width: 200px">
<span class="rightlabel">Female</span>
</fieldset>
JS
// get and display height
var displayHeightInput = document.getElementById("UserInputHeight");
displayHeightInput.addEventListener("input", function() {
sliderChange(this.value);
});
function sliderChange(val) {
var heightOutput = document.getElementById("yourHeight");
heightOutput.innerHTML = val;
toFeet();
return val;
}
function toFeet() {
var heightOutputCM = document.getElementById("yourHeight");
var converter = parseInt(heightOutputCM.innerHTML);
var realFeet = converter * 0.3937 / 12;
var feet = Math.floor(realFeet);
var inches = Math.round((realFeet - feet) * 12);
document.getElementById("heightInches").innerHTML=feet + "and" + inches;
return feet + " and " + inches;
}

Categories