data-accept

Restrict input to allowed characters without enforcing a rigid format. Named presets for phone, date, credit card, and more. Custom character classes via bracket syntax.

Overview

The data-accept attribute restricts an input to a set of allowed characters without enforcing a rigid format. Unlike data-mask, which auto-injects separators and dictates the shape of the value, data-accept lets the user format freely — only invalid characters are blocked.

<label for="phone">Phone number</label> <input type="text" id="phone" data-accept="phone" placeholder="+1 (555) 123-4567">

How It Works

Add data-accept with a preset name or custom character class to any text input. The init script:

  1. Resolves the allowed character set from the preset name or bracket syntax
  2. Intercepts beforeinput events to block invalid characters before they appear — no flicker, no cursor jump
  3. Filters pasted text character-by-character, keeping only valid characters
  4. Falls back to input event stripping for browsers where beforeinput is not cancelable
  5. Handles IME composition events to avoid interfering with multi-byte input
  6. Sets inputmode automatically from the preset
  7. Stores the regex source in data-accept-pattern for external consumption

Attributes

Attribute Type Description
data-accept string Preset name or custom character class (e.g., [0-9a-fA-F]).
data-accept-pattern string Set automatically. Contains the regex source for the allowed character set.
data-accept-init boolean Set automatically to prevent double-binding. Do not set manually.

Presets

The following presets are available out of the box:

Preset Allowed characters inputmode
digits [0-9] numeric
alpha [a-zA-Z] text
alphanum [a-zA-Z0-9] text
phone [0-9+()- ] (digits, plus, parens, hyphen, space) tel
date [0-9/-.] (digits, slash, hyphen, period) numeric
hex [0-9a-fA-F] text
currency [0-9.,] (digits, comma, period) decimal
cc [0-9 -] (digits, space, hyphen) numeric
<label for="phone-demo">Phone</label> <input type="text" id="phone-demo" data-accept="phone" placeholder="+1 (555) 123-4567"> <label for="date-demo">Date</label> <input type="text" id="date-demo" data-accept="date" placeholder="MM/DD/YYYY"> <label for="cc-demo">Credit card</label> <input type="text" id="cc-demo" data-accept="cc" placeholder="1234 5678 9012 3456"> <label for="currency-demo">Currency</label> <input type="text" id="currency-demo" data-accept="currency" placeholder="1,234.56"> <label for="digits-demo">Digits</label> <input type="text" id="digits-demo" data-accept="digits" placeholder="123456"> <label for="hex-demo">Hex</label> <input type="text" id="hex-demo" data-accept="hex" placeholder="FF00AA">

Custom Patterns

For character sets not covered by a preset, pass a character class directly. The value must start with [ and is parsed as a JavaScript RegExp.

<label for="hex">Hex color</label> <input type="text" id="hex" data-accept="[0-9a-fA-F]" maxlength="6" placeholder="FF00AA">

With Form Field

Wrap in <form-field> for validation feedback, helper text, and required indicators.

<form-field> <label for="phone-field">Phone number</label> <input type="text" id="phone-field" data-accept="phone" required placeholder="+1 (555) 123-4567"> <small slot="help">Digits, +, parentheses, hyphens, and spaces.</small> </form-field>

Paste Behavior

When the user pastes content, the filter runs character-by-character: valid characters are kept, invalid ones are silently stripped. The paste uses document.execCommand('insertText') to preserve the browser's undo history.

<!-- Paste "abc123def456" into this field — only digits are kept --> <label for="paste-demo">Digits only (try pasting)</label> <input type="text" id="paste-demo" data-accept="digits" placeholder="Paste mixed content">

data-accept vs data-mask

Both attributes filter input, but they serve different purposes:

data-mask data-accept
Separators Auto-injected User types them
Format Rigid, one shape Flexible, user decides
Core logic Strip → reformat → reposition Block or strip invalid chars
Use when You dictate the format User picks the format

If both data-mask and data-accept are present on the same input, data-mask wins and a console warning is logged.

Dynamic Elements

Accept inputs added to the DOM after page load are automatically enhanced via a shared MutationObserver. No manual initialization is needed.

// Dynamically added accept inputs are auto-enhanced via MutationObserver const input = document.createElement('input'); input.type = 'text'; input.dataset.accept = 'digits'; document.body.appendChild(input); // input is ready to use — no manual init needed

Accessibility

  • inputmode is set automatically from the preset, showing the appropriate keyboard on mobile devices
  • IME composition is handled correctly — filtering pauses during compositionstart and resumes after compositionend
  • Cursor position is preserved when the fallback filter strips characters
  • A visible <label> is required for the input
  • The placeholder attribute should hint at what characters are accepted
  • Without JavaScript, the input accepts freeform text — progressive enhancement