# Input Masking

**URL:** <https://es.discourse.group/t/input-masking/835>\
**Category:** 💡 Ideas\
**Created:** [June 29, 2021, 2:02pm UTC](https://es.discourse.group/t/input-masking/835 "2021-06-29T14:02:09Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomayac](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/tomayac/32/860_2.png) [@tomayac](https://es.discourse.group/u/tomayac)\
**Post date:** [June 29, 2021, 2:02pm UTC](https://es.discourse.group/t/input-masking/835/1 "2021-06-29T14:02:09Z")

</div>

# Input Masking

**Author:** Thomas Steiner ([tomac@google.com](mailto:tomac@google.com), [@tomayac](https://twitter.com/tomayac))

**Last updated:** 2021-06-29

## The problem

By _"restricting input using preformatted input masks (telephone number, birthday, Social Security number), or even auto-correcting input by appending or removing unnecessary characters"_ [_cf._ [Klimczak](https://books.google.es/books?id=xMJOm4ppCkYC&printsec=frontcover&dq=editions:OTpjPvHq_7MC&hl=en&sa=X&redir_esc=y#v=onepage&q=input%20masks&f=false)], **input masking** helps users enter information in forms more correctly, and existing data can be formatted adequately.  
Many implementations of input masking [exist in user land](https://bashooka.com/coding/javascript-input-mask-libraries/), proving that there is a true need for this feature.

## A beginning of a proposal

This proposal is to gauge interest in making input masking part of the language, maybe as a new interface of `Intl`. Here're some code snippets how this could look like in practice:

- **Globally agreed-on** input mask:

- **Locale-aware input mask** with customization options:

- Fully **custom input mask** with a mask function:

## Isomporhic JS™

The idea of making this part of the language would allow people to use this on the **client** and the **server**.

### On the client

For example, a **client-side implementation** could use this as follows (note that the `type="tel"` of the `<input>` does not mean _"the value is actually the input value is not automatically validated to a particular format before the form can be submitted, because formats for telephone numbers vary so much around the world"_ [_cf._ [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/tel#:~:text=the%20input%20value%20is%20not%20automatically%20validated%20to%20a%20particular%20format%20before%20the%20form%20can%20be%20submitted%2C%20because%20formats%20for%20telephone%20numbers%20vary%20so%20much%20around%20the%20world.)]):

```html
<label for="phone">Enter your phone number:</label>
<input type="tel" id="phone" name="phone">

```

```js
const formatPhoneNumber = (value) => {
  return new Intl.InputMask('phone-number', {
     locale: 'de-DE',
     countryCode: 'leadingPlus',
     areaCode: 'leadingZero',
     groupSize: 2,
   }).format(value));
};

const input = document.querySelector('#phone').addEventListener('input', (e) => {
  e.target.value = formatPhoneNumber(e.target.value);
});

```

### On the server

For a **server-side implementation** , this could look as follows:

```bash
SELECT phone FROM users_legacy;
# Returns a mix of formats from a legacy dataset:
# 00494012345678\n+494012345678\n04012345678

```

```js
const formatPhoneNumber = (value) => {
  return new Intl.InputMask('phone-number', {
     locale: 'de-DE',
     countryCode: 'leadingPlus',
     areaCode: 'leadingZero',
     groupSize: 2,
   }).format(value));
};

// Express.js YOLO example.
app.get('/phones', (req, res) => {
  const rawPhones = getPhoneNumbersFromLegacyDB();
  const formattedPhonesHTML = rawPhones.map(rawPhone => {
    return formatPhoneNumber(rawPhone);
  }).join('<br>'); 
  res.send(formattedPhonesHTML);
});

```

## Alternatives

Just leaving this to the user land is an obvious alternative. The ecosystem of input masking libraries is alive, and great implementations exist. Pulling any of those in comes at a cost for each locale that's needed, and the weight of the library itself.

Another alternative would be to add new (and smarter) input types. A recent example is the [`input[type=currency]`](https://discourse.wicg.io/t/proposal-input-type-currency/5398) proposal. The declarative burden for advanced formatting needs is not to be underestimated, though (see the above `countryCode` and `areaCode` examples). This also does not solve the issue on the server side.

## Feedback

Feedback on this early-stage idea is welcome. Please [open a new Issue](https://github.com/tomayac/js-input-masking/issues) on the GitHub repo where this was crossposted.

---

<div class="post-metadata">

**Author:** ![tomayac](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/tomayac/32/860_2.png) [@tomayac](https://es.discourse.group/u/tomayac)\
**Post date:** [June 29, 2021, 2:07pm UTC](https://es.discourse.group/t/input-masking/835/2 "2021-06-29T14:07:40Z")

</div>

(I'm a new user and can't add more than five links to a post, which means now that my first post was accepted by an admin that I can't make any modifications to it. A version of this post that fixes the syntax errors is [on GitHub](https://github.com/tomayac/js-input-masking).)

---

<div class="post-metadata">

**Author:** ![hemanth](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/hemanth/32/33_2.png) [@hemanth](https://es.discourse.group/u/hemanth)\
**Post date:** [June 30, 2021, 2:15pm UTC](https://es.discourse.group/t/input-masking/835/3 "2021-06-30T14:15:23Z")

</div>

I have personally faced challenges, especially with credit-card also formatting with a separator.  
I would like to champion this if there are no obvious objections from others on the committee.

---

<div class="post-metadata">

**Author:** ![rumkin](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rumkin/32/598_2.png) [@rumkin](https://es.discourse.group/u/rumkin)\
**Post date:** [June 30, 2021, 2:16pm UTC](https://es.discourse.group/t/input-masking/835/4 "2021-06-30T14:16:20Z")

</div>

It's extremely important to implement such standard. But I think it requires a lot of work from many different parties. It's not a TC39 problem, IMO it's more W3C. Here are the issues with plain text-to-text formatting:

1. It's incorrect to replace input value with the new one, you need to preserve caret position. So there should be some way to map old caret position to the new one.
2. It would add formatting to the value itself, so formatting would be copied to buffer with the value, what seems wrong.
3. Modifications of such text could break the formatting or lead to glitches or awkward behavior. Like adding numbers in the middle of phone number.

Also I'm sure it should support rich input to make the technology suitable for the future. Plain text-to-text conversion is good for 90s, but it wouldn't solve user-land solutions issue.

---

<div class="post-metadata">

**Author:** ![rumkin](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rumkin/32/598_2.png) [@rumkin](https://es.discourse.group/u/rumkin)\
**Post date:** [June 30, 2021, 2:38pm UTC](https://es.discourse.group/t/input-masking/835/5 "2021-06-30T14:38:22Z")

</div>

I've developed MightyInput ([demo](https://mighty-input.vercel.app/)). It's some-kind of rich input with input masking and input suggestion. It allows format values, colorize formatting and to highlight input errors right in the place where they appear. It uses hacks which I strongly don't like and would like to avoid, but it's good as an example.

---

<div class="post-metadata">

**Author:** ![tomayac](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/tomayac/32/860_2.png) [@tomayac](https://es.discourse.group/u/tomayac)\
**Post date:** [July 1, 2021, 11:20am UTC](https://es.discourse.group/t/input-masking/835/6 "2021-07-01T11:20:56Z")

</div>

Thanks, @hemanth! Super appreciate the kind offer! I'm all new to TC39, so double-value you taking the time to champion this. What would be the next step?

---

<div class="post-metadata">

**Author:** ![tomayac](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/tomayac/32/860_2.png) [@tomayac](https://es.discourse.group/u/tomayac)\
**Post date:** [July 1, 2021, 11:32am UTC](https://es.discourse.group/t/input-masking/835/7 "2021-07-01T11:32:24Z")

</div>

Thanks, @rumkin, for taking the time to reply!

- For 1.):  
Yes, caret position needs to be taken into account. This is a bit orthogonal since it touches upon the UX of form fields. I'll dig deeper.
- For 2.):  
This is what libraries like [cleave.js](https://nosir.github.io/cleave.js/) seem to do, and to me this seems right.
- For 3.):  
Yes, absolutely. Again, like 1.), I think this is super important, but orthogonal. As I wrote above, I'll dig deeper.
- For rich text:  
I see this proposal more on the level of [`Intl.NumberFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat).
- For MightyInput:  
This is a really impressive component, especially at this file size!

---

<div class="post-metadata">

**Author:** ![rumkin](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rumkin/32/598_2.png) [@rumkin](https://es.discourse.group/u/rumkin)\
**Post date:** [July 7, 2021, 7:57am UTC](https://es.discourse.group/t/input-masking/835/8 "2021-07-07T07:57:41Z")

</div>

About MightyInput seems like I've described it wrong, and it might look like the component does what it doesn't. MightyInput only allows to replace plain text input with HTML. And it lets developers to implement formatting, colorization, error highlighting, etc.

---

<div class="post-metadata">

**Author:** ![tomayac](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/tomayac/32/860_2.png) [@tomayac](https://es.discourse.group/u/tomayac)\
**Post date:** [September 16, 2021, 12:21pm UTC](https://es.discourse.group/t/input-masking/835/9 "2021-09-16T12:21:19Z")

</div>

FYI, I have presented this proposal to ECMA-402 folks, you can see the [slides](https://docs.google.com/presentation/d/1ki6f4SUGkHlot8As2RaylQuECS_w9g84bzEPeIVUyDM/edit?usp=sharing) online.
