Open joewestcott opened 6 years ago
Related to #255? 🤔
It also happens with the phone field in the same example.
I think its the typical react input cursor jump issue: facebook/react#955
any workaround on this issue? I'm can't figure out how to fix the issue in this example: https://codesandbox.io/s/no20p7z3l
Not using format
and using react-text-mask worked for me:
Example: https://codesandbox.io/s/m4183xjk5j
@emartini could you solve it without react-text-mask
?
New to the code base but working on a solution, attempting to add a 3rd parameter to parse callback sending old value, if new value is shorter than the old value don't parse.
// todo: add oldValue to callback
const normalizePhone = (value, field, oldValue) => {
if (!value) return value;
const isDelete = oldValue.length > value.length
if(isDelete) return value;
const onlyNums = value.replace(/[^\d]/g, "");
if (onlyNums.length <= 3) return onlyNums;
if (onlyNums.length <= 7)
return `(${onlyNums.slice(0, 3)}) ${onlyNums.slice(3, 7)}`;
return `(${onlyNums.slice(0, 3)}) ${onlyNums.slice(3, 6)}-${onlyNums.slice(
6,
10
)}`;
`};`
@emartini could you solve it without
react-text-mask
?
@taschetto I am starting to believe that what solved this for Esteban was not necessarily the use of react-text-mask
- and was more importantly the result of doing his own input masking (by way of rendering a <MaskedInput>
component) within the render()
prop of <Field ... />
, instead of using the built-in parse
attribute (which I am hypothesizing suffers the ill effects of some state mutation/rerender cycles within the bowels of react-final-form
, as opposed to the outside handling of the masking/transformation of the user's input that react-text-mask
in Esteban's example - admittedly, I haven't taken the time yet to tweak his refenced code sandbox sufficiently to further confirm).
@erikras - Does this seem like a plausible theory/something worth investigating further?
UPDATE:
So I added a field to a fork of the codesandbox, and it appears to prove that this approach (using the Field's render prop, and effectively treating the render function like the Component prop through use of the value
and onChange
from the reference to input
) suffers the same cursor jump issue...to a point.
The only time that I can get the cursor to not jump is when the input length is less than the allowed length (in this example, less than 10 digits entered) AND when the cursor is in the last "chunk" of the value (in this example, when the cursor is to the right of the last hyphen if any have already been added). After some more playing, this seems to be tied to whenever the value is mutated from the previous (e.g., for the phone number, I input a character to turn "123" into "1234" - and then my masking mutates it to "123-4") - meaning that input.onChange()
is suffering the same ill effects of some state mutation/rerender cycles within the bowels of react-final-form
? To make this more apparent, you can even attempt to manually set the cursor position with an example like this:
onChange={(event) => {
const caretStart = event.target.selectionStart;
const caretEnd = event.target.selectionEnd;
onChange(
formatString("999-999-9999", event.currentTarget.value)
);
event.target.setSelectionRange(caretStart, caretEnd);
}}
I am hypothesizing that the state update/rerender happening within RFF is happening after the setSelectionRange()
call, so it has no visible effect. Circling back around to the react-text-mask
example above (and why it works), notice that it doesn't actually set the form field value to the masked input form (instead, it has the value of the raw input - the second field is a great example of this) - so the efficacy of the solution seems to depend a lot on your requirements (Do you just need to display the mask, or are you trying to control what gets handed off to some sort of persistence mechanism?).
See this example, in the username field: https://codesandbox.io/s/10rzowm323
Typing an uppercase character moves the cursor to the end of the line. This is only visible when the cursor has characters to it's right.