Hacker News new | past | comments | ask | show | jobs | submit login
Cleave.js – Format input text content when you are typing (nosir.github.io)
456 points by octosphere on Feb 23, 2019 | hide | past | favorite | 140 comments

When I’m just trying to get past a signup form, please don’t make me re-learn a new way to type. Here, the delete key does something other than delete the last keypress. For example, typing 20199<delete>11 gets me 2019/01/1 because it helpfully autoinserted the 0 before the 9 and didn’t undo it.

Filling in a form is never delightful. It’s a tedious interruption in my flow. Just let me get past it with minimum cognitive load.

On Firefox mobile, the backspace key can't delete the automatically inserted slashes. Type in 2019 09 > need to change month from 09 to 02 -> backspace key just doesn't work -> need to click on the textbox between the 9 and / to position cursor and then press backspace.

Would a normal person try to do that or would they just reload the page and start the whole form over again? Or would they just leave the website and never come back?

Usability errors/barriers like this on high-profile sites have caused millions in lost-revenue.

Many people just abandon their intended action when simple usability things are not right because your sales experience is sorta a "first impressions" thing (bit of a generalization but yea).

In Orfox after a few tries I managed to hit backspace twice quickly enough to remove a slash. Not a fun game, please don't use things like this if you're considering it!

A much simpler approach is to show in realtime what computer will interpret of current input without changing the input, instant feedback is a much more better approach to improve quality of input.

This sounds like a cool idea, like sibling I'd also love to see a good example of this :)

Do you have an example of good integration of this? Interesting.

I found this library many moons ago when looking for a credit card formatting solution.

It had so many bugs when I tried it, and it has at least as many now.

For example: in the first demo, type the card number 1234567812345678. Works nice, eh? Now try again with 1233567... oh wait, let me go back and change that second "3" to a "4". And it's broken.

I agree with you in the general sense. However, the credit card entry is nice. It doesn't change what you'r typing, it just adds extra information (spacing, which card type). Trying to type in credit card info w/o the spacing is really annoying.

Credit card forms are probably the most over-engineered inputs, majority of which lead to break my browser autocompletion.

I beg to disagree. It's just a number, like any other number. And not even that long, really. Instead of adding something automatically, it would be much better to allow users to put space if they wish so and remove it when processing. Everyone is happy and when users see space there actually is space there.

the problem is mobile keyboards.

pulling up a numeric keyboard to enter a cc number is helpful, but also lacks a space key, making it hard to viaually verify a 4-4-4-4 pattern. yes, there's luhn, but that doesnt work until you're finished (same problem with formatting post-entry, eg onblur/onchange)

for entering a date, most numeric keypads lack /.

thankfully, phone entry is mostly covered with type=tel. which is numeric + symbols, so i end up using it as a hack for some other numeric types, as suggested on SO.

i would rather just type big numbers instead of fumble with symbols or tiny keys on a full keyboard for numeric inputs.

> the problem is mobile keyboards.

So much work is put into making various pointless design gimmicks recognize whether they're displayed on mobile vs. desktop. Why not recognize whether the user is on mobile (and thus likely has crappy keyboard), and conditionally enable those convenience factors?

Also, I feel this problem was solved 20+ years ago with CD-key entry boxes. You'd have a row of text boxes, 2-4 characters long each, but they behaved as if they were one large text field - the focus correctly jumped between the boxes as you wrote or erased stuff.

> CD-key entry boxes

Unless you missed one character and then everything was misaligned and it wouldn't let you just insert one in the middle so you had to delete everything after that point and start over. Meanwhile, your pirate friends were already at level 10.

Nah, the ones I'm thinking of were made of native Windows text field controls, so arrow keys & all worked within them (and AFAIR transparently moved between them), and Tab/Shift+Tab behaved correctly too.

> the problem is mobile keyboards.

No, that's just the default iOS keyboard, meaning the problem is Apple. My Pixel's keyboard sensibly has a space button, as do most 3rd party keyboards on iOS.

there are actually several variants of keyboards on all devices (not just numeric or alphanumeric). the phone entry keyboard is different, and there are a couple others. it's not just iOS.

to make the right one pop up in ios you have to do stuff like pattern=[0-9]*, but that becomes restrictive, too.


Exactly. Most of the "shortcuts" are anything but. If the input/form is messing with user input (as opposed to the formatting of user input), it's doing it wrong.

My Google-foo is failing me: isn't there a site that catalogs UX/UI anti-patterns? This library edits what the user types in real time, which is a serious anti-pattern because it causes users to compound mistakes. I would call it the "overzealous autocorrect" antipattern.

For example, if I want to type in the date "2017-03-30", but I accidentally type "2017-02-30", this library silently changes the day in addition to the month, leaving me with "2017-02-28". I suppose you could use this to illustrate how fallible humans are, but if your goal is to minimize errors, you simply can't autocorrect number fields. You must show error messages.

I have to deal with exactly this issue at work on a project that emulates spreadsheet behavior for number formatting. I learned immediately that you have to format on blur, because anything you do to the input value while the user is typing will move their cursor to the end of the input, and no amount of clever prediction will put it back in the right place in all cases. Always format on blur unless you want your users to hate your app.

