Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
nick-michael opened this issue Dec 8, 2019 · 36 comments · Fixed by fabOnReact/react-native-improved#16
Labels
Bug Component: TextInput Related to the TextInput component. Never gets stale Prevent those issues and PRs from getting stale Platform: Android Android applications.

Comments

@nick-michael
Copy link

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

@react-native-bot react-native-bot added Component: TextInput Related to the TextInput component. Platform: Android Android applications. labels Dec 8, 2019
@bezenson
Copy link

Yeah. The same issue! On iOS all works fine

@ghost
Copy link

ghost commented Jan 31, 2020

Same issue for me....

@laraferroni
Copy link

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

@YeshanJay
Copy link

Any luck finding a workaround for this??

@simon-davies-avtura
Copy link

simon-davies-avtura commented Apr 16, 2020

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
Copy link

ghost commented Apr 17, 2020

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.

@arthurolga
Copy link

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.

@fabOnReact
Copy link
Contributor

seems similar issue to #11068 (comment)

It is difficult to fix this issue related to Rich Text, more info in Pull Request #27757

@stale
Copy link

stale bot commented Aug 24, 2020

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 stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Aug 24, 2020
@jamesdarabi
Copy link

This issue is still present in React Native version: 0.63.2

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Aug 27, 2020
@lorenamelor
Copy link

I have the same problem.

@arthurolga
Copy link

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

@fabOnReact
Copy link
Contributor

Hello ReactNative Developers! 😃

I just prepared Pull Request #29070 that seems to solve this issue

PREVIEWS OF THE BUGFIX

BEFORE AFTER

You can contact me by email at fabrizio.developer@gmail.com

Please head over to the Pull Request #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 🙏 ☮️ 🏖️

@fabOnReact
Copy link
Contributor

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

To answer the question of when the pr #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:

@infinitbility
Copy link

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

@jarrisondev
Copy link

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
Copy link

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

@montoyadamien
Copy link

Any news on a fix ?

@jtvargas
Copy link

jtvargas commented Oct 6, 2022

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

@lay-mand
Copy link

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

@toviszsolt
Copy link

toviszsolt commented Jan 31, 2023

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.

@jukkahuuskonen
Copy link

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='john.doe@xyz.com...'
  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='john.doe@xyz.com...'
  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.

@toviszsolt
Copy link

@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.

@jukkahuuskonen
Copy link

@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.

@toviszsolt
Copy link

@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().

@jukkahuuskonen
Copy link

  • 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...

@Productivix
Copy link

Productivix commented Feb 8, 2023

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)

@github-actions
Copy link

github-actions bot commented Aug 8, 2023

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 github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Aug 8, 2023
@Productivix
Copy link

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

@github-actions github-actions bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Aug 9, 2023
@cortinico cortinico added the Never gets stale Prevent those issues and PRs from getting stale label Aug 9, 2023
@shindenitish
Copy link

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

@fabOnReact
Copy link
Contributor

Do you still experience this issue?

I have four years of experience maintaining facebook/react-native and I specialize in the Text and TextInput components. I currently have 58 facebook/react-native PRs.

If you still experience this issue, I will prepare a patched release with the fix.

Thanks a lot

@Productivix
Copy link

Productivix commented Jan 17, 2024

hi, yes on
RN 0.73.2 , with code :

const [filter, setFilter] = useState('');

<TextInput
              onChangeText={text => setFilter(text.toLowerCase())}
              value={filter}
              placeholder="post filter"
              style={CommonPrxStyles.inputWoWidth}
              maxLength={15}
            />

autoCapitalize="none" solve the problem for 1st letter if you don not force to uppercase.

The problem is :

  • double 1st letter if uppercase : ex: "Fg" gives "ffg" but "fg" remains "fg" and "Fgh" gives "ffgffgh"
  • "fghK" gives "fghk" but "fghKl" gives "fghkfghkl"
  • no effect on lowercases : "fghj" gives "fghj"

@Productivix
Copy link

You have the same behaviour with the code that delegates the 'toLowercase' function elsewhere :

const [filter, setFilter] = useState('');

useEffect(() => {
    console.log('filter:', filter);
    if (filter != filter.toLowerCase()) {
      const replic = filter.toLowerCase();
      console.log('replic:', replic);
      setFilter(replic);
    }
  }, [filter]);

<TextInput
              onChangeText={text => setFilter(text)}
              value={filter}
              placeholder="post filter"
              style={CommonPrxStyles.inputWoWidth}
              maxLength={15}
              autoCapitalize="none" //bug of double 1st letter-still in 0.73.2 - facebook/react-native/issues/27449
            />

you get in console with typing "fgHj" :
LOG filter: f
LOG filter: fg
LOG filter: fgH
LOG replic: fgh
LOG filter: fgh
LOG filter: fghfgHj
LOG replic: fghfghj
LOG filter: fghfghj

it as if there is a state inside the Textinput that is emerging back with an old memory not updated.

@fabOnReact
Copy link
Contributor

This PR is included in the react-native-improved library:

react-native-improved

  • Supports ONLY react-native 0.73.
  • Supports only old architechture (new architechture is WIP)

Set-up

In package.json

 "scripts": {
+  "postinstall": "yarn run react-native-patch"
 }

Then

npm

npm install react-native-improved --save-dev

yarn v1

yarn add react-native-improved --dev

@Productivix
Copy link

Thank you but :
in "react-native": "0.73.4",
with the useeffect written in this beginning, it is correct, without still not.
And only yarn add react-native-improved --dev is accepted , "postinstall": "yarn run react-native-patch" generate an error.

@fabOnReact
Copy link
Contributor

The lib supports only 0.73 now, ill publish support for 0.74 soon thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Component: TextInput Related to the TextInput component. Never gets stale Prevent those issues and PRs from getting stale Platform: Android Android applications.
Projects
None yet