I wrote some js to handle decimal input while typing. I have not found a library that did this decently. If anyone is interested I would appreciate feedback (preferably on the github page).
I’m on mobile currently, so I can’t do a thorough review. Just glancing at the code, nice work. It’s clear and concise. It also proves that js needs a std lib.
The only thing that stuck out immediately is that you need to decouple from the DOM API and make it a proper npm lib that is distributed already transpiled to ES5.
Thanks! Any tips on decoupling from the DOM API? An article or a github page where it’s done right?
- Behaviour on digit keydown
With nothing selected
- If the cursor is in the integer part on a position immediately left of the first digit and the integerpart value is zero (or -0) replace the zero and put the cursor one position to the right
This aspect could take some people by surprise.
If I deliberately aim the cursor to the left of the zero to type “1” with the intent of having a “10” I’m greeted with a “1”.
This rule is probably a consequence of forcing a value in the field - it’s impossible to have
value === '' to in indicate an unspecified, optional value.
Also as far as I can tell the
value attribute is ignored, so the initial
value is always 0.
preferably on the github page
You may have reasons for doing it this way - so I can’t really have an issue with it.
Most as-I-type-validators-with-invalid-key-blocking do confuse me while I’m typing and editing. Usually they are in my way.
Even worse, many of them deny to accept copy-pasted inputs and mangle it.
Lets say I have some german formatted number with decimals (1.024,99 € => One thousand twentyfour Euro and ninety-nine Cent). Copypasting that from the bill to your input field will probably leave me with one Euro and 2 Cent. A lot of manual editing necessary to get it right again.
Try mine and paste the 1.024,99 without the euro sign (just download the .html and open in in f.e. chrome). It works. Pasting the value without thousands separators also, the thousands separtor will be added to the input value. It does not delete the value of an input with an invalid keystroke, it just does not echo the key. I’m used to a decimal input that works about this way in the gui desktop applications I programmed for 20+ years. In some ways I improved it a bit, in some I let out some handy functionality as it would cost more work. I have never seen a decimal input that works neatly in web applications.
Thanks. I’ll sleep a couple of nights over this one. I have not thought about it thoroughly, this one is copied from the workings of the desktop gui development environment I programmed with for 20+ years. While retrying this environment I see that it replaces the last digit of the integerpart before the decimal separator always when the cursor is put left of it, even if there are more digits in the integerpart. At other cursorpositions (except right left of the decimal separator) in the integerpart the digit is inserted when the max number of digits is not exceeded. A small riddle…
There was recently a library submitted to hacker news: https://nosir.github.io/cleave.js/. There are some interesting comments about not using this https://news.ycombinator.com/item?id=19233637 because it can be very confusing for a user.
I mostly agree with this. I’ve also done format as you type in the past, but given up on it and switched to doing a validation/transformation after the user is done (and also saving the original content so the user can edit easily).
disclaimer: I haven’t tested your library.
I’m used to desktop applications and find the format as you type at least in the case of a decimal handier than validation/transformation after the user is done. Just try my test html before sending a judgement. It is a lot of work to get it right because there do not seem to be decent libs for this and I have never seen it work in a to me acceptable way on the web. I often found desktop gui’s offering a better ux than web apps.
Thanks again for your mindfullnees. I’m going to change this requirement + the implementation. I think I found out why it works this way in my desktop dev environment. For decimal input you can assign a format property like ‘->,>>>.>>9.99’ (you can find equivalents in other desktop gui dev environments, maybe also in visual form designers for mobile) which is equivalent to numDecimals=2, maxDigits=9, allowNegativeSign in my implementation. The 9 in that format says a digit is always shown, default is 0.00 in case of the shown format (or 0,00 in Europe). For 9 in the format the rule is: replace this number when the cursor is left of it and a digit is typed. Makes sense for the decimal part, and for an integer with format ‘999’ for example, but not in case of a decimal where there are more than one digits in the integer part while the last integer digit is formatted with a 9.
I tried numeral formatting in https://nosir.github.io/cleave.js/. It’s unintuitive and you can even create nonsense values like 1,888. (a number with a decimalseparator at the end). I can understand the rejection when only looking at this input.
Here some research results and conclusions on the value of auto formatting credit card number input while typing: https://baymard.com/blog/credit-card-field-auto-format-spaces as some question this value. I have btw changed and implemented a requirement change in my github project triggered by Peer’s remark. I’m still wondering about factoryd 's remark “you need to decouple from the DOM API” . Maybe a dumb question, but why would you do that?
The logic might be useful outside of a direct dom manipulation context, e.g. in frameworks like react or vue, where the framework handles all the dom updates for you.
Ah! Thanks, I’ll see what I can do about it.