You can detect where the cursor is before editing the input value, and place it in the correct place afterwards. This is a pretty basic trick used in many different places, including by Cleave itself.

I think my comment has been validated by the dozens of comments here complaining about broken inputs. I didn't say it was impossible; the basic trick only works in simple cases and the edge cases are numerous. If I implement a feature and it causes even one person to bounce, it's a failure.

Well, yeah, Cleave.js isn't a very usable example, as the dozens of comments are proving. But it proves that it's _possible_. Your comment is saying that it's impossible:

> no amount of clever prediction will put it back in the right place in all cases

If you're instead changing your argument to say that it's impossible to do _well_, that's a different argument which I also disagree with: most implementations of tab-completion definitely have more fans than opponents. Not to mention keyboard shortcuts like Cmd+I to bold, or Cmd+B to italicize. Or even OS features like copy/paste. Many features require modifying the contents of a textbox, and it's far from impossible to do well.

Tab completion is different - it's explicit, you have to choose a completion. Bolding, italicizing, copying, pasting, etc. are all explicit actions here.

This here is implicit alteration of user input, and the real question is not whether it can be done correctly (in this case, I vote for "maaaybe in theory; impossible in practice"). The real question is why do it at all? It only confuses and irritates people, which makes them make more errors and also break their flow.

(Hell, it's not an issue if that's just one field on a random sign-up field of some fly-by-night shop. But those "brilliant" UX ideas tend to find their ways to software people use for work - say, managing listings in ecommerce shops. There, such ideas cause many people to lose a lot of time, and by extensions their employers to lose a ton of money.)

Why do it at all? Because users like the feature, because the grouping numbers makes typoes easier to spot, etc.

If you want to narrow it down to implicit alteration: Syntax highlighting is implicit alteration. And people love it.

So are a lot of WYSIWYG features, like Enter inserting a new paragraph or a new bullet point depending on context. Or tab completion itself, in the sense that it replaces the "insert tab" feature of the Tab key. Or URLs automatically transforming into links.

Explicitly with regards to Cleave.js-style auto-formatting, I personally like it (for the same reason I like syntax highlighting) and I assume many other users do too. Someone further downthread mentioned an AB test showed improved conversions:


> If you want to narrow it down to implicit alteration: Syntax highlighting is implicit alteration. And people love it.

That's only a change of formatting that's otherwise inaccessible to the user. Effects like colors and bold/italics aren't part of the code, users can't and won't try to insert them manually - they're an extra data channel, orthogonal to what users type in, and thus free for the application to use.

You want Cleave.js-style implicit? Think automatic autocorrect on Windows and MacOS. That one generates quite a lot of justified criticism - besides being a huge annoyance when dealing with proper names, brand names, peoples' names, addresses, etc., it can create life-threatening situations[0].

> Someone further downthread mentioned an AB test showed improved conversions:

They did, but I honestly don't buy it - not without knowing much more about the scope and methodology of the test in question (see my response somewhere in that thread for details). "A/B test told us that" is the new "I was only following orders".


[0] - https://twitter.com/slatestarcodex/status/944739157988974592...

> If you're instead changing your argument to say that it's impossible to do _well_

What? I didn't change my argument, that's what I said in the original comment you replied to.

All of your examples are things that _don't_ happen while you're typing. If you want to dispute my statement that all formatting should happen on blur, fine; you can expand that to include any time the user isn't typing. The issue is when you format the text while the user is actively trying to enter it, you'll mess up the cursor position and easily get into a situation where you can't add or remove a character for some reason because the formatting considers whatever you're trying to type invalid. And you'll also notice that I explicitly said in my original comment that you can't get it right _all_ of the time, and those times when you do get it wrong prevent the user from completing their task because of a superfluous feature. This is terrible UX and once this happens to a user they will never trust your software again.

Hm, I think we might have just misunderstood each other.

I originally thought you meant it was impossible to fix the cursor position after it was messed up. So I was just saying it _was_ possible:


(Which _can_ be done seamlessly while the user is typing.)

So everything since then felt like moving the goalposts. But I think in the end that was just a misinterpretation.

I mean, I do also disagree that it's impossible to do well, but in hindsight that's not really something I want to argue about further.

I’ve spent tens of hours trying to create inputs which do this in an intuitive manner but I have always failed. There is always some edge case where it’s nearly impossible to determine user intent.

“Input Masking” is a UX design pattern.

The implementation of the date field mask could be better.

>isn't there a site that catalogs UX/UI anti-patterns


I'm sorry to say this is everything I hate about "modern" UI.

It looks fantastic, but, for example, the YYYY/MM/DD field, I can't just write 19/2/23 or whatever (explicitly entering the delimiting slashes), I have to follow the prescribed format, 2019/02/23 (oh, ok thankfully 2 gets filled to 02 automatically).

Try 1/20 in the MM/YY field. Doesn't work.

It seems fairly simple to fix; when the user types a delimeter, trust them.

> I can't just write 19/2/23 or whatever (explicitly entering the delimiting slashes), I have to follow the prescribed format, 2019/02/23

I think this is exactly the point: to guide users toward inputting data in a standard format.

I would say it's forcing users to follow the exact format, not guiding them.

