RRonny
RRonny

Reputation: 23

Set max value of three input numbers together

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?

Upvotes: 2

Views: 1520

Answers (5)

Anmol Mehta
Anmol Mehta

Reputation: 17

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" />

Upvotes: 0

Eponyme Web
Eponyme Web

Reputation: 976

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>

Upvotes: 1

user7780408
user7780408

Reputation:

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>

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 191976

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" />

Upvotes: 4

Salmanul Faris
Salmanul Faris

Reputation: 356

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" />

Upvotes: 1

Related Questions