react-native icon indicating copy to clipboard operation
react-native copied to clipboard

Using `toUpperCase` or `textTransform: 'uppercase'` breaks on an Android controlled TextInput

Open nick-michael opened this issue 4 years ago • 34 comments

React Native version: 0.61.4 and lower

Trying to force capitalization of characters inside a TextInput is broken on Android.

  • autoCapitalize="characters" doesn't seem to do anything
  • Using toUpperCase in the onChangeText hook causes duplication of letters
  • Using textTransform: 'uppercase' in styles block causes the same duplication of letters
  • Using textTransform: 'uppercase' in a non-controlled TextInput does nothing

Steps To Reproduce

  1. Create a controlled TextInput and either use onTextChanged to modify the text to uppercase or use text transform in the styles block
  2. Type multiple lowercase characters into the text box

Describe what you expected to happen: Characters should be capitalized

What actually happens: Characters are capitalized and duplicated

Snack, code example, screenshot, or link to a repository: https://snack.expo.io/@nmi09/rn-android-capitalize-input-bug

ezgif com-video-to-gif

nick-michael avatar Dec 08 '19 17:12 nick-michael

Yeah. The same issue! On iOS all works fine

bezenson avatar Dec 13 '19 13:12 bezenson

Same issue for me....

ghost avatar Jan 31 '20 08:01 ghost

Had same issue. Adding secureTextEntry={Platform.OS === 'ios' ? false : true} seemed to fix it for me.

laraferroni avatar Mar 04 '20 03:03 laraferroni

Any luck finding a workaround for this??

YeshanJay avatar Mar 20 '20 20:03 YeshanJay

keyboardType={Platform.OS === 'ios' ? 'default' : 'visible-password'}