But then why does 2019/2/24 get automatically expanded to 2019/02/24 (adding the leading zero to the month), but not 19/2/24? As I said, it should be a fairly simple change to respond to delimiters, and marshal the input into the required format without forcing the user to slavishly follow the exact prescription.

But if the intent is to do that, then it's a trend I do not agree with at all.

Yes, that is the point

Yep, I encountered the same issue and became frustrated within seconds. From a user's perspective: I'm trying to enter a character which makes perfect sense in context, but the key press is ignored. There's no reason to restrict the user's actions in such a way.

> Try 1/20 in the MM/YY field. Doesn't work.

i've never seen a card that specified expiration month with a single digit. google images for "card expiration" does not bring up any examples either. a placeholder="MM/YY" should make it clear that both are needed.

To humans, 01 is the same as 1. To computers, there's two integers separated by a slash.

While it's true that there's a leading 0 on the card itself, there's no reason not to just split on the / and convert both sides to integers.

It depends on the human. Some humans might interpret "01" as one yes, but others will see it as a "zero-one".

FYI Firefox mobile was unable to enter dates in January.

I agree this is bad practice. I have similar code in an app I'm writing right now, I also didn't consider the usability issues or wierd delete cases. Gonna remove the code after reading this thread.

Falls under trying to be clever.

I think slightly increasing the space between groups of numbers might be acceptable? Anything that magically inserts characters seems to be problematic.

yes, but this is what people write when filling out paper forms, showing that they consider 0 suppression the norm.

I hate this idea. Why does every credit form out there have to invent new ways to "format" credit card numbers and do fancy stuff behind my back? I have to learn how every form works, because cursor keys, delete, and punctuation no longer behave like everywhere else.

Invest all the effort into reliable, flexible and intelligent parsing of whatever the user types in. Even in 2019 I find web forms (banks excel at this) which complain about "invalid" characters instead of ignoring them.

Incidentally, this idea of "let's improve the standard user interface to make it easier for ORDINARY PEOPLE" is not limited to web forms. Browser URL fields are a playground for programmer creativity and I'm regularly baffled by their behavior: autoselecting the entire input, suggestions completing what I typed even though I never asked for it, and similar ideas.

Blow into your device's left microphone to use VISA. Blow into the right one for American Express.

Ugh! Please don’t give them new ideas!

I am seeing a lot of criticism of this library in the comments. Does anyone have better suggestions aside from “just let the user enter ‘fuck you’ for a date and ‘screw this’ for their phone number”?

I am currently using Cleave for a project where the customer unequivocally requested this kind of functionality. Specifically I need to implement phone masking, date masking (no calendar pickers except native mobile ones allowed), and number and currency validation and masking. Cleave was the least opinionated library of its kind that I found.

I would prefer a generic <input type="text"> or <input="number">. Choose the one that gives me the best input experience on mobile. <input="email"> if it's email for example.

I would then prefer some live validation JavaScript that highlights if my input is wrong and tells me what it think is wrong but does not mess with my input.

Ideally the JavaScript validation does not warn me in until I leave the field because if say I'm typing a phone number and after 1 digit the field turns red, to me that feels like shouting "Hey IDIOT! ONE DIGIT IS NOT A PHONE NUMBER!" which of course I know I just hadn't finished typing.

On top of that I want the form to not be stupid. Let me enter 555-555-5555 or 5555555555 for a phone number. Let me enter 1111222233334444 or 1111 2222 3333 4444 for a CC number. Let me enter 01/19 or 1/19 for an expiration date. Trim whitespace on submission too. Don't force me to jump through hoops the code should be smart enough to deal with. Don't correct this kind of text in the field, correct it on submission. If something is ambiguous then add that to your validation message.

Don't format on keypress. Ideally, give the user feedback on their input while they type, and disable saving until the field is correctly formatted. If you must have automated formatting, do it on blur instead.

If a user is gonna write that and you force him to write a proper number he'll give you a fake one and you'll waste time sending marketing SMS and calls

That's usually how I give my email to access free public wifi:


     Invalid email


I agree, however, if the user did want to enter their phone number and they did not notice a silly error because of how it was entered, then you've lost an opportunity.

We are seeing this lib as users who get frustrated with marketing forms. There are other use-cases out there. I work with non-profits, where they may not have the budget for fancier validation, so this helps a lot.

What I am working on is not marketing. Users don’t really have the option of fake numbers or skipping forms. Not that I want it to be inconvenient. Far from it.

I don't have direct experience but libphonenumber looks pretty comprehensive: https://github.com/googlei18n/libphonenumber

yep, it's what Cleave.js uses for phone number formatting.

Validate that the content is correct, but never automatically format text.

It may be possible, but I have yet to see a perfect implementation.

GitHub has an input-mask topic with quite a few alternatives https://github.com/topics/input-mask

Cleave.js is the top starred option

Edit: the #2 library, text-mask, doesn’t seem to have the issues with the date field

No JS library will stop that when you can just POST the form directly. Best let the user input as they please and let the server do the rest.

Perhaps they should read this: https://news.ycombinator.com/item?id=19214035

Phone numbers are something you dial into a phone. They are not a alphabetic ISO code and then some numbers. Country codes and international dialing codes are NOT 1:1. North Korea for example has two dialing codes but is one county. Many island nations share the US's +1. Staphones have their own dialing prefixes that don't correspond to an ISO country code. With all due respect, this code is a disaster and it is guaranteed to lead to problems when one of these many edge cases is hit.

