Question

How to Allow Only Numeric Input in HTML and JavaScript

htmljavascriptjquery

Question

How can I make an HTML text input allow only numeric keyboard input, including the decimal point (.)?

For example, I want a field like this:

<input type="text" />

I would like the user to type only numbers, with . allowed for decimal values. Is there a simple way to do this in HTML, or do I need JavaScript as well?

Short Answer

By the end of this page, you will understand the difference between restricting what a user can type and validating input correctly. You will learn how to use HTML input types and attributes such as type="number", inputmode, and pattern, and when JavaScript is useful for cleaning or checking numeric input with decimals.

Concept

Numeric input in web forms seems simple, but there are actually two separate problems:

  1. User experience: guiding the user to enter the right kind of value.
  2. Validation: making sure the submitted value is actually valid.

A common beginner idea is to block every non-numeric key as the user types. That can work in simple cases, but it is usually not enough on its own.

Why?

  • Users can paste invalid text.
  • Different keyboards and devices behave differently.
  • Some valid numbers include characters like - or ..
  • Browsers may allow scientific notation in numeric fields, such as 1e3.
  • Accessibility tools may not behave well with aggressive key blocking.

In real web development, the safer approach is usually:

  • Use HTML to hint that the field expects a number.
  • Use browser validation where helpful.
  • Add JavaScript only if you need extra control.
  • Always validate again when processing the form.

For decimal input, the browser can help if you use:

<input type="number" step="any">

However, type="number" does not literally mean “only digits and a dot”. It means “a numeric value”, and browser behavior may vary.

If your requirement is specifically “digits and at most one decimal point,” JavaScript is often used to sanitize or validate the text field value.

Mental Model

Think of an input field like a door to a building.

  • HTML attributes are the signs on the door: “Numbers only, please.”
  • JavaScript filtering is a security guard who stops obviously wrong entries.
  • Validation is the final ID check inside the building.

A sign helps. A guard helps more. But the final check is what really protects correctness.

So when working with numeric input, do not rely only on the keyboard restriction. Make sure the value is checked before you trust it.

Take Quiz

Syntax and Examples

Option 1: Use type="number"

This is the simplest built-in HTML approach.

<input type="number" step="any" />

What this does

  • type="number" tells the browser the field expects a number.
  • step="any" allows decimal values.

Notes

  • Many browsers show numeric controls or numeric keyboards on mobile.
  • Users may still be able to type characters like e, -, or + in some browsers because they can be part of valid numeric formats.
  • This is usually good for numeric values, but not for strict formatting rules.

Option 2: Use inputmode with a text field

<input type="text" inputmode="decimal" />

What this does

  • Keeps the field as text.
  • Suggests a decimal-friendly keyboard on mobile devices.

Important

inputmode improves typing experience, but it does not validate the value.

Option 3: Validate with a pattern

<input type="text" pattern="^\d+(\.\d+)?$" inputmode="decimal" />

This pattern means:

  • \d+ → one or more digits
  • (\.\d+)? → optionally, a decimal point followed by one or more digits

This matches values like:

  • 12
  • 12.5
  • 0.99

This does not match:

  • .5
  • 12.
  • abc

Option 4: Clean the value with JavaScript

If you want to remove invalid characters as the user types:

<input type="text" id="priceInput" inputmode="decimal" />

<script>
  const input = document.getElementById('priceInput');

  input.addEventListener('input', () => {
    let value = input.value;

    value = value.replace(/[^0-9.]/g, '');

    const parts = value.split('.');
    if (parts.length > 2) {
      value = parts[0] + '.' + parts.slice(1).join('');
    }

    input.value = value;
  });
</script>

What this example does

  • Removes everything except digits and .
  • Ensures only one decimal point remains

This is useful when you want the field to behave like a controlled decimal input.

Step by Step Execution

Consider this example:

<input type="text" id="amount" inputmode="decimal" />

<script>
  const input = document.getElementById('amount');

  input.addEventListener('input', () => {
    let value = input.value;
    value = value.replace(/[^0-9.]/g, '');

    const parts = value.split('.');
    if (parts.length > 2) {
      value = parts[0] + '.' + parts.slice(1).join('');
    }

    input.value = value;
  });
</script>

Step-by-step

  1. The user types something into the input.
  2. The input event runs every time the value changes.
  3. input.value reads the current text.
  4. value.replace(/[^0-9.]/g, '') removes any character that is not:
    • a digit from 0 to 9
    • a decimal point .
  5. value.split('.') breaks the string into pieces around each dot.
  6. If there is more than one dot:
    • keep the first dot
    • remove the extra ones by joining the remaining parts without dots
  7. The cleaned result is written back into the input.

Example trace

If the user types:

12a.3.4b

Then the script processes it like this:

  • Original: 12a.3.4b
  • Remove invalid characters: 12.3.4
  • Split by dot: ["12", "3", "4"]
  • Keep only first dot: 12.34
  • Final input value: 12.34

This is a good example of sanitizing input rather than just blocking key presses.

Real World Use Cases

Numeric-only or decimal-friendly inputs are common in many applications.

Typical examples

  • Price fields: product price, invoice amount, discount value
  • Measurements: weight, height, distance, temperature
  • Finance tools: tax rate, loan amount, exchange rate
  • Admin dashboards: limits, quotas, percentages
  • Data entry forms: quantities, scores, decimal metrics

Example scenarios

E-commerce

A checkout page may ask for a custom amount or quantity.

Health app

A form may accept body weight like 72.5.

Reporting dashboard

An analyst may enter a threshold such as 0.85.

In all of these, the application should both:

  • make input easy for the user
  • reject invalid values before using them
Take Quiz

Real Codebase Usage

In real projects, developers usually combine several techniques instead of relying on only one.

