HOWTO · JavaScript
How to Mask Input Text Without a Plugin Using JavaScript
Format credit-card, postal-code, and telephone input as people type with a browser-side JavaScript input mask, without a plugin.
On this page
You can create an input mask in JavaScript without a plugin by formatting a field’s value in an input event handler. The examples below use small JavaScript functions, so there are no library files to download. They format credit-card digits, an illustrative alphanumeric postal code, and a North American telephone number, then show how to adapt the formatter for another field.
To try an example, put its script in a <script> element after the matching input in your HTML, or load it with defer. Give the input the id used by the script. Each code sample is a complete JavaScript program for its stated field. The snippets have not been run in a browser here, so no output is claimed.
Formatting changes what is displayed while someone types. It does not establish that a value is valid, identify a payment card, or replace server-side checks. An HTML pattern can help check a completed value when a form is submitted, but it does not add spaces or punctuation as someone types.
Input Masking for Credit Card Numbers in JavaScript
This example keeps digits and inserts a space after each group of four. It displays up to 19 digits, which accommodates common card-number lengths without assuming every card has the same length. The code uses type="text" with a numeric input hint so that the browser does not apply number-field behavior to a digit string.
function formatCardNumber(value) {
const digits = value.replace(/\D/g, "").slice(0, 19);
return digits.replace(/(.{4})/g, "$1 ").trim();
}
if (typeof document !== "undefined") {
const cardField = document.querySelector("#card-number");
if (cardField) {
cardField.addEventListener("input", () => {
cardField.value = formatCardNumber(cardField.value);
});
}
}
Pair it with an input such as <input id="card-number" type="text" inputmode="numeric" autocomplete="cc-number" placeholder="1234 5678 9012 3456">. Enter digits without spaces; the handler adds grouping spaces. This simple handler is most comfortable when entering text at the end. Reformatting the value on every keystroke can move the caret during edits in the middle, so a production payment form should use a well-tested caret-aware formatter. Treat the formatted value as display input and validate it separately.
Zipcode Input Masking in JavaScript
Postal-code formats vary by country, and some use letters, spaces, or hyphens. This example illustrates one six-character pattern with alternating letters and digits; it is not a universal postal-code rule. It uppercases letters, removes other characters, and displays a space after the third character.
function formatPostalCode(value) {
const characters = value.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 6);
return characters.length > 3
? `${characters.slice(0, 3)} ${characters.slice(3)}`
: characters;
}
if (typeof document !== "undefined") {
const postalField = document.querySelector("#postal-code");
if (postalField) {
postalField.addEventListener("input", () => {
postalField.value = formatPostalCode(postalField.value);
});
}
}
Use it with <input id="postal-code" type="text" autocomplete="postal-code" placeholder="A1B 2C3">. The formatter accepts letters and digits in any position; the placeholder communicates an example shape, while the function only formats characters. Adjust the character rules, grouping, and length for the country and address data your form supports. Do not use this illustrative format to reject codes from other regions.
Telephone Number With Parenthesis Input Masking in JavaScript
The following formatter assumes a ten-digit North American national number and displays it as (212) 555-0123. It accepts digits, discards additional digits, and adds punctuation as groups become available. It does not handle country calling codes, extensions, or other national numbering plans.
function formatNorthAmericanPhone(value) {
const digits = value.replace(/\D/g, "").slice(0, 10);
if (digits.length === 0) return "";
if (digits.length < 4) return `(${digits}`;
if (digits.length < 7) return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
}
if (typeof document !== "undefined") {
const phoneField = document.querySelector("#phone-number");
if (phoneField) {
phoneField.addEventListener("input", () => {
phoneField.value = formatNorthAmericanPhone(phoneField.value);
});
}
}
Pair the script with <input id="phone-number" type="tel" autocomplete="tel-national" placeholder="(212) 555-0123">. The input event also runs when someone pastes text, and the formatter keeps only its digits. For an international form, choose a format from the user’s selected country or use a phone-number library that handles numbering plans and caret movement; this fixed example is not a general telephone mask.
Customize the Input Masking for Different Fields in JavaScript
To adapt a mask, change both the formatting rule and the field’s placeholder so they describe the same shape. This example formats a four-digit department code, followed by a hyphen and two digits. Its formatter accepts digits only and adds the hyphen after the first group is complete.
function formatDepartmentCode(value) {
const digits = value.replace(/\D/g, "").slice(0, 6);
return digits.length > 4
? `${digits.slice(0, 4)}-${digits.slice(4)}`
: digits;
}
if (typeof document !== "undefined") {
const departmentField = document.querySelector("#department-code");
if (departmentField) {
departmentField.addEventListener("input", () => {
departmentField.value = formatDepartmentCode(departmentField.value);
});
}
}
Use <input id="department-code" type="text" inputmode="numeric" placeholder="1234-56"> for this rule. For a different field, decide which characters to keep, how many to display, and where separators belong; then update the placeholder to match. A placeholder is a visual hint, not a formatting rule. Likewise, an HTML pattern checks whether a submitted string matches an expression, but does not insert characters while the user types. Keep formatting logic and validation logic separate, and validate the completed value for the actual requirements of your form.