I type in my phone number in and THEN select the country..my number gets deleted... I hate you now

I just noticed the same bug. It’d be a little more tolerable if it auto detected that e.g. +1 meant US or suggested based on the browser locale rather than requiring you to scroll a huge list but deleting input is almost always a mistake.

This is a weird API for what it’s trying to achieve. Why make every Cleave instance use a boolean to determine its type + some related other field that varies based on which type happens to be set to true? Doing it this way prevents tree shaking from getting rid of all the methods you’re not using. If instead it was something like:

cleave.Date(...), cleave.Phone(...), etc.

then each of those constructors could implement specific options that are relevant. As it is now, you could have an onCreditCardTypeChanged() method on a date input. And if you did it in a manner like I’m proposing, you’d be able to import just the specific formatters you need, allowing your module bundler to strip out the rest.

Glad I'm not the only one that thought the API was a bit 'interesting'. I was also wondering what happens when you set `phone`, `date` and `creditCard` to `true` in the same config and pass it to the constructor? Surely this should at least be a single field, if not separate classes/prototype chains (as jsf01 mentioned).

This is very nicely done.

Personally I prefer my data entry to be a simple text field so that I can use backspace, or clipboard paste, or insert/delete from the middle normally.

Meanwhile, the UI can show its interpretation of what I entered just above the field. For example, if I enter a date field 2/25, the software could show its interpretation (02/25/2019) as I type, allowing me to quit typing as soon as the interpretation is correct. Likewise with credit cards: it isn't a big problem hitting a space bar to separate, but that's my choice.

In other words, the beautiful formatting is good, but keep the input field and the eventual rendering of the field separate.

Cute, but it looks like it's trying too hard to be clever.

Are you expecting websites to show a giant pop-up menu of 2-letter country codes to users? Or are you expecting websites to hardcode one country, and reject phone numbers which don't match that pattern? And what about extensions?

For dates, most browsers support form type="date" and the like. That's going to be better than whatever you use here.

For credit cards, it's fine, because 16 decimal digits is a universal standard. For anything else, it's going to cause as many problems as it solves.

American Express cards are 15 digits.

Ha! Shows what I know. Exceptions abound.

For phone numbers if you accept numbers without country code then you need to know it. This library correctly handles numbers with country code without specifying the country in other way.

We implemented this recently because a design that was dropped on my desk called for it, cause you know, marketing people. I was pretty happy with the library, but after reading some of the reviews on here I think we are going to have to look into how it plays on some devices and use-cases again.

Never write the form lables into the form fields. Chrome Form Autofill is a common use case for all forms. And you can not QA if everything was put in correctly if the lables are part of the form.

Nice lib. Though many of these things should simply be solved by browsers imho. As developer I simply want to render input with the type of phone and be good. Let those who provide the operating system/browser handle the details in a standard way.

Following the comments posted here, I think the proper way to format input is to split the transformations into two.

The credit card example gives us purely cosmetic changes and it makes sense to apply them in real-time so the user receives important feedback. The other type is the application of strict formatting, like in the date format example. It's really nice to infer 1992223 as 1992/02/23, but it robs some control from the user. As we're already inferring what the user is trying to say, we could show them 1992/2/23 to give them feedback and apply the transformation before sending the data, thus having the best of both worlds.

For credit card and bank accounts, Stripe Elements has some battle-tested React inputs: https://stripe.dev/elements-examples/

Prefix is broken-- put the cursor before the 'P' in the example and press any letter 6 times

Wow, horrible! I tried to select a few characters and copy and paste but it didn't copy the part I selected. instead it copied everything.

Also if you tell me the format is 00:00:00 then I'm going to type digit digit colon digit digit colon digit digit but instead you auto inserted the colon which means now my typing and correcting muscle memory is doesn't match. I typed 8 characters so it should take 8 key presses to backspace or 8 characters to go left.

Please don't use these on your site

This looks great! I typically use an individual library to format.

One request I didn’t see: money formatting.

>One request I didn’t see: money formatting.

Probably for a good reason. Formatting currency should be handled by the i18n system, because that's what it is.

Take one thousand dollars in US currency, it can be displayed as:




$1,000.00 USD

1,000.00 $

$ 1 000,00

and more. And that's not even counting negative numbers which can change their display format based on the industry it's used in, let alone the language.

Then add in other currencies in different locales, often the currency symbol is after the currency, some locales use different spacing, some don't have a decimal to their currency in common usage, some use the same symbol for different currencies ($ could mean USD or CAD or more and in some cases that can be a big mistake) and a LOT more edge cases.

Couldn't find my country for the phone number (UK). Looked for EN and UK, eventually discovered it was GB. Hard!

So, as a developer I know my country's 2-digit ISO code, and those of plenty of other countries - the point is, the general population doesn't.

Heh, no I wasn't assuming that you didn't know, I guess I was just pointing out that our ISO code is silly!


If they can fix the backspacing issue on Android this will be superb for things like UK sort codes (NN-NN-NN) which invariably are handled badly for mobile users (eg the most common case being the switching to alphabet from numeric keyboard with each pair of digits being in a distinct box)