Common pattern: HTML hint + JavaScript validation

<input type="text" id="rate" inputmode="decimal" />
function isValidDecimal(value) {
  return /^\d+(\.\d+)?$/.test(value);
}

This keeps the typing experience flexible while still validating the final value.

Guard clause before processing

const value = input.value.trim();

if (!/^\d+(\.\d+)?$/.test(value)) {
  console.log('Invalid number');
  return;
}

const amount = Number(value);
console.log(amount);

This is a guard clause: if the value is invalid, stop early.

Sanitizing pasted input

Users often paste values instead of typing them. Real code frequently cleans pasted or typed text on the input event instead of only watching keyboard events.

Server-side validation still matters

Even if the browser checks input, production systems validate again when receiving data. Client-side validation improves usability, but it is not a security boundary.

Configuration example

Some teams allow integers only, while others allow decimals up to two places.

const moneyPattern = /^\d+(\.\d{1,2})?$/;

This is common for currency inputs.

Common Mistakes

1. Blocking only keypress

A common older approach is to stop non-numeric keys during keyboard input.

<input onkeypress="return event.charCode >= 48 && event.charCode <= 57">

Why this is a problem

  • It does not handle paste well.
  • It may block useful keys like backspace, delete, or arrow keys depending on implementation.
  • It can behave inconsistently across browsers.

2. Assuming type="number" means only digits and a dot

<input type="number" />

This does not always enforce the exact text format beginners expect.

Avoid this mistake

Use type="number" when you want a numeric value, not when you need strict character-level formatting.

3. Forgetting decimal rules

Broken expectation:

/^\d+$/

This allows only integers, not decimals.

If decimals should be allowed, use something like:

/^\d+(\.\d+)?$/

4. Not thinking about pasted input

A user can paste:

abc12.3xyz

If you only block keys, this may still get through.

Use validation or sanitization on the full value.

5. Trusting browser validation alone

Client-side checks are useful, but they should not be the only validation.

6. Rejecting valid edge cases without deciding intentionally

Do you want to allow:

  • 0.5
  • .5
  • 12.
  • negative numbers like -3.2

Your pattern should reflect your actual requirements. There is no single correct regex for every numeric field.

Comparisons

ApproachWhat it doesGood forLimitations
type="number"Browser treats the field as numericStandard numeric formsMay allow characters like e, -, +; browser behavior varies
type="text" + inputmode="decimal"Suggests decimal keyboard on mobileBetter typing experience with custom validationNo built-in numeric validation
patternValidates text formatSimple form validation rulesDoes not actively clean input while typing
JavaScript sanitizingRemoves invalid characters during inputStrict UX controlExtra code; must be designed carefully
JavaScript final validationChecks the value before useReliable application logicDoes not guide typing by itself

Practical recommendation

  • Use type="number" if you want a general numeric field.
  • Use type="text" + inputmode="decimal" + validation if you need strict formatting.
  • Use JavaScript sanitizing only when the typing experience must be tightly controlled.
Take Quiz

Cheat Sheet

Quick options

General numeric input

<input type="number" step="any" />

Text input with decimal keyboard hint

<input type="text" inputmode="decimal" />

Text input with decimal validation

<input type="text" inputmode="decimal" pattern="^\d+(\.\d+)?$" />

JavaScript validation

/^\d+(\.\d+)?$/

JavaScript sanitizing

value = value.replace(/[^0-9.]/g, '');

Useful rules

  • type="number" is for numeric values, not strict text formatting.
  • inputmode helps mobile keyboards, but does not validate.
  • pattern validates format for text inputs.
  • input event is better than only keypress for cleaning typed and pasted content.
  • Always validate before using submitted data.

Common decimal regex

Allow integers and decimals like 12 or 12.34

/^\d+(\.\d+)?$/

Allow up to 2 decimal places

/^\d+(\.\d{1,2})?$/

Edge cases to decide

  • Should .5 be allowed?
  • Should 12. be allowed?
  • Should negative numbers be allowed?
  • Should scientific notation be allowed?

FAQ

Can I make an HTML input accept only numbers without JavaScript?

Yes, you can use type="number". For stricter format rules, you may also use pattern on a text input. JavaScript is helpful when you want to clean input while the user types.

Why does input type="number" still allow some non-digit characters?

Because browsers may allow characters used in valid numeric formats, such as -, +, or e. It is a numeric field, not a strict “digits only” field.

Should I use keypress to block invalid characters?

Usually no. It is better to validate or sanitize on the input event, because that also handles paste and other input methods more reliably.

How do I allow decimals but not letters?

Use a text input with inputmode="decimal" and validate with a pattern like ^\d+(\.\d+)?$, or clean the value using JavaScript.

What is the best input type for currency?

Often developers use a text input with custom validation, because currency fields usually need strict decimal rules such as two decimal places.

Do I still need server-side validation?

Yes. Client-side checks improve usability, but the server must still validate all incoming data.

How do I allow only two decimal places?

Use a regex such as:

/^\d+(\.\d{1,2})?$/

This allows values like 10 and 10.25.

Take Quiz

Mini Project

Description

Build a small product price input field for a form. The field should allow digits and one decimal point, show an error message for invalid values, and convert the final value into a JavaScript number when valid. This demonstrates the difference between input sanitization and final validation.

Goal

Create a decimal input that accepts values like 12 and 12.50, rejects invalid formats, and displays the parsed numeric result.

Requirements

  • Create a text input for entering a price.
  • Allow only digits and a single decimal point while typing.
  • Show an error message if the final value is not a valid decimal number.
  • Accept up to two decimal places.
  • Display the parsed numeric value when the input is valid.
Take Quiz

Keep learning

Related questions

View more