Seems to be the only workaround for me with Android at the moment (I've been looking for ages!). Will need some cross platform testing locally though.

simon-davies-avtura avatar Apr 16 '20 23:04 simon-davies-avtura

Really weird, it worked but I think that should be fixed asap.

keyboardType={Platform.OS === 'ios' ? 'default' : 'visible-password'}

Seems to be the only workaround for me with Android at the moment (I've been looking for ages!). Will need some cross platform testing locally though.

ghost avatar Apr 17 '20 17:04 ghost

i have the same problem. The solution by simon-davies-avtura solved it partially, but I really wanted to use keyboardType='email-address'. If there is any other workaround or a solution. I just want to display the font in lowerCase on the UI.

arthurolga avatar May 25 '20 20:05 arthurolga

seems similar issue to https://github.com/facebook/react-native/issues/11068#issuecomment-574013816

It is difficult to fix this issue related to Rich Text, more info in Pull Request https://github.com/facebook/react-native/pull/27757

fabOnReact avatar May 26 '20 06:05 fabOnReact

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

stale[bot] avatar Aug 24 '20 07:08 stale[bot]

This issue is still present in React Native version: 0.63.2

jamesdarabi avatar Aug 27 '20 17:08 jamesdarabi

I have the same problem.

lorenamelor avatar Sep 03 '20 19:09 lorenamelor

autoCapitalize={'characters'} Seems to solve the problem. https://www.reddit.com/r/reactnative/comments/jhdref/any_solution_to_the_touppercase_problem

arthurolga avatar Oct 24 '20 22:10 arthurolga

Hello ReactNative Developers! :smiley:

I just prepared Pull Request https://github.com/facebook/react-native/pull/29070 that seems to solve this issue

PREVIEWS OF THE BUGFIX

BEFORE AFTER

You can contact me by email at [email protected]

Please head over to the Pull Request https://github.com/facebook/react-native/pull/29070 and thumbs up if you like it. If you want to get this fix you can follow the instructions for building ReactAndroid or checkout my video introduction on forking react-native (patch-package does not work).

If you don't like the pr please feel free to leave a code review or comment, I'll be happy to add improvements and changes.

Thanks a lot :pray: :peace_symbol: :beach_umbrella:

fabOnReact avatar Feb 05 '21 08:02 fabOnReact

Please, is it possible to merge this PR in the next version ?

To answer the question of when the pr https://github.com/facebook/react-native/pull/29070 which fixes this issue will be released in the next version of React Native, I suggest you to follow the discussions at https://github.com/react-native-community/releases/issues by subscribing to those threads. The process of releasing a new version with a bug fix is the following:

  • an Issue is opened in facebook/react-native
  • a contributor writes a Pull Request to fix/close the react-native Issue
  • The Pull Request is merged in Master
  • For each realease (the upcoming one is 0.64.1) there will be a separate discussion on https://github.com/react-native-community/releases/issues where anyone can request a commit to be cherrypicked from master. The link need to be from the a commit from master (for ex. https://github.com/facebook/react-native/pull/29157#issuecomment-651430945) and not a Pull Request not yet merged in master :peace_symbol: :pray:

fabOnReact avatar Mar 16 '21 16:03 fabOnReact

Text transform Example in React Native

Table of content

  1. textTransform Props
  2. textTransform uppercase
  3. textTransform lowercase
  4. textTransform capitalize

https://infinitbility.com/react-native/text-transform-in-react-native

infinitbility avatar Jul 07 '21 17:07 infinitbility

i have the same issue when i want to save the value on the onChangeText function. i'm using expo and react-hook-form for handle the form.

imagen imagen

jarrisondev avatar Dec 13 '21 21:12 jarrisondev

I find a possible solution to my problem, the TextInput has a property autoCapitalize with the values 'words, sentences, characters', but the user can disable the uppercase in his keyboard so is necessary convert the value to uppercase when i want to save the data

jarrisondev avatar Dec 20 '21 15:12 jarrisondev

Any news on a fix ?

montoyadamien avatar May 05 '22 20:05 montoyadamien

The duplications of letters are still happening, RN:0.68.0 on Android when you try to use the delete function.

jtvargas avatar Oct 06 '22 13:10 jtvargas

The only thing that I can suggest for people stuck with this issue as me is that to apply TextInput's value formatting (.toUpperCase or whatever) on onBlur, so we forcibly format value after user finished typing. And don't forget about this property: https://reactnative.dev/docs/0.69/textinput#autocapitalize

lay-mand avatar Nov 18 '22 10:11 lay-mand

The issue still persists. I encountered the issue when using toLowerCase.

For me, the doubling only occurs when typing with the keyboard in capital letters. Each time a letter is pressed, the converted string is appended to the previous string for an unknown reason, instead of being overwritten.

I have now tested some cases to try to help find the source of the issue.

  • Case 1: I have removed the value property on TextInput, and I write out the value of TextInput in a Text component. The issue does not occur.
  • Case 2: The toLowerCase() function is called from within the value property of TextInput. The issue occurs.

So then, the conclusion is that the source of the issue arises when handling (internal) the value propery of the TextInput. Maybe the component has an internal state (probable) and the state handling is looks like not correct.

UPDATE - Case 3:

I've also just tested not using the toLowerCase function at all, and adding the style={{ textTransform: 'lowercase' }} property to the TextInput component. ( Because that's what a developer is. If you can't get in the door, you looks for the windows. ) The result was shocking. 🤣

  • On the one hand, the transform style really transformed the text, I mean exactly like toLowerCase, so not just in appearance, but in reality. That was really shocking to me. 🤣
  • And what I didn't expect is that unfortunately the problem persists, so this doesn't solve the problem either.

toviszsolt avatar Jan 31 '23 09:01 toviszsolt

Some notes and an ugly fix for this:

  1. It seems that unlike in regular JS this seems to change the value of the input only after launching the onChange/onChangeText-events, that may cause some update order mistakes causing this problem
  2. Since I figured the problem had something to do with timing I decided to try setTimeout on onChangeText-prop to delay the change of receiver until the next render.
const [receiver, setReceiver] = useState();
...
<TextInput
  onChangeText={value => {
    setTimeout(() => {
      setReceiver(value.toLowerCase());
    });
  }}
  value={receiver}
  placeholder='[email protected]...'
  textContentType='emailAddress'
  autoCorrect={false}
  keyboardType='email-address'
/>

This already helped the situation. Only the first letter was doubled. trying to type Boxer would change to 'bboxer' 3. after briefly looking at the TextInput.js-code I decided to try and give the receiver an empty string as a defaultValue:

const [receiver, setReceiver] = useState('');
...
<TextInput
  onChangeText={value => {
    setTimeout(() => {
      setReceiver(value.toLowerCase());
    });
  }}
  value={receiver}
  placeholder='[email protected]...'
  textContentType='emailAddress'
  autoCorrect={false}
  keyboardType='email-address'
/>

And this fixed the doubling of letters. Text is blinking a bit but at least for me it worked otherwise just fine.

jukkahuuskonen avatar Feb 03 '23 08:02 jukkahuuskonen

@jukkahuuskonen Now try writing in all caps. I think you will be surprised. The error only occurs for uppercase letters when using the toLowerCase() function.

toviszsolt avatar Feb 03 '23 09:02 toviszsolt

@jukkahuuskonen Now try writing in all caps. I think you will be surprised. The error only occurs for uppercase letters when using the toLowerCase() function.

Not sure if I understood correctly, but it works just fine with me BOXER becomes boxer no problems except for the text blinking a bit (hence the 'ugly' in the fix). Also works with swipe-typing.

Of course I've only tested it with my Sony Xperia 5ii.

jukkahuuskonen avatar Feb 03 '23 09:02 jukkahuuskonen

@jukkahuuskonen You understood well. This seems like a good temporary hack. Good job. I tried it, it works for me, but it causes another bug. Here comes the vicious circle.

  • If you delete longer (i.e. hold backspace), then very strange things happen because of setTimeout().

toviszsolt avatar Feb 03 '23 09:02 toviszsolt

  • If you delete longer (i.e. hold backspace), then very strange things happen because of setTimeout().

yup, that can be problem. Didn't notice it myself. Also, if you type too fast a similiar problem occurs. It is really something the react-native-team should fix. The problem has been around for several years already...

jukkahuuskonen avatar Feb 03 '23 10:02 jukkahuuskonen

yes I got that bug also on RN 0.70.6 the first letter is doubled with .toLowerCase() (Android) and with autoCapitalize="none" in the Text Input parameters it is "solved" (does not reaprear)

Productivix avatar Feb 08 '23 15:02 Productivix

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Aug 08 '23 05:08 github-actions[bot]

Hi @cortinico , I think it is inside React-Native, part Android that there is this bug : can you please have a look ?

Productivix avatar Aug 08 '23 11:08 Productivix

Adding autoCapitalize={"none"} and keyboard type as visible-password works. Another thing to note is don't add autoCorrect={false} with this fix.

shindenitish avatar Oct 12 '23 15:10 shindenitish