Total percentages of three input fields - javascript

I'm trying to set 100% in total on three input fields. So the idea is when the user sets 30 in one field, in the other two automatically to split numbers up to 100. So in the second field needs to be 35 and in the third one 35. Also, if any number is changed after that, the other two will be adjusted accordingly.
The number in any of those three fields can't exceed 100. I think you are getting the idea of what I'm trying to achieve.
Here is what I have tried so far (I'm not so experienced in JavaScript, but I know that this is a bad approach):
HTML:
<input class="pp-w-100 pp-range-numbers pp-first-field" type="number" name="pp-age-old-2030">
<input class="pp-w-100 pp-range-numbers pp-second-field" type="number" name="pp-age-old-3040">
<input class="pp-w-100 pp-range-numbers pp-third-field" type="number" name="pp-age-old-4050">
JS:
const firstField = document.querySelector('.pp-first-field');
const secondField = document.querySelector('.pp-second-field');
const thirdField = document.querySelector('.pp-third-field');
const totalPercentage = 100;
firstField.addEventListener('change', () => {
let intValue = parseInt(firstField.value);
if (intValue < totalPercentage) {
let getFirstValue = totalPercentage - intValue;
secondField.value = getFirstValue / 2;
thirdField.value = getFirstValue / 2;
}
});
secondField.addEventListener('change', () => {
let intValue = parseInt(firstField.value) + parseInt(secondField.value);
if (intValue < totalPercentage) {
thirdField.value = totalPercentage - intValue;
}
});
The code above is not working as expected.
Thank you.

Related

Javascript math not displaying right output [duplicate]

This question already has answers here:
How to perform an integer division, and separately get the remainder, in JavaScript?
(18 answers)
Closed 6 months ago.
I want the program to increase the number of notes when the user enters a number higher than 5 if the user enters 12 then its should say that you have 2 notes. I would also my to know if my code could be made more readable and more efficient
const box = document.getElementById('box');
const store = document.getElementById('store');
function notesChecker() {
let num = parseInt(box.value);
if (num / 5 == 0) {
store.textContent = 'You go this number of notes ' + num;
} else {
store.textContent = 'You dont have enough money for notes';
}
}
body {
text-align: center;
}
<h1>Number of notes</h1>
<p>Enter a number and it will tell you the number of notes you will get in £5 notes.</p>
<input id="box" type="number">
<button onclick="notesChecker()">Submit</button>
<div id="store"></div>
It looks like you expected the / operator to perform an integer division, but that is not the case. For example 3 / 5 is 0.6, not 0.
Secondly, you don't want to display the input number in the output message, but the number of notes, for which you need to use the integer division by 5.
Finally, if that quotient is 0, then you should display the other message ("you don't have enough..."), so you need to either swap the messages or invert the if condition.
You can use Math.floor to achieve what you want:
const box = document.getElementById('box');
const store = document.getElementById('store');
function notesChecker() {
let num = parseInt(box.value);
let notes = Math.floor(num / 5);
if (notes > 0) {
store.textContent = "You got this number of notes " + notes;
} else {
store.textContent = "You don't have enough money for notes";
}
}
body {
text-align: center;
}
<h1>Number of notes</h1>
<p>Enter a number and it will tell you the number of notes you will get in £5 notes.</p>
<input id="box" type="number">
<button onclick="notesChecker()">Submit</button>
<div id="store"></div>
const box = document.getElementById('box');
const store = document.getElementById('store');
function notesChecker(){
let num = parseInt(box.value);
if(num<5){
store.textContent ='You dont have enough money for notes';
}else{
num=parseInt(num / 5);
store.textContent='You get this number of notes '+ num ;
}
}

How do I get innerHTML to display my output? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
Improve this question
I'm fairly new to JS and I cannot figure out why my innerHTML is not displaying any output to my 4 input text fields. The ID values for all of the text fields match to the document.getElementByID values, but they aren't getting displayed.
document.getElementById('calculate').addEventListener('click', calculateCoins)
function calculateCoins (){
//converts cents value from string to Int
var cent = parseInt(document.getElementById('cents').value, 10);
/*
calculates # of quarters, displays # of quarters,
and calculates the remainder money
*/
let quarterAmount = Math.floor(cent / 25);
document.getElementById('quarters').innerHTML = quarterAmount;
let quarterRemainder = cent % 25;
/*
calculates # of dimes, displays # of dimes,
and calculates the remainder money
*/
let dimeAmount = Math.floor(quarterRemainder / 10);
document.getElementById('dimes').innerHTML = dimeAmount;
let dimeRemainder = quarterRemainder % 10;
/*
calculates # of nickels, displays # of nickels,
and calculates the remainder money
*/
let nickelAmount = Math.floor(dimeRemainder / 5);
document.getElementById('nickels').innerHTML = nickelAmount;
let nickelRemainder = dimeRemainder % 5;
/*
calculates # of pennies and displays # of pennies
*/
let pennyAmount = Math.floor(nickelRemainder / 1);
document.getElementById('pennies').innerHTML = pennyAmount;
console.log(quarterAmount);
console.log(quarterRemainder);
console.log(dimeAmount);
console.log(dimeRemainder);
console.log(nickelAmount);
console.log(nickelRemainder);
console.log(pennyAmount);
}
To update the input field use .value not .innerHTML
document.getElementById('pennies').value = pennyAmount;
For forms, you need to use the value property instead of the innerHTML property. This is because innerHTML changes the inside code of the tags, while value changes the value attribute of the input.
An example of this is below.
document.querySelector("#text").value = "I'm text!";
<input type="text" name="text" id="text" placeholder="Enter any text here..." />
Also, the value property can also be read to see the current text inputted by the user.
Extra: I also just noticed the below line from your code.
let pennyAmount = Math.floor(nickelRemainder / 1);
This code is actually not nessecary, as division by one is basically just the same number, and flooring it will not change the result.
This may be one possible solution to achieve the desired objective:
This uses document.getElementById(k).value = <<calculated value>>; rather than innerHTML.
Code Snippet
const coins = Object.fromEntries('quarters:25, dimes:10, nickels:5, pennies:1'
.split(',')
.map(ob => ob.split(':'))
.map(([k, v]) => ([k.trim(), {divisor: v, val: 0}])));
const getQR = (num, divisor) => ([
Math.floor(num / divisor), num % divisor
]);
const calculateCoins = () => {
const userInput = +document.getElementById('cents').value.toString();
coins.quarters.val = userInput;
Object.entries(coins).
forEach(([k, {divisor, val}], idx, selfArr) => {
const [d, r] = getQR(val, divisor);
document.getElementById(k).value = d;
if (idx + 1 < selfArr.length) selfArr[idx+1][1].val = r;
});
};
document.getElementById('calculate').addEventListener('click', calculateCoins)
.outer { display: flex; flex-direction: column }
input { width: fit-content; margin: 25px 5px 5px; border: 2px solid black; }
button { width: fit-content; margin: 10px; }
<div class="outer">
<input id="cents">Enter num of cents</input>
<input id="quarters" >Num of quarters</input>
<input id="dimes" >Num of dimes</input>
<input id="nickels" >Num of nickels</input>
<input id="pennies" >Num of pennies</input>
<button id="calculate">Get coins</button>
</div>
Explanation
This solution uses a coins object generated by using known information
Each coin has multiple attributes
The entries of this object are iterated in order to obtain the HTML element information required to render.
Results of the calculation are stored in val for next iteration.
Take a look at this, it worked for me
// Elements
const calculate = document.getElementById("calculate");
const centsEl = document.getElementById("cents");
const quartersEl = document.getElementById("quarters");
const dimesEl = document.getElementById("dimes");
const nickelsEl = document.getElementById("nickels");
const penniesEl = document.getElementById("pennies");
calculate.addEventListener("click", calculateCoins);
function calculateCoins() {
const cents = Number(centsEl.value);
// Quarters calc
let quarterAmount = Math.floor(cents / 25);
quartersEl.innerHTML = quarterAmount;
let quarterRemainder = cents % 25;
// Dimes calc
let dimeAmount = Math.floor(quarterRemainder / 10);
dimesEl.innerHTML = dimeAmount;
let dimeRemainder = quarterRemainder % 10;
// Nickels calc
let nickelAmount = Math.floor(dimeRemainder / 5);
nickelsEl.innerHTML = nickelAmount;
let nickelRemainder = dimeRemainder % 5;
// Pennies calc
let pennyAmount = Math.floor(nickelRemainder / 1);
penniesEl.innerHTML = pennyAmount;
}
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<input type="text" id="cents" />
<button id="calculate">Calculate</button>
<h5>Quarters</h5>
<div id="quarters"></div>
<h5>Dimes</h5>
<div id="dimes"></div>
<h5>Nickels</h5>
<div id="nickels"></div>
<h5>Pennies</h5>
<div id="pennies"></div>
</div>
<script src="src/index.js"></script>
</body>
</html>

Coin Change Algorithm JS

I have been trying to come up with a solution for this algorithm for 3-4 days but nothing seems to work and the available solutions are a bit more advanced for me. It has to be solved with conditionals only so no recursion or dynamic programming.
I need to determine the least amount of coins necessary to give change given the following denominations: 1, 0.5, 0.2, 0.1, 0.05, 0.02 and 0.01.
Input is the following:
Price of an item
Sum paid by customer
Current ideas:
let price = +gets();
let paidSum = +gets();
//gets is used to accept number input
let change = paidSum - price;
I figured I could use Math.floor to isolate the integer part and subtract it but then I have no idea what to do with the remaining sum.
Would modulo work to test whether the remaining sum contains any of the remaining values for change and then subtract again until I reach zero?
I do realize this isn't the best formulated question but I am at a loss here and I've done every other task apart from this. Thanks.
Simpler, reverse and map the denominations in cents and return a new array with the number of coins you need for each denomination.
const coinsCents = [1, 2, 5, 10, 20, 50, 100]
const getChange = (amountInCents) => {
return coinsCents.reverse().map(coin => {
let amountCoin = Math.floor(amountInCents/coin)
amountInCents -= amountCoin * coin
return amountCoin
}).reverse()
}
With the denominations you have specified, the problem is simpler than the general change making problem. In this actual case we can be sure that using the largest denomination, that is not greater than the amount to pay, always leads to an optimal solution.
So then there is no need for recursion or dynamic programming. Just a simple loop will do.
I will here ignore the additional "layer" of getting the price of the bill and the amount that the customer pays. In the end the only thing that counts is the change amount to pay back to the customer. So this snippet asks for that change amount and returns the coins that need to be given as change.
function getChange(amount) {
amount *= 100; // Convert to number of cents
var denominations = [1, 2, 5, 10, 20, 50, 100]; // cents
var result = [];
while (amount > 0) {
var coin = denominations.pop(); // Get next greatest coin
var count = Math.floor(amount/coin); // See how many times I need that coin
amount -= count * coin; // Reduce the amount with that number of coins
if (count) result.push([coin/100, count]); // Store count & coin
}
return result;
}
// I/O management
change.oninput = function () {
var coins = getChange(this.value);
result.textContent = coins.map(([coin, count]) => `${count} x $${coin}`).join(" + ");
};
To be paid to customer: <input id="change">
<div>Coins to pay: <span id="result"></span></div>
var coins;
var coinArray = {};
var output = {};
/* Method to get coin value without decimal point - it is required because
* javascript will consider 5.6 as 6 if we do Math.round()
*/
function getRoundFigureCoinValue(x) {
return (x * 10 - ((x * 10) % 10)) / 10;
}
// Method to calculate possible combination of coins
function calculateCoins(input) {
let largestPossibleCoin = 1;
if (input) {
coins.forEach((x) => {
if (input >= x) {
largestPossibleCoin = x;
}
});
let remainingCents = input % largestPossibleCoin;
output[largestPossibleCoin] = getRoundFigureCoinValue(
(input / largestPossibleCoin).toFixed(1)
);
if (remainingCents && input > 1) {
calculateCoins(remainingCents);
}
return largestPossibleCoin;
}
}
// Method to be called to get output.
function calculatePossibleCoinCombinations(value) {
if (isNaN(value) || +value <= 0) {
console.log('Invalid input');
return;
} else {
console.log('Possible combinations are:')
value = +value;
}
coins = [1, 5, 10, 25];
while (coins.length) {
let largestPossibleCoin = calculateCoins(value) || 0;
let outputString = '';
coins = coins.filter((x) => x < largestPossibleCoin);
Object.keys(output).forEach((key) => {
outputString += `${output[key]} - ${key} cents; `;
})
console.log(outputString);
output = {};
}
}
/*
Sample inputs:
calculatePossibleCoinCombinations('89');
calculatePossibleCoinCombinations(10);
calculatePossibleCoinCombinations(0);
calculatePossibleCoinCombinations('someString');
calculatePossibleCoinCombinations(-10)
*/

Taking any 2 inputs and show result in third input in JS onChange

I have a formula:
Capacity = factor * height
I have to show three inputs on the form for the (Capacity, factor, and height), the requirement is that if a user enters any two inputs the third one must be calculated.
For example, if user inputs capacity and height, factor must be calculated by
factor = capacity/height
and so on. Can anyone suggest how it can be achieved by using onChange of any input? Or is there any better way to do it?
HTML
<input id="Factor" min="0" onchange="calculate();" type="number">
<input id="Capacity" min="0" onchange="calculate();" type="number">
<input id="Height" min="0" onchange="calculate();" type="number">
JS
function calculate() {
var capacity = $("#Capacity ").val();
var height = $("#Height").val();
var factor = $("#Factor").val();
if (!capacity || !height || !factor) {
return false;
}
if (height > 0 || factor > 0) {
$("#Capacity").val(factor * height);
}
if (capacity > 0 || factor > 0) {
$("#Height").val(capacity / factor);
}
if (capacity > 0 || height > 0) {
$("#Factor").val(capacity / height);
}
};
I think the problem is still under-specified. You also need to specify how to handle cases when all 3 inputs are non-empty and the user changes one of them. For example: capacity=10, factor=5, height=2 and the user changes capacity to 101 (i.e. just adds 1 to the end). What is the expected behavior? There are a few choices.
Do nothing (i.e. wait till user clears at lest one of the fields) and probably add explicit "Clear" button
Specify re-calculation priorities (e.g. recalculate capacity unless it is the focused field in which case recalculate factor).
less obvious and more complicated: keep track in which order user focused fields and update the one that was focused least recently (or was not focused at all). I think you may come up with a few more ideas.
You may see a demo of the option #3 at JS Fiddle
The code of the solution is mostly written by #mark.hch
//to hold the order in which inputs were populated
var inputOrder = ['Factor', 'Capacity', 'Height'];
//calculation formulae
function UpdateFactor(c, h) { $('#Factor').val(c / h); }
function UpdateCapacity(f, h) { $('#Capacity').val(f * h); }
function UpdateHeight(f, c) { $('#Height').val(c / f); }
//tied to keyup, could easily be change too
$('#Factor,#Capacity,#Height').keyup(function() {
//gather our input numbers as floats
var f = parseFloat($('#Factor').val());
var c = parseFloat($('#Capacity').val());
var h = parseFloat($('#Height').val());
//get the current element's id
var id = $(this).attr('id');
//get the index in inputOrder if already present
var idx = inputOrder.indexOf(id);
//if the input already had a value, splice it from the inputOrder array
if(idx != -1) { inputOrder.splice(idx, 1); }
//add the current input id to the inputOrder array
inputOrder.push(id);
//count how many fields are currently filled out
var ct = 0;
ct += isNaN(f) ? 0 : 1;
ct += isNaN(c) ? 0 : 1;
ct += isNaN(h) ? 0 : 1;
if(ct >= 2) {
//update the least recently populated field
switch(inputOrder[0]) {
case 'Factor':
UpdateFactor(c, h);
break;
case 'Capacity':
UpdateCapacity(f, h);
break;
case 'Height':
UpdateHeight(f, c);
break;
}
}
});

Random number extractor getting weird values

I'm trying to get a random integer which is between two given values and has not been extracted yet with javascript.
To do that, I'm using the following code:
var extracted = [];
function rand(){
var from = document.getElementById('from').value;
var to = document.getElementById('to').value;
var number = Math.floor(from) + Math.floor(Math.random() * to);
var alreadyextracted = (extracted.indexOf(number) > -1);
if(alreadyextracted){
var maximum = Math.floor(to) - Math.floor(from);
var count = extracted.length;
if(count > maximum){document.getElementById('result').innerHTML='All numbers have been extracted.';}
else{rand();}
}
else{document.getElementById('result').innerHTML=number;
extracted.push(number);
if(extracted[0] == number){var content = number;}
else{var before = document.getElementById('got').innerHTML;
var content = number + ', ' + before;}
document.getElementById('got').innerHTML= content;
}
}
From: <input id="from" value="1">
To: <input id="to" value="10">
<input type="button" value="Extract" onclick="rand()">
<div id="result"></div>
<div id="desc">Already extracted numbers:</div>
<div id="got"></div>
It works fine if i put a "from" value which is lower than 10, but, if it is greater, it gets a completely random integer and randomly says that all numbers have been extracted even if it's not true.
I don't see anything in the firefox console.
What could be the problem?
You're doing it all wrong.
Fill an array with all of your range of numbers from smallest to largest.
Use a Fisher/Yates/Knuth shuffle to mix the array.
Draw out as many numbers as you need.
(No code included on purpose because I didn't fix your problem)
Spender is not wrong but the problem lies in the way you generate you random numbers:
var number = Math.floor(from) + Math.floor(Math.random() * to);
That's not the proper way to generate a number between min and max. This should be:
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Use the method proposed by spender and then pick an element in the remaining set using this function (In this case min will be 0 and max the number of remaining elements-1)

Categories