To reproduce:
Yeah, this is something annoying for formatting lib, will keep this issue open. Not sure if this can be totally avoided though.
@nosir You have to use input.selectionStart to move the cursor, but there is a lot of stuff going on: handle selections, check if there is a separator etc. It's not impossible, tho.
Actually this is possible by storing the cursor's position. I did it once on my website.
@IonicaBizau actually has the right idea on this:
input.selectionStart pointinput.selectionStart _and_ input.selectionEnd to the saved index + additional charactersThe biggest breaking edge case to worry about in this case is people pressing backspace or delete over a non-numeric character. Pretty much nothing happens except their cursor snaps to the end and with the solution above it will just stay in the same place! That's a little more complex to solve every case of but it's still not that bad.
Let me know if you want me to throw together a pull request for this!
+1 for this. Love the library, but really annoying if you mistype something and need to go correct a previous character
@isaacnass The selectionEnd should be stored too (imagine the user selecting the text and pasting/editing there the snippet). Always (if I'm not wrong), after editing the selectionEnd should be the same with selectionStart, otherwise, we would end with selected text.
@IonicaBizau I actually thought of this at first and changed my comment away from it. The manipulation is happening after the field changes, at which point if the user pasted or added characters or whatever there won't be text selected, so the selectionEnd point doesn't really matter.
You are right though that selectionEnd and selectionStart should both be put at the same point, good catch!
Hi, guys, thanks for providing the solution, it looks promising. This definitely needs to be tested very much, and make sure it doesn't break any behaviour for all the current options (prefix, delimiter, etc...).
@isaacnass we will get @nosir implement this first, will let you know if we have any problem.
Been looking into input formatting libraries myself. Seems most are susceptible to this. Make a selection partway through the input, type to overwrite and fail.
It's funny that I had to implement from scratch a small functionality like this these days and I'm happy to see a tiny module doing which should do that. 馃殌
I assumed to be quite simple but then when I realized how complicate is to handle the input selection, I just disabled the selection on the input. 馃槀
Not very good UX there @IonicaBizau
@rickysullivan Well, I mean it's still better than just jumping the cursor in a weird place. The user clearly sees that they cannot select the text.
Actually, this is why I'm interested to see a fix for that. 馃榿
We're all keen to see a fix.
I think not formatting an input would be better UX than not being able to select the value.
@rickysullivan I implemented it for a card number and expiration date. People shouldn't copy-paste these values anyways.
@IonicaBizau right.
Not sure how much helpful this is, but vanilla-masker don't have this bug and here is how they handle selection.
I implemented this a while back for an "input mask validator" directive in an old Angular project.. I don't have any time right now to help with a PR, but I can share that implementation.
Sorry for the Angular and CoffeeScript, but almost all the logic is separated into simple functions below any Angular stuff: https://gist.github.com/spicydonuts/303ff39c10af8a5933e56279794453a6
Putting in my two cents here: inputmask-core has a decent abstraction for cursors and selected text. I've been working on a comma number input (my specific use case only needs US number formatting) for the past day and treating inputmask-core's methods as an interface (like in Java or Go) works very well.
Not sure how much helpful this is, but vanilla-masker don't have this bug and here is how they handle selection.
I just tried the VanillaMasker Demo Page. It's all sorts of borked. Quite possibly some of the worst input behavior I've experienced for a masked-input library.
@rmm5t that is why I am trying to move away from it, but this one bug they don't have.
@vicentedealencar from what I was experiencing it appears they do have the bug.
Could be a race condition happening so whatever fix they have in place is either firing too soon, or too late for me.
+1 on this
Would be great if we could find a way to prevent that :/
Is there no hope anymore?
I'm on it.
This thing needs to interpolate the native behaviour a lot, and so far, many glitches. Not to mention the increase of the code.
The idea is, if the fix can only partially solve some cases, or still acts buggy. We'd rather not to bring it in at all.
So please be patient and do not put too much hope in :p Cheers.
Currently, this bug breaks user input in _all_ cases where the user edits the contents of a field.
Partially solving some cases is surely better than leaving it broken for all cases?
I consider this a bug rather than an enhancement.
Honestly, I think this fix has too many things to consider, anyone who would like to give a try, please feel free to go.
The way to get / set input cursor position is straightforward, forget about legacy browsers, we can just use:
input.selectionStart and input.setSelectionRange(pos, pos); to get / set.
The annoying part is to move the cursor.
First thing, we can store the cursor position when keyup happens, then eventually, the field value is updated here:
https://github.com/nosir/cleave.js/blob/ec28c4e7dc365395449146c105f8e396ff8caf8c/src/Cleave.js#L266
I guess after this, the stored position should be somehow updated.
Basically, cursor position needs to be calculated:
Any news? This bug is terrible to the user experience.
I am storing the cursor position here ok: https://github.com/bn-l/Input-Mask. I am saving it on keyup and detecting selections with "start !== end?". Could this work with this code? If so maybe I can modify this to remove this bug.
This repo, was a bit more ambitious: A mask within the input that does not change (no matter if pasting, cutting or undoing). I have given up though because I can't get redo working. All vanilla JS.
Need a fix for that :(
One of the proposed PR are not OK for you?
Hi guys, an update for this 馃帀:
Finally, 2 PR https://github.com/nosir/cleave.js/pull/161 https://github.com/nosir/cleave.js/pull/150 have been merged to master, and they did solve most of the problems.
Thanks @reborg & @mdziekon 馃憤
I've created an issue https://github.com/nosir/cleave.js/issues/219 based on the fixes, will follow up.
Most helpful comment
@IonicaBizau actually has the right idea on this:
input.selectionStartpointinput.selectionStart_and_input.selectionEndto the saved index + additional charactersThe biggest breaking edge case to worry about in this case is people pressing backspace or delete over a non-numeric character. Pretty much nothing happens except their cursor snaps to the end and with the solution above it will just stay in the same place! That's a little more complex to solve every case of but it's still not that bad.
Let me know if you want me to throw together a pull request for this!