HOWTO · JavaScript

How to Validate Numbers in Form Inputs in JavaScript

Choose an accepted numeric format and validate complete form input in JavaScript, with regular expressions, number checks, and input-event feedback.

On this page

To validate a number in an HTML form, first decide which strings your form accepts. A whole number, a signed decimal, and a value with surrounding spaces are different formats. Then validate the complete input at submission; feedback while typing can help, but it does not replace that final check.

Choose what counts as a number

JavaScript can convert many strings to numbers, but conversion alone does not define your form’s rules. For example, Number(" ") is 0, while Number("12px") is NaN. Decide whether to accept signs, decimals, exponent notation, surrounding whitespace, and empty input. If your application expects a positive whole number, enforce that specific rule rather than treating every value JavaScript can convert as acceptable.

Validate a complete input with a regular expression

A regular expression is useful when the accepted format is deliberately narrow. The pattern below allows an optional sign followed by one or more digits. RegExp.prototype.test() returns a boolean for the match.

Run this example:

const wholeNumber = /^[+-]?\d+$/;
const value = "-42";
console.log(wholeNumber.test(value));

This pattern accepts -42 and rejects 42x and 2.5; it does not impose a numeric range. JavaScript’s $ anchor can also match just before a final line terminator, so pair the pattern with an explicit check for one. The function below rejects that terminator as well as any other text after the digits:

const wholeNumber = /^[+-]?\d+$/;
const isWholeNumber = value =>
  wholeNumber.test(value) && !/[\r\n\u2028\u2029]$/.test(value);

console.log(isWholeNumber("-42"));
console.log(isWholeNumber("42x"));
console.log(isWholeNumber("2.5"));
console.log(isWholeNumber("42\n"));

This format check does not set a numeric range. If decimals are allowed, define their syntax explicitly, such as whether 3., .5, or -0.5 should count. Avoid a pattern like /\d/ as a complete validator; it only finds a digit somewhere in the string.

Validate numeric strings with JavaScript number checks

For values accepted by JavaScript’s numeric conversion, convert once and check the result. Number.isFinite() rejects NaN, positive and negative infinity, and non-number values. Number.isNaN() specifically detects the NaN value. By contrast, the global isNaN() coerces its argument, which can make strings such as whitespace appear numeric.

A complete-value check can trim surrounding whitespace, reject a blank string, convert the remaining text with Number(), and require a finite result. The example below deliberately limits the accepted text to signed decimal and exponent notation before conversion, so strings such as 0x10 are excluded even though Number() can convert them. parseFloat() is often unsuitable as the only validator because it accepts a numeric prefix, so text such as 12px parses as 12.

function isDecimalNumber(value) {
  const trimmed = value.trim();
  const decimal = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i;
  if (trimmed === "" || !decimal.test(trimmed)) return false;
  return Number.isFinite(Number(trimmed));
}

const examples = ["", "12.5", "1e3", "12px"];
for (const value of examples) {
  console.log(`${JSON.stringify(value)}: ${isDecimalNumber(value)}`);
}

Here blank input and trailing text fail, while 12.5 and 1e3 pass. Number.isNaN() can identify a NaN result, but Number.isFinite() also rules out infinities and is the useful final check here.

For more detail on this distinction, see checking whether a string is a number.

Validate input as the user types

Listen for the input event to update helpful status as the field changes. Read the field’s current .value and run the same complete-value rule you use at submission. This compact browser example keeps the status polite while the user edits and repeats the check when the form is submitted:

<form id="number-form">
  <label for="amount">Amount</label>
  <input id="amount" name="amount" type="text" inputmode="decimal">
  <p id="number-feedback" aria-live="polite">Enter a decimal number.</p>
  <button type="submit">Submit</button>
</form>
<script>
  const form = document.querySelector("#number-form");
  const field = document.querySelector("#amount");
  const feedback = document.querySelector("#number-feedback");

  function isDecimalNumber(value) {
    const trimmed = value.trim();
    const decimal = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i;
    return trimmed !== "" && decimal.test(trimmed) &&
      Number.isFinite(Number(trimmed));
  }

  field.addEventListener("input", () => {
    const value = field.value;
    feedback.textContent = value.trim() === ""
      ? "Enter a decimal number."
      : isDecimalNumber(value)
        ? "This value is ready to submit."
        : "Enter a signed decimal or exponent value.";
  });

  form.addEventListener("submit", event => {
    if (!isDecimalNumber(field.value)) {
      event.preventDefault();
      feedback.textContent = "Enter a valid decimal number before submitting.";
      field.focus();
    }
  });
</script>

The input handler checks the field’s current complete value after each edit; it does not filter individual keystrokes. A blank field gets a prompt, and a partially entered value can show interim guidance until the user finishes it. Submission performs the same rule again and prevents sending a value that fails.

Do not validate a proposed character in isolation: users edit by pasting, deleting, selecting, using assistive technology, or entering text through mobile keyboards. A character-by-character filter can also prevent correcting a value that is temporarily incomplete while typing.

Keep interim feedback distinct from the final form decision. A partially entered decimal may be incomplete at one moment and valid once finished. On submit, validate the final string, show a clear message, and prevent submission if it does not meet the chosen rule. Native HTML constraints such as required, min, max, and step can also help, but server-side validation is still needed for data you rely on.

Test edge cases and choose an approach

Check representative values against the exact rule your form intends to enforce. A digits-only pattern rejects 2.5, -2, and surrounding spaces unless you allow them in the pattern. Numeric conversion accepts decimals, but blank text needs an explicit rejection because converting whitespace yields zero. A value such as 1e3 converts to a finite number even if your form does not want exponent notation. Likewise, conversion does not enforce positivity or a maximum amount.

Use a regular expression when the textual format matters, and numeric conversion plus range checks when the value’s numeric meaning matters. In either case, test empty input, a valid integer, an allowed decimal, a sign, trailing letters, and any boundary values relevant to your form. Keep these cases in application tests so later changes do not silently broaden what the form accepts.