Is it possible to ensure a User's input doesn't exceed a specific range in JavaScript?

Viewed 106

So I currently have a set up where there are input boxes that take numbers. The range is 0-100. I want to keep the value within that range, so if it's set to like, 200, it just caps at 100, or 0 in the case of a negative number.

I figure it'd be possible with an if statement. But the only way I see it working is through multiple if/else if statements. So I'm wondering if there's some other method to accomplish the goal.

Can view the current thing here

My code:

function updateStats() {
  var hp = document.getElementById("hpValue").value;
  var mp = document.getElementById("mpValue").value;
  var strength = document.getElementById("strengthValue").value;
  var defense = document.getElementById("defenseValue").value;
  var speed = document.getElementById("speedValue").value;
  var luck = document.getElementById("luckValue").value;

  document.getElementById("hpBar").style.width = hp + "%";
  document.getElementById("mpBar").style.width = mp + "%";
  document.getElementById("strBar").style.width = strength + "%";
  document.getElementById("defBar").style.width = defense + "%";
  document.getElementById("speedBar").style.width = speed + "%";
  document.getElementById("luckBar").style.width = luck + "%";

}
table {
  border-collapse: collapse;
}

table,
th,
td {
  border: 1px solid black;
}

.statbarsBG {
  background-color: #808080;
  text-align: left;
  height: 20px;
  width: 350px;
  -webkit-appearance: none;
  border: none;
  font-weight: bold;
  /* Set the progressbar to relative */
  position: relative;
}

.statbarsHP {
  background-color: green;
  height: 20px;
}

.statbarsMP {
  background-color: purple;
  height: 20px;
}

.statbarsSTR {
  background-color: red;
  height: 20px;
}

.statbarsDEF {
  background-color: darkblue;
  height: 20px;
}

.statbarsSPD {
  background-color: powderblue;
  height: 20px;
}

.statbarsLUCK {
  background-color: khaki;
  height: 20px;
}

input:invalid {
  border: 3px solid red;
}
<h3>Character Rank: B</h3>

<table cellspacing="20">
  <tr>
    <th>Stat</th>
    <th> Level</th>
    <th> Value (Between 0-100)</th>
  </tr>
  <tr>

    <td>HP</td>
    <td>
      <div class="statbarsBG">
        <div class="statbarsHP" style=" width:93%" id="hpBar" </div>
    </td>
    <td> <input type="text" pattern="[0-9]+" id="hpValue"> </td>
  </tr>
  <tr>

    <td label="MP">MP</td>
    <td>
      <div class="statbarsBG">
        <div class="statbarsMP" style=" width:30%" id="mpBar">

        </div>
      </div>
      </>
    </td>

    <td> <input type="text" pattern="[0-9]+" id="mpValue" value=""> </td>
  </tr>
  <tr>

    <td>STR </td>
    <td>
      <div class="statbarsBG">
        <div class="statbarsSTR" style=" width:75%" id="strBar" </div>
    </td>
    <td> <input type="text" pattern="[0-9]+" id="strengthValue" value=""> </td>
  </tr>

  <tr>

    <td>DEF </td>
    <td>
      <div class="statbarsBG">
        <div class="statbarsDEF" style=" width:89%" id="defBar" </div>
    </td>
    <td> <input type="text" pattern="[0-9]+" id="defenseValue"> </td>
  </tr>

  <tr>

    <td>SPEED </td>
    <td>
      <div class="statbarsBG">
        <div class="statbarsSPD" style=" width:45%" id="speedBar" </div>
    </td>
    <td> <input type="text" pattern="[0-9]+" id="speedValue" value=""> </td>
  </tr>

  <tr>

    <td>LUCK </td>
    <td>
      <div class="statbarsBG">
        <div class="statbarsLUCK" style=" width:95%" id="luckBar" </div>
    </td>
    <td> <input type="text" pattern="[0-9]+" id="luckValue" value="" class="userInput"> </td>
  </tr>
</table>


<button onclick="updateStats()">Click to Update Stats</button>

5 Answers

Use <input type="number">. And to set the range you can use the attributes min and max.

So for example:

<input type="number" min="0" max="100" id="strengthValue" value="">

To prevent users from typing in a value higher than the max or lower than the min you can use this script:

function checkMinMax(event) {
var value = this.value,
    min = this.getAttribute('min'),
    max = this.getAttribute('max');

if(value < min)
    this.value = min;
else if(value > max)
    this.value = max;
}

window.addEventListener('load', function() {
    document.getElementById('yourinput').addEventListener('keyup', checkMinMax);
});

First of all, let's clear up a lot of that repetition.

const map = {
    hpValue: 'hpBar',
    mpValue: 'mpBar',
    strengthValue: 'strBar',
    defenseValue: 'defBar',
    speedValue: 'speedBar',
    luckValue: 'luckBar'
};
for (let fieldId in map)
    document.getElementById(map[fieldId]).style.width = document.getElementById(fieldId).value+'%';

Now, outside the function, we can listen for the input event and act accordingly.

document.addEventListener('input', evt => {
    if (!evt.target.matches('table input')) return;
    let intVal = parseInt(evt.target.value);
    if (isNaN(intVal)) return evt.target.value = '';
    if (intVal < 0) return evt.target.value = 0;
    if (intVal > 100) return evt.target.value = 100;
});

Demo.

use below code for multiple input box validation (min value and max value):

Example:

<input type="number" min="0" max="100" onkeyup="myFunction(event, 0, 100)">

<input type="number" min="100" max="200" onkeyup="myFunction(event, 100, 200)">

<script>
    function myFunction(e, minValue, maxValue){
        let number = e.target.value;
        if(number > maxValue){
            // check if number is greater than max value
            e.target.value = maxValue;
        }else if(number < minValue){
            //check if number is less than min value
            e.target.value = minValue;
        }
    }
</script>

You could use a regular expression to test if the value entered is a number between 0 and 100.

if (document.getElementById("hpValue").value.match(/^(\d{1,2}|100)$/)){
  // value was a number between 0 and 100
}

You could create a resusable function to test the value:

function isValidRange(inputValue){
   return inputValue.match(/^(\d{1,2}|100)$/);
}

// usage:
if(isValidRange(document.getElementById("hpValue").value)){
   // value was a number between 0 and 100
}

Using input type='number' as evilgenious448 points out is a good hint, but ineffective as you can insert a bigger value by keyboard.

You can use Jquery library.

First, add a common class to all inputs, i.e. class = "inpt"

Then, retrieve all the input fields at once and apply if statements.

$(document).on("change", ".inpt", function() {
    $(".inpt").each(function(){
        if ($(this).val() > 100) $(this).val(100);
        if ($(this).val() < 0) $(this).val(0);
    });
});
Related