payform icon indicating copy to clipboard operation
payform copied to clipboard

Caret moved to the end of input after change

Open agka opened this issue 5 years ago • 5 comments

Steps to reproduce

  • set up a card number input with auto formatting
  • begin to type in a card number, with enough digits to trigger formatting (eg 4242 42)
  • move caret position somewhere before the last digit, can be anywhere (eg 424|2 42)
  • delete a digit (for instance the second 4 of the example: 42|2 42)

Caret is then moved to the end of input (eg. 4224 2|).

(Edit) The same goes when adding a digit in the middle of the current value

  • set up a card number input with auto formatting
  • begin to type in a card number, with enough digits to trigger formatting (eg 4242 42)
  • move caret position somewhere before the last digit, can be anywhere (eg 424|2 42)
  • add a digit (eg. 4248|2 42)

Caret is then moved to the end of input (eg. 4248 242|).

Reproduced on https://jondavidjohn.github.io/payform/

This bug occurs as long as there are enough digits to trigger the formatting. If there is fewer chars (id est, only three digits), the caret position is not changed

Expected behavior

Caret position should not change

agka avatar Mar 06 '19 20:03 agka

Dug the issue a bit. Found suspicious behaviour in reFormatCardNumber

reFormatCardNumber = (e) ->
    cursor = _getCaretPos(e.target)
    return if e.target.value is ""

    if getDirectionality(e.target) == 'ltr'
        cursor = _getCaretPos(e.target)

    e.target.value = payform.formatCardNumber(e.target.value)
    // after `formatCardNumber()`, `e.target.selectionStart` now equals
    // `e.target.value.length`
    // in other words, there's no way to get the expected caret position
    // from the input

    if getDirectionality(e.target) == 'ltr' and cursor isnt e.target.selectionStart
        // this assignment to `cursor` looks fishy :-/
        // the cursor var will be set to `e.target.value.length`
        // the expected position of the cursor is lost
        // why not restore the cursor position with
        // `e.target.setSelectionRange(cursor, cursor)` instead ?
        cursor = _getCaretPos(e.target)

    if getDirectionality(e.target) == 'rtl' and e.target.value.indexOf('‎\u200e') == -1
        e.target.value = '‎\u200e'.concat(e.target.value)
      
    cursor = _getCaretPos(e.target)

    if cursor? and cursor isnt 0 and e.type isnt 'change'
        e.target.setSelectionRange(cursor, cursor)

Maybe related to the issue Reposition cursor when pasting full card numbers (#51)

agka avatar Mar 06 '19 22:03 agka

Thanks for bringing up the issue @agka, the cursor should definitely remain at its position with or without triggering a formatting!

ddayguerrero avatar Mar 11 '19 22:03 ddayguerrero

Hi @ddayguerrero, do you have an idea if and/or when this issue will be fixed? Thank you.

andygi avatar Mar 19 '19 11:03 andygi

@andygi I see that you have a possible PR in the works, I didn't have the chance to look it up myself but perhaps we can go over your solution?

ddayguerrero avatar Mar 20 '19 16:03 ddayguerrero

@ddayguerrero I have worked around the issue and I have fixed for LTR scenario but not for RTL and I don't think it is possible to add some test as well. But if you agree I can create the PR for this part.

andygi avatar Mar 27 '19 09:03 andygi