I have three input numbers:
<input min="0" name="cat1" step="1" type="number" max="50" value="0" />
<input min="0" name="cat2" step="1" type="number" max="50" value="0" />
<input min="0" name="cat3" step="1" type="number" max="50" value="0" />
Currently the max value is 50. I would like the max for all three together to be 50 aswell.
How can I solve this with javascript or jquery?
This method sums the other inputs, and if the sum + the current value is greater than max, it changes the current input's value to fit max.
For example, try entering 30, 5, 20 to the input boxes.
var max = 50;
var $inputs = $('input');
function sumInputs($inputs) {
var sum = 0;
$inputs.each(function() {
sum += parseInt($(this).val(), 0);
});
return sum;
}
$inputs.on('input', function(e) {
var $this = $(this);
var sum = sumInputs($inputs.not(function(i, el) {
return el === e.target;
}));
var value = parseInt($this.val(), 10) || 0;
if(sum + value > max) $this.val(max - sum);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input min="0" name="cat1" step="1" type="number" max="50" value="0" />
<input min="0" name="cat2" step="1" type="number" max="50" value="0" />
<input min="0" name="cat3" step="1" type="number" max="50" value="0" />
Hope you expected this way.
Try Using this code.
it will check the aggregate of three fields and check it whether it is greater than 50.
$(":input").bind('keyup mouseup', function () {
var cat1=$("#cat1").val();
var cat2=$("#cat2").val();
var cat3=$("#cat3").val();
var total=parseInt(cat1) + parseInt(cat2) + parseInt(cat3);
if(total>50) {
alert("it exceeds 50");
return false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input min="0" id="cat1" name="cat1" step="1" type="number" max="50" value="0" />
<input min="0" id="cat2" name="cat2" step="1" type="number" max="50" value="0" />
<input min="0" id="cat3" name="cat3" step="1" type="number" max="50" value="0" />
This will ensure the sum doesn't exceed 50. In case the new value makes the total exceed the limit, the other two will be lowered equally to enforce the total=50 rule.
Note the
let share2 = Math.min(Math.floor(excessValue / 2), elmt2Value) which ensures
To ensure we won't remove more from one of the input than its value.
<input min="0" name="cat1" id="cat1" step="1" type="number" max="50" value="0" onchange="valueChanged('cat1')" />
<input min="0" name="cat2" id="cat2" step="1" type="number" max="50" value="0" onchange="valueChanged('cat2')" />
<input min="0" name="cat3" id="cat3" step="1" type="number" max="50" value="0" onchange="valueChanged('cat3')" />
<script>
function valueChanged(changedElmtId) {
// Retrieve all input, the one changed and the other 2
let elmt2Id = "cat2", elmt3Id = "cat3"
if ( changedElmtId === elmt2Id ) {
elmt2Id = "cat1"
}
else if ( changedElmtId === elmt3Id ) {
elmt3Id = "cat1"
}
let changedElmt = document.querySelector("#" + changedElmtId)
let elmt2 = document.querySelector("#" + elmt2Id)
let elmt3 = document.querySelector("#" + elmt3Id)
let elmt2Value = parseInt(elmt2.value)
let elmt3Value = parseInt(elmt3.value)
// Check if any action is needed
let totalValue = parseInt(changedElmt.value) + elmt2Value + elmt3Value
if ( isNaN(totalValue) || totalValue <= 50 )
return
// Measure excess then split in 2
let excessValue = totalValue - 50
let share2 = Math.min(Math.floor(excessValue / 2), elmt2Value)
let share3 = excessValue - share2
console.log("Current:", " " + elmt2Id + ": ", share2, " " + elmt3Id + ": ", share3)
console.log("Total:", totalValue, " Excess: ", excessValue, " " + elmt2Id + ": ", share2, " " + elmt3Id + ": ", share3)
elmt2.value = elmt2Value - share2
elmt3.value = elmt3Value - share3
}
</script>
I don't know how optimal my solution is but it works. Covered some edge cases too.
let inputs = document.querySelectorAll('input');
const max = inputs[0].getAttribute("max");
let value;
inputs.forEach((input, i) => {
input.addEventListener('change',(e) =>handleChange(e)); // adding change event
input.addEventListener('blur',(e) =>handleChange(e)); //adding a blur eventto prevent direct typing of input larger than max
})
const handleChange = (e) =>{
if(e.target.value > max - value){
e.target.value = max-value; //setting max value possible if input value is greater than max
return;
}else{
value = 0;
inputs.forEach( input => {
value+=parseInt(input.value); //calculating value to negate from max
});
inputs.forEach( input => {
if(max-value > 0){
input.setAttribute("max", max-value); //setting max value on every input
}
});
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<input min="0" name="cat1" step="1" type="number" max="50" value="0" />
<input min="0" name="cat2" step="1" type="number" max="50" value="0" />
<input min="0" name="cat3" step="1" type="number" max="50" value="0" />
</body>
</html>
I hope that works for you easy small and fast for lesser number of input in form.
$(function(){
$('input[type=number]').attr('max', '50')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input min="0" name="cat1" step="1" type="number" value="0" />
<input min="0" name="cat2" step="1" type="number" value="0" />
<input min="0" name="cat3" step="1" type="number" value="0" />
Related
I am student testing and learning new things. Right now I'm trying to make a GUI fan speed controller. While I have made the basic code, I want that the user cant enter smaller value than previous input.
Javscript code
// 30
var range3 = document.getElementById("range3");
var num3 = document.getElementById('num3');
range3.addEventListener('input', function (e) {
num3.value = e.target.value;
});
num3.addEventListener('input', function (e) {
range3.value = e.target.value;
});
// 40
var range4 = document.getElementById("range4");
var num4 = document.getElementById('num4');
range4.addEventListener('input', function (e) {
num4.value = e.target.value;
});
num4.addEventListener('input', function (e) {
range4.value = e.target.value;
});
// 50
var range5 = document.getElementById("range5");
var num5 = document.getElementById('num5');
range5.addEventListener('input', function (e) {
num5.value = e.target.value;
});
num5.addEventListener('input', function (e) {
range5.value = e.target.value;
});
function execute(){
document.getElementById("result").innerHTML = num3.value + " " + num4.value + " " + num5.value ;
}
HTML code
<input id="range3" type="range" min="0" max="100" value="0" />
<input id="num3" min="0" max="100" type="number" value="0" />
<input id="range4" type="range" min="0" max="100" value="0" />
<input id="num4" min="0" max="100" type="number" value="0" />
<input id="range5" type="range" min="0" max="100" value="0" />
<input id="num5" min="0" max="100" type="number" value="0" />
<button onclick="execute()">Click</button>
<p id="result"></p>
I would like for the code to change its answer when I change the value of the input.
So let's say instead of 10, I would like it to tell me how much HP (health points) I will have at level 15. Is there any way I can do this? I'm not that experienced in Javascript.
So right now I coded it to default to 10 on all stats. My website tells me that at level 10, I have 895.4 hp. The only problem is that it won't stay at 15 when I try to press enter. It will just revert back to 10. Pretty much useless. Is there any way to keep that number 15 when I press enter?
var finalhp = 500;
let hpmultiplier = 1.06;
var hpvaluestring = document.querySelector('.hp').value;
var hpvalue = parseInt(hpvaluestring);
for (let i = 0; i < hpvalue; i++) {
var finalhp = finalhp * hpmultiplier
}
console.log(finalhp)
<form>
<div>
<input class="hp" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>
Add a form submit event listener to the form element and prevent form submission there.
<form onsubmit="submitForm(event)">
<div>
<input class="hp" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>
Add a submitForm function inside a script tag
function submitForm(event){
event.preventDefault();
var finalhp = 500;
let hpmultiplier = 1.06;
var hpvaluestring = document.querySelector('.hp').value;
var hpvalue = parseInt(hpvaluestring);
for (let i = 0; i < hpvalue; i++) {
var finalhp = finalhp * hpmultiplier
}
console.log(finalhp)
}
So mainly I'm just adding eventListeners to trigger the function calculateHP on input/slider value change. The function calculateHP contains the same logic that you shared. I did this so that the eventListeners can callback the function.
Try the following:
const input = document.querySelector('.hp')
const slider = document.querySelector('.slider')
slider.addEventListener('change', calculateHP)
input.addEventListener('change', calculateHP)
function calculateHP(){
let multiplier = 1.06
let level = Number(input.value)
let HP = 500
for(let i = 0; i<level; i++){
HP = HP * multiplier
}
return console.log(HP)
}
<div>
<label>Level: </label>
<input class="hp" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
I have some range sliders and input fields. From that I'm getting some equations now I want to subtract those dynamic numbers by their ID. Below is the code but I'm getting NaN value. Below the steps, I've done.
Getting #totalavgtime from the multiplication of range slider and .averagetime
Getting #timetoproduce from the multiplication of range slider and .radio-roi next input value.
Now trying to subtract #totalavgtime - #timetoproduce but getting NaN value in #timesaving.
$(document).ready(function() {
$(".range").on("change", function() {
var mult = 0;
$('.range').each(function(i) {
var selector_next = parseInt($(".averagetime:eq(" + i + ")").attr("value"))
mult += parseInt($(this).val()) * selector_next //multply..
console.log($(".averagetime:eq(" + i + ")").attr("value"), $(this).val())
})
$("#totalavgtime").val(mult)
})
});
$(document).ready(function() {
$('.range').on('change', function() {
let n = $(this).attr('id').match(/\d+/g)[0];
let total = 0;
let checkVal = $('.radio-roi:checked').next('input').val();
let multiplyFactor = parseFloat(checkVal);
console.log(multiplyFactor)
$('.range').each(function() {
total += (parseFloat($(this).val()) * multiplyFactor);
});
$('#timetoproduce').value(total);
})
});
$(document).ready(function() {
var txt1 = parseInt(document.getElementById("totalavgtime").value);
var txt2 = parseFloat(document.getElementById("timetoproduce").value);
var res = document.getElementById("timesaving");
Number(txt1);
Number(txt2);
//Substract that
res.value = txt1 - txt2;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<input type="radio" id="" class="radio-roi" name="plan" value="plus" checked>
<input type="text" value="2.5" id="actualtime2" class="hiden-actual-time" disabled><br>
<input type="radio" id="" class="radio-roi" name="plan" value="pro">
<input type="text" value="3" id="actualtime3" class="hiden-actual-time" disabled><br>
<input type="text"value="6" id="avgtime-id" class="averagetime"disabled><br>
<input type="range" name="slider-1" min="0" max="12" value="0" step="1" class="range" id="range-slider"><br>
<input type="text"id="totalavgtime" value="" disabled><br>
<input type="text"id="timetoproduce" value="" disabled><br>
<input type="text"id="timesaving" value="" disabled><br>
You can merge both event handler in one as both are triggering same elements . So , inside this on each iteration get value of range slider and add total to same variable and set them in required input . Now , to subtract them check if the value is not null depending on this take value of input else take 0 to avoid NaN error.
Demo Code :
$(document).ready(function() {
$(".range").on("change", function() {
$(this).next().text($(this).val()) //for output(range)
var selector_next_avg = 0;
var timetoproduce = 0
var checkVal = parseFloat($('.radio-roi:checked').next('input').val()); //radio next input
$('.range').each(function(i) {
var selector_next = parseInt($(".averagetime:eq(" + i + ")").val()) //avg..input
selector_next_avg += parseInt($(this).val()) * selector_next;
timetoproduce += (parseFloat($(this).val()) * checkVal);
})
//set both values
$("#totalavgtime").val(selector_next_avg)
$('#timetoproduce').val(timetoproduce);
total() //call to total..(sub)
})
});
function total() {
var txt1 = $("#totalavgtime").val() != "" ? parseFloat($("#totalavgtime").val()) : 0; //if null take 0
var txt2 = $("#timetoproduce").val() != "" ? parseFloat($("#timetoproduce").val()) : 0;
$("#timesaving").val(txt1 - txt2); //set value
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<input type="radio" id="" class="radio-roi" name="plan" value="plus" checked>
<input type="text" value="2.5" id="actualtime2" class="hiden-actual-time" disabled><br>
<input type="radio" id="" class="radio-roi" name="plan" value="pro">
<input type="text" value="3" id="actualtime3" class="hiden-actual-time" disabled><br>
<input type="text" value="6" id="avgtime-id" class="averagetime" disabled><br>
<input type="range" name="slider-1" min="0" max="12" value="0" step="1" class="range" id="range-slider"><output></output><br>
<input type="text" id="totalavgtime" value="" disabled><br>
<input type="text" id="timetoproduce" value="" disabled><br>
<input type="text" id="timesaving" value="" disabled><br>
i want button to increment 1 value to first and second range and button decrement 1 value on first and second range
my code:
function run(){
var one = document.getElementById("range1").value;
document.getElementById('out1').value=one;
var two = document.getElementById("range2").value;
document.getElementById('out2').value=two;
}
<input type="range" name="range1" step="1" value="20" min="0" max="100" oninput="run(this.value)" id="range1"/>
<output id="out1">20</output>
<input type="range" name="range2" step="1" value="37" min="0" max="100" oninput="run(this.value)" id="range2"/>
<output id="out2">37</output>
<br>
<button>+</button><button>-</button><br><br><br>
<h2>+ :increment 1 value on both of them</h2>
<h2>- :decrement 1 value on both of them</h2>
and live change
function run(){
var one = document.getElementById("range1").value;
document.getElementById('out1').value=one;
var two = document.getElementById("range2").value;
document.getElementById('out2').value=two;
}
function plus(){
document.getElementById("range1").value++;
document.getElementById("range2").value++;
run();
}
function minus(){
document.getElementById("range1").value--;
document.getElementById("range2").value--;
run();
}
<input type="range" name="range1" step="1" value="20" min="0" max="100" oninput="run(this.value)" id="range1"/>
<output id="out1">20</output>
<input type="range" name="range2" step="1" value="37" min="0" max="100" oninput="run(this.value)" id="range2"/>
<output id="out2">37</output>
<br>
<button onclick="plus()">+</button><button onclick="minus()">-</button><br><br><br>
<h2>+ :increment 1 value on both of them</h2>
<h2>- :decrement 1 value on both of them</h2>
and live change
Created two functions(and assigned them to the onclick events of the buttons)
Both either add 1 or substract 1 (++ and -- are shorthand for +=1 and -=1)
Both functions call run() in order to refresh the values of output tags.
More info:
++:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Addition_assignment
--:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Subtraction_assignment
Here is the code. Add a click event to the buttons and increment or decrement the vale as necessary.
function run() {
var one = document.getElementById("range1").value;
document.getElementById('out1').value = one;
var two = document.getElementById("range2").value;
document.getElementById('out2').value = two;
}
function setNewValue(val) {
var r1 = document.getElementById("range1");
r1val = parseInt(r1.value) + val;
if (r1val >= 0 && r1val <= 100) {
r1.value = r1val;
document.getElementById('out1').value = r1val;
}
var r2 = document.getElementById("range2");
r2val = parseInt(r2.value) + val;
if (r2val >= 0 && r2val <= 100) {
r2.value = r2val;
document.getElementById('out2').value = r2val;
}
}
<input type="range" name="range1" step="1" value="20" min="0" max="100" oninput="run(this.value)" id="range1" />
<output id="out1">20</output>
<input type="range" name="range2" step="1" value="37" min="0" max="100" oninput="run(this.value)" id="range2" />
<output id="out2">37</output>
<br>
<button onclick="setNewValue(1)">+</button>
<button onclick="setNewValue(-1)">-</button>
<br>
<br>
<br>
<h2>+ :increment 1 value on both of them</h2>
<h2>- :decrement 1 value on both of them</h2>
and live change
In case you want a simple solution with jQuery:
$('#more').click(function() {
$('#range1').val(parseInt($('#range1').val())+1);
$('#out1').text($('#range1').val());
$('#range2').val(parseInt($('#range2').val())+1);
$('#out2').text($('#range2').val());
});
$('#less').click(function() {
$('#range1').val(parseInt($('#range1').val())-1);
$('#out1').text($('#range1').val())
$('#range2').val(parseInt($('#range2').val())-1);
$('#out2').text($('#range2').val())
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="range" name="range1" step="1" value="20" min="0" max="100" oninput="run(this.value)" id="range1" />
<output id="out1">20</output>
<input type="range" name="range2" step="1" value="37" min="0" max="100" oninput="run(this.value)" id="range2" />
<output id="out2">37</output>
<br>
<button id="more">+</button>
<button id="less">-</button>
<br>
<h2>+ :increment 1 value on both of them</h2>
<h2>- :decrement 1 value on both of them</h2>
and live change
I have 3 inputs and I'm trying to get the sum of the numbers each time a user updates one of them.
HTML
<input class="my-input" type="number" name="" value="0" min="0">
<input class="my-input" type="number" name="" value="0" min="0">
<input class="my-input" type="number" name="" value="0" min="0">
JS
var sum = 0;
$('.my-input').each(function(index, elem){
var value = $(this).val();
sum += parseFloat($(elem).val());
console.log(sum);
$(this).on('keyup click', function (){
sum += parseFloat($(elem).val());
});
});
But I keep getting crazy results..
EDIT:
I tried this:
function getSum(){
var sum = 0;
$('.my-input').each(function(index, elem){
var value = $(this).val();
sum += parseFloat($(elem).val());
});
return sum;
}
$('.my-input').each(function(){
$(this).on('keyup click', function(){
console.log( this.value );
var curSum = getSum();
console.log('current sum: ' + curSum);
});
});
Consider this example:
<input class="my-input" type="number" name="" value="0" min="0" />
<input class="my-input" type="number" name="" value="0" min="0" />
<input class="my-input" type="number" name="" value="0" min="0" />
<input type="text" id="total" value="" />
<script type="text/javascript">
// just get keyup event
$('.my-input').on('keyup', function(){
var total = 0;
// on every keyup, loop all the elements and add all the results
$('.my-input').each(function(index, element) {
var val = parseFloat($(element).val());
if( !isNaN( val )){
total += val;
}
});
$('#total').val(total);
});
</script>