1

I'm doing input validation on the following field and I want to set a default value. What I mean by default value is I want to set some value to input field if the field is empty.

var inputBox = document.getElementById("inputBox");

inputBox.addEventListener("input", function() {
  validateInput(this);
});

inputBox.addEventListener("keydown", function(e) {
  validateInput(this, e);
});

function validateInput(elm, e) {
  // handle keydown event
  if (e) {
    // do not allow floating-point numbers, if it's not expected
    if (!isFloat(elm.step)) {
      if (e.key == ".") {
        e.preventDefault();
      }
    }
  }
  // handle input event
  else {
    // do not allow leading zeros
    while (elm.value.length > 1 && elm.value[0] === "0") {
      elm.value = elm.value.toString().slice(1);
    }
    // input should be between min and max
    if (elm.validity.rangeUnderflow) {
      elm.value = elm.min;
    } else if (elm.validity.rangeOverflow) {
      elm.value = elm.max;
    }
  }
}

function isFloat(x) {
  var f = parseFloat(x);
  var floor = Math.floor(f);
  var fraction = f - floor;
  if (fraction > 0) {
    return true;
  }
  return false;
}
<input type="number" id="inputBox" min="0" max="16581375" step="1" value="0" />

In a very straightforward approach, I can add the following to the end of validateInput()

// set default value, empty field isn't allowed
if (elm.value == "") {
    elm.value = elm.min;
}

but this breaks some functionality. For example, I can't enter exponential values (e.g. 1e+5).

Input field does its own check at input. The moment I enter 1e, it evaluates to NaN and the value property of the element is set to "", but visually, 1e is still entered on the field. So, you see, the entered value and the HTMLInputElement.value might differ.

To be able to set a default value, I should be able to check the entered value, not the parsed one by the element. Something like this would probably work:

// set default value, empty field isn't allowed
if (elm.value == "" && !elm.stringValue.includes(e)) {
    elm.value = elm.min;
}

But of course, there's no such stringValue property. One way I can think of to get around this problem is to use a text input field and do an extra validation for number.

Is there a way to make this work with number input field?

akinuri
  • 10,690
  • 10
  • 65
  • 102

1 Answers1

0

Looks like you need to parse exponential values into numbers.

I think, this solution should help you: https://stackoverflow.com/a/18719988/6420563

This solution made for text field but i think it will also work for number input.

Community
  • 1
  • 1
vadjs
  • 325
  • 3
  • 16
  • Input element with type set to number automatically validates the input using a regex. Makes sure it is a number. If it passes the validation, the input is stored in `value` property and parsed value is stored in `valueAsNumber` property. I can't check if the value is exponential or not at each input, because as soon as I type `1e`, it won't pass the validation, will evaluate to `NaN`, and `value` will be set to `""`. I can't get the actual entered value. – akinuri Aug 31 '16 at 22:28
  • You must to validate value after conversion that described in example. After it you can overwrite value if it's needed. – vadjs Aug 31 '16 at 22:36