I dont understand this. For sort codes why not just type six digits? What do you get from inserting the dashes?

Just don't, I want simple text fields where I can type without being attacked by a script. I want my autofill to work properly, I want to be able to copy paste without any strange behaviour. I want to type the delimiter. And you should be locale aware, for 2019-02-24 I would type 24.2.19. Of course you might target only the US market with your form, but the problem is that bad practices are spreading to global developers.

This is a half way solution, as you can see a lot of artifacts like when typing numbers to the time field when it is already full.

The only way to properly address this is to bring this as native HTML5 components. Then different UX paradigms, like desktop and mobile, can properly handle complex input.

This shows the shortcoming of web UI. You cannot properly address shortcomings of browsers on low enough layer. It is not an issue for native apps.

The credit card one is cool, but when I clicked it and Chrome offered to autofill my credit card, the first thing that popped into my head was "hmm, this would be a sneaky way to siphon some credit card numbers." Paranoid? Maybe. It made me ponder how I seem to be growing more suspicious of things on the modern web though.

Of course, if you were just a tad _more_ paranoid you might not be so thrilled that Chrome is storing your credit card details, your address and the passwords to every sites you trust it with in a way that is accessible to Google.

They are not just storing a hash, as that would prevent them from offering the data back to you to fill in passwords et al. And they are not just storing it locally * , I assume that is for your benefit as well, maybe if you switch computers?

* This I know from a popup on Vivaldi, which never informed me it is sending my passwords to Google for "safe"keeping, until I tried to change a password and it told me I need to login to my Google account....

I had a similar thought when trying the phone number field. I immediately thought "hey, this is what I've been keeping away from Yahoo for years..."

Can you elaborate on how you expect them to siphon Credit Card numbers? Are you speaking of the demo, or are you saying of potential users of the library?

Chrome offered to auto-fill his CC number that is stored with his expiry, name on card, and (maybe) payment address/zip... everything but the CVV, (card verification number, usually three digits).

Chrome is pretty clever these days with payment details and tries to help you keep a "wallet" so-to-speak which acts like an "autofill" feature. Do some searches around Web Payments, Payment Request API, W3C Payment Request, blah blah - let's just say it goes a lot deeper than basic autofill =)

Now for siphoning. That attack (as far as I know) wouldn't be allowed to happen. Chrome WILL NOT autofill your details or inject ANYTHING into the DOM until you've entered/verified your CVV. Due to security with how payments work there has to be some sort of a user interaction before any PAN is allowed to populate the DOM. This is to avoid his exact paranoia where a CC num gets entered automatically w/o a user's knowledge.

Since this is enforced by the browser I consider it to be pretty safe, and appreciate the feature in my day-to-day browsing activities =)

Back to the Cleave.js lib though - that thing is going to BARF on things like CC num autofill driven by browsers/etc. Trying to be super clever is just going to screw-up native browser capabilities.

I wonder if it might be used for something like formatting plaintext Git commit messages. Rules would be things like 'subject line 50 characters, then blank line, then paragraphs or bullet points of 72 characters'. That would solve a major issue with writing commit messages on the web.

It's a good library -- I've used it multiple times.

However, I'm curious why its trending at the top of Hacker News. It's been around since 2016.

Might be a coincidence but we included it in this week's JavaScript Weekly on Friday: https://javascriptweekly.com/issues/425 .. we probably saw it come up somewhere else though. One of those organic things.

Strange how Visa starts with 40-49 (10x) while Mastercard is only 51-55 (4x). I wonder if there is any logic with these prefix numbers.


>The first (leading) digit of the IIN identifies the major industry of the card issuer.

4 and 5 stand for "Banking and financial".

>The leading six digits of the card number is the issuer identification number (IIN), sometimes referred to as the "bank identification number (BIN)".

There's a list of all 1000000 possible IINs/BINs, but it's not publicly available:

>The official "ISO Register of Issuer Identification Numbers", is not available to the general public. It is only available to institutions who hold IINs published in the Register, financial networks and processors. Institutions are required to sign a licensing agreement before they are given access to the Register. Several IINs are well known, especially those representing credit card issuers.

It's a bit like IP address blocks: there's is/was some logic to it, but to actually know which bank a IIN/BIN belongs to (after mergers, acquisitions etc) you have to look it up in the register.

Thanks this answers exactly what I was looking for. One of those things you have in the back of your mind that you want to look into one day.

I like it. Never do any front-end stuff, but if I ever do I’ll look it up.

I've tried similar libraries and they all suffer the same general "I don't know what the backspace key just did" sorta issues...

Just look at the top features listed on their Github:

* CC number - doesn't actually support all PAN formats - 19 digits exist although extraordinary rare. NEVER try to do anything fancy with your CC details field because if people try to pay you and can't you've lost a customer.

* Phone number formatting - doesn't support all phone # formats. Leave this as flat text (non-numeric) or numeric for base telephone # and a text field for extension.

* Date formatting - use type="date" so you get native mobile support for date entry.

* Numeral formatting - use type="number" so you get native mobile support for numeric entry.

This comment breaks the site guidelines. Can you please make your substantive points without being gratuitously negative or disrespectful? That's always possible and always better, and it's what users here are asked to do.


My apologies - can you give me the edit capability to go in and tone that down then? Or maybe the ability to delete a comment that turned out to be controversial?

If you are a mod - feel free to delete this thread as many people in other parts of the post are echoing my sentiments, some with equally as harsh language (which you are not singling out).

That lib is technologically irresponsible to use and breaks user experience for a lot of people - I was trying to put a very clear warning out there and decided to be honest in my choice of words which many people have actually defended in this conversation.

Sure, I've marked your GP comment editable. If you could let us know at hn@ycombinator.com when you've finished editing it, that would be helpful.

We can't come close to reading all the comments on HN, so inevitably we miss ones that are as bad or worse as the ones we reply to. If you notice bad comments that haven't been moderated, the likeliest explanation is that we didn't see it. Please flag them (as described in https://news.ycombinator.com/newsfaq.html), since that helps bring them to our attention. You can also email links to hn@ycombinator.com in egregious cases.

> that one fact alone makes this trash. Like - hot garbage "screws up your conversion rates" trash.

That's a pretty hostile and condescending way to talk about someone else's work. Your statement is also incorrect if applied as a general rule. I have personally administered A/B tests for this type of masking behavior on a sales funnel and observed an increase in conversation rates (specifically for credit card number masking) on our site.

I can’t imagine ever being in a situation where I’ve already entered enough digits of my credit card number into a form to trigger some sort of formatting and then decided that I no longer want to continue the transaction because no formatting happened, e.g. because it’s just a plain old input. Is this a real thing?

It COULD be a "real thing" but 100% don't believe it until someone links a study backing up a claim like that.

Breaking up long numbers into smaller input fields CAN help with data-entry (think dyslexia etc.) but in the case of CC numbers that are of different formats (ie: VISA vs AMEX) there's no good way to "auto-format" it even if you knew the issuing PCN of the card before hand.

So - best practice generally is, ignore the dashes and let it be entered as a 10-19 digit numeric only field (or 13-19 if you're not worried about ancient cards). Just don't allow non 0-9 characters in the input via JS which is SUPER easy. Then, before submission, ensure it passes a mod-10 Luhn check to let someone know they fat-fingered it! Easy-peasy.

> there's no good way to "auto-format" it even if you knew the issuing PCN of the card before hand.

this is plainly wrong. you can swap the mask as soon as you know it's amex from the prefix. i know because we do it without any issues. it's 4-4-4-4 for visa/mast/disc and amex is 4-6-5. you have more than enough info by 4 digits to choose the correct mask in all cases.

We speculated that it was the result of less frustration when entering the card number. Perhaps the visual parity between the distribution of the numbers on the card and the form causes customers to make fewer erroneous entries. I'd be lying if I said I knew the exact reason but that is what we observed.

edit: I want to add that this wasn't a scientific study, we did a lot of A/B tests so we felt pretty confident about it but I wouldn't claim that it's a general rule.

Yep - and I'm entirely skeptical of people who singularly use a singular "A/B" study to back up any case when it comes to a real business' sales funnel. Simple input masking or not - it just wouldn't hold up in some of the board rooms I've had to stand in front of during my career... the phrase "not statistically significant" comes to mind.

And before you link that "A/B Testing is Still Needed" HBR article - know that I 100% agree with it but on the premise of testing MULTIPLE solutions under the traditional "A/B testing" model. As far as you've posited in this conversation - you guys only tried one thing. You're also admitting it's not a "scientific study" so I assume you did nothing to minimize other changing variables/conditions in regards to the input masking.

TLDR: Input masking CC fields is probably a bad idea beyond filtering non-numeric/non-slash characters. I will make that generalization. I'm not convinced you've got a valid argument against that with your "A/B test" experience.

> I'm entirely skeptical of people who singularly use a singular "A/B" study to back up any case when it comes to a real business' sales funnel.

You're skeptical of people who test their business process and follow the data where it leads them rather than taking the advice of arrogant internet curmudgeons that try to puff up their opinions with flippant allusions to statistical significance and vague appeals to the authority of "board room" war stories? That doesn't speak very well for your own credibility.

> You're also admitting it's not a "scientific study" so I assume you did nothing to minimize other changing variables/conditions in regards to the input masking.

Well that assumption might make it easier for you to justify your haughty screed but it's also incorrect (you can apply that to your edits as well). Unlike you, I'm not arrogant enough to suggest that the insights I've gained in my own personal experiences are totally absolute and generalizable to every other business and circumstance.

> I'm not convinced you've got a valid argument against that with your "A/B test" experience.

That's the aspect you don't seem to be grasping; I have no reason to care about your opinion since it flies directly in the face of the data I've seen and you haven't provided any support besides your own feelings about why formatting credit numbers kills conversation rates. At best, both our experiences are anecdotal, the only difference is I'm not a dick about it.

That all depends on what the results of that A/B test were.

If it was a 50% increase in signups over a set of 1000 cases, I’d be inclined to say it’s statistically significant.

That's assuming they tested for one masked/non-masked input only and not bundled it with other redesigns, or didn't have other confounders like a sale, or marketing campaign, etc. Also that they did run this as a trial for set amount of time, and not until Optimizely told them that the B-version is outperforming A-version (common A/B testing pitfall).

Overall, seeing the UX crap produced by many data-driven companies (Google included), I have low trust in their methodology.

Fair enough, but those are kind of testing 101, so I’d be a bit dissapointed if they influenced the numbers given.

Given my personal experience in this industry, and around adtech companies, I wouldn't. It's easy to get things wrong, and hard to verify against reality.

> Your statement is also incorrect if applied as a general rule.

I would absolutely disagree with you here. It is a generally accepted "case" that additional validation barriers on conversion experiences cause users to drop off. I have seen this scientifically proven by hard numbers time and time again over my ecommerce career.

> That's a pretty hostile and condescending way to talk about someone else's work.

Sure, I'll take that criticism. I still think it's a horrible practice and would professionally advise anyone against implementing this.

I do love how we like to rip on the JS community when it's convenient for us (npm, every new framework ever, etc) but when I say a front-end lib is "hot-garbage trash" because it breaks something as simple as backspace it's over the line...

> That's a pretty hostile and condescending way to talk about someone else's work.

When a JavaScript framework has the job of improving user input and it actually massively downgrades it so far that USER INPUT IS IMPOSSIBLE if I press backspace / or use tab / or highlight some text / or paste ... then this feedback is justified.

> It is a generally accepted "case" that additional validation barriers on conversion experiences cause users to drop off.

Presumably the introduction of validation barriers that don't guide the input to the intended form, then. How would the ability to type an arbitrary amount of numbers, or letters, in a credit card number field lead to higher conversion?

> How would the ability to type an arbitrary amount of numbers, or letters, in a credit card number field lead to higher conversion?

Sure - I'll bite. But I'm also going to point out that you're swinging to the other end of the extreme. Obviously no one in their right mind would just allow arbitrary input...

Clearly every CC number can be represented by numbers alone (by omitting the slashes). People are absolutely familiar with this and often will omit the dashes in their fields all together without any filtering of characters. Personally I key off of the "keydown" event on that field and e.preventDefault/return false on anything non-numeric. In the future, I hope the "inputmode" HTML attribute catches on with non-Chromium browsers - that would eliminate my need to do this.

After the number is entered, or (personal preference) before the form is posted, you do a simple Luhn check and show a dynamic error message RIGHT ABOVE the field saying "hey invalid CC num yo" - ideally you keep the "process" button and CC num field close to each other so this happens within the same document view without having to auto-scroll/anchor to the invalidated field.

Then, as always - ensure you have the capability to validate that data using the same rules on the back-end before it's allowed to be sent to your processor, or w/e.

There ya go - there's the "everyman's" approach to CC validation on the front-end.

> additional validation barriers on conversion experiences cause users to drop off

It's not a validation, it's simply a mask - it does not block the user, only formats what they enter into the text field.

> I do love how we like to rip on the JS community when it's convenient for us (npm, every new framework ever, etc) but when I say a front-end lib is "hot-garbage trash" because it breaks something as simple as backspace it's over the line...

Personally, I think "ripping on the JS community" is always a waste of time; jQuery still works in 2019, if you think that's the best way to go, have at it, but even in those threads I think it's pretty rare to see someone openly regard others work with such disdain as "hot garbage".

It's not just a mask.

The phone number field tries a lot of clever stuff, and when I went back and inserted digits near the start of the number it wiped half the entered digits, presumably because the temporary state didn't fit its idea of a valid phone number, so it cut off everything that was "wrong"

Changing the year in the date field destroys the months and days in some cases. Editing the month left it happily in a state with a day number of 0.

Same issues with the time fields.


When someone creates trash, calling their work trash is perfectly appropriate.

Very compelling reasoning. Using your logic, if I called your comment "trash" would that be appropriate or condescending and unnecessary?

Of course that would be appropriate (provided you also include your reasoning). Silly question.

> Date formatting - use type="date" so you get native mobile support for date entry.

I do work for GDS and while we offer a date picker for date fields in the app I work on, we also have three day/month/year fields, because date pickers are terrible for accessibility and we would fail assessment.

So is having one field that tries to magically parse what you mean into a date. Just let the user enter the numbers they want, and return a 400 when they post the form if the numbers don't make sense.

Imagine if you're blind and you try and enter a date into those `dd/mm/yyyy/` magic fields

> we also have three day/month/year fields

Yep - I actually use strategy this and type="date" both depending on what the precision requirements are =)

I've always seen the "three-field" old-school method as the most bullet-proof approach for this. Plus, validation becomes super easy since you're just doing simple integers w/ranges.

> Imagine if you're blind and you try and enter a date into those `dd/mm/yyyy/` magic fields

100% - those things absolutely break down for screen reading tech/etc. That's also why I hate these sort of "input masking" libs... accessibility is a huge concern of mine.

An interesting thing I’ve seen in user research is deaf people writing “Please do not call me, I’m deaf” in telephone fields. If your masking blocks this functionality you’re working against your users.

I've never seen that but it's a super interesting case. Reading this makes me start brainstorming ways I can be more accommodating for that situation - that wouldn't fly with certain sites I run due to US-based NPA-NXX validation on the back-end. Hmm.

personally, i don't like how this particular lib does masking. however...

> 19 digits exist although extraordinary rare.

this is an understatement. in 15 years and hundreds of thousands of transactions, i've never seen one.

> Phone number formatting - doesn't support all phone # formats.

depends on your customers. 99.99% of ours are US and CA. i would argue that a very large swath of businesses do not have wildly varied customers. we very rarely encounter anything other than 555-555-5555. but very frequently encounter 555555555 (one digit too short), cause customer wasnt required to add delimiters. yes, you can validate this post-entry, but still. post-entry errors are annoying, too.

> Date formatting - use type="date" so you get native mobile support for date entry.

unless you need MM/YY, right? [type=month] also sucks, btw.

> Numeral formatting - use type="number"

this allows symbols that aren't actually numeric to be entered in many cases.

i use a fork i made based on this: https://codepen.io/lagden/pen/XzLYJE

- it handles deleting from end in chrome and safari (i had to add a bit to make it work in Firefox, Edge, IE since they dont support [1]).

- it inserts a valid symbol even if you mistype a symbol instead of preventing entry.

- it's not perfect, and doesnt quite handle editing in the middle since it just assigns the input value. it also cannot do more complex stuff like optional chars. but it's good enough to be helpful 99% of the time and not horribly intrusive.

[1] e.inputType === 'deleteContentBackward'

Perfect example of "post your professional experiences on HN and get it ripped apart immediately."

On PANs - sure. However, I (personally) have seen odd-digit PANs but also deal with an industry that sees literally EVERY type of CC number you can imagine from all different areas of the world. Your experience (like mine) is anecdotal. But, here's the kicker - I HAVE to go with what VISA tells me to do because of their individual PCN integration requirements. If VISA is telling me "hey - it's a best practice to support all of our potential PAN formats even though 99% are going to be 16 digit" then I have to support that =)

On phone # formatting - sure. If your use case is the US and Canada things become MUCH more standardized for everything from banking data, to addresses, to (of course) phone numbers. However - I see foreign/odd phone # formats from the Americas constantly as not all the people who are here at this time have a local phone provider. (ie: travel).

I concede on number formatting - but I still use it because (IMO) it has the best/most-consistent mobile experience vs. custom libraries.

On date formatting - sure. "also sucks, btw" let's tell the users WHY it sucks because otherwise it's just trusting some random guy on the internet.

But yea - cool fork on codepen.

> Perfect example of "post your professional experiences on HN and get it ripped apart immediately."

that's why i try not to make blanket statements without qualifications about my specific case. know your customer, and all. we also have a direct phone line prominently shown in our header, so for those who do encounter issues, they simply call in to finish their order and we're happy to sell them additional things and/or give them better pricing. it's one of those odd "worse is better" situations.

our product takes some planning before purchase and is not a commodity you can buy elsewhere (we mfg). those who start the checkout process are unlikely to leave if they encounter minor issues.

if you're strictly a reseller, with no sales phone support, or have a huge international market, then sure, a lot of what we can get away with could lose a chunk of buyers to competitors for someone else.

Well, you did call this project "hot garbage trash." Surely you can take a little criticism.

Seems to me like he took the criticism perfectly well and responded in a fair, respectful way.

type="number" gives a numeric input keyboard on mobile instead of a full keyboard

I haven’t looked at this particular project, but the common “wow form JS!!!” feature that annoys me the most is when the script automatically advances to the next field when it thinks I finished the current field. Not only does this break when users finish typing and hit tab by reflex, but it makes it extremely difficult to go back and correct error.

Just use normal HTML text entry. Showing validation errors is fine. Actually interfering with input is a huge UX mistake.

> screws up your conversion rates

Well, it is called cLEAVE.

Your response is assholish. Try being more compassionate next time, some dude probably worked on this on his own time, and these issues you’ve noted can be fixed.

Sure but look at the top-level comments on here and there are words like:

* "anti-pattern"

* "overzealous autocorrect"

* "this is everything I hate about 'modern' UI"

* "I hate this idea"

* "This is a weird API for what it’s trying to achieve"

* "...THEN select the country..my number gets deleted... I hate you now"

* "Cute, but it looks like it's trying too hard to be clever."

* "Couldn't find my country for the phone number (UK). Looked for EN and UK, eventually discovered it was GB. Hard!"

* "hot garbage trash" - wait whoops ... that's mine - seems to fit right in though!

It actually took me a few consecutive quotes before I even found a neutral sounding "should simply be solved by browsers imho" comment.

"Your response is assholish" is correct, and I will agree. However I have a visceral reaction against these anti-patterns. The web is suppose to be open, and the web is suppose to be usable by a diverse group of people (including those with disabilities). I don't care if someone built this in their "free-time", this is NOT a responsible front-end lib to use.

Your logical fallacy (which encompasses your entire comment here) is: https://en.wikipedia.org/wiki/Whataboutism

This is why I very rarely comment... people on this site are far too sensitive.

Dude, just stop. We're trying to read the thread and you keep coming in with novel-sized replies about nothing!

Check your address bar. This is HN, not Twitter. Longer-form comments here are welcome.

(And it's not about nothing, it's a perfectly valid, if strong worded, criticism about a library promoting bad UX, which is unfortunately popular, and thus inflicting UX suffering on many users on the Internet.)

this is super great

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact