When trying to implement an upper case only input, adding autoCapitalize="characters"
seems to work on Android by setting the keyboard to be upper case by default. One can hit the shift key and then type a lower case letter.
To ensure that we only let the user enter (and see) upper case letters, I thought that I might be able to handle it by ensuring that when we update the react state of the component we capture the text in upper case.
By using a toUpperCase on top of what is a pretty standard state update cycle (i.e. a very similar update method ala the examples at https://facebook.github.io/react-native/releases/next/docs/textinput.html ), this saves the input into the state, uppercased, ready for the next render cycle. (I'm not concerned about the dangers of toUpperCase at this point.)
Unfortunately, the behaviour is a bit strange when you start typing both upper and lowercase letters, where you start getting repeated letters, e.g. if I type _AbC_, I will end up with _ABABC_, _AbcdE_ I get _ABABCDABABCDE_.
I created an example app here: https://rnplay.org/apps/t-gBOA
Note that the behaviour seems fine on the iOS simulator, but is 'wrong' on the android simulator.
or see the component below:
import React, {Component} from "react";
import {View, TextInput} from "react-native";
export class UpperCaseTextEntry extends Component {
constructor() {
super();
this.state = {
text: ""
}
}
upperCaseIt(text) {
var textUpperCase = text.toUpperCase();
this.setState({text: textUpperCase});
}
render() {
var text = this.state.text;
return (
<View>
<TextInput value={text} autoCapitalize="characters"
onChangeText={(text) => {this.upperCaseIt(text)}}
/>
</View>
)
}
}
I suspect that there's something going awry with the syncing of state between the react state and the state of the underlying components, quite possibly some case-ignoring checks are being in some places, but not others.
I've also noted during that it's more than possible to fire multiple onChangeTexts before a render is triggered, which could lead to unexpected app behaviour. This could be expected unexpected behaviour though :-)
Are there any updates on these issue already? , I am also experiencing this.
having same issue with lowercasing, every time a capital case character is entered, the text that is passed to onChangeText function contains exact duplicate of existing text plus last entered character. it happens only on android devices, on ios it works fine
Experiencing same with lowercase.
RN: 0.39.2
Phone: samsung galaxy S7
Any news on this issue?
I have exactly the same problem and cannot release without a fix...
RN: 0.42.3
Phone: Galaxy s6 edge
Is anybody working on this? Thanks.
Same issue.
RN: 0.44.3
Phone: Galaxy S8
Cannot reproduce this in emulator, so maybe something Samsung specific?
Since the rnplay link is broken, I have recreated it on Expo Snack here:
https://snack.expo.io/S1ksBZsEW
Samsung Galaxy S8 is breaking for me.
When I disable the "Predictive Text" at "Language and Input > Samsung keyboard settings" the issue is solved, but how to solve that programmatically? :/
Same issue
RN: 0.44.0
Phone: Samsung Galaxy S7 Edge
Any fix?
Same issue.
Phone: Samsung Galaxy S7 / Moto Z2 Play
Keyboards: Samsung Keyboard (with predict), Swiftkey Keyboard and Google Keyboard
RN: [email protected]
Same issue here.
Phone: OnePlus 5
Keyboard: [email protected]
RN: 0.46.2
Same issue here.
Android 7.0 emulator, google pixel hardware selected.
RN: 0.46.2
same for Samsung Galaxy
@facebook ?
What's the work around? Just don't use autocapitalize and your own?
Experienced same issue. I thought that in Android onChangeText() is triggered multiple times or so. But after checking, it's not what I thought it would be. Totally no hint of solving the issues at this moment.
Same issue here. It seems to be on any android devices with swipe / SwiftKey keyboards turned on.
I think this issue should be escalated as these keyboards come pre-installed on a lot of devices.
Same issue, I was getting paranoid cause I couldn't find the reason
For me it doesn't even matter if you set autoCapitalize
or not
Do anyone know a workaround?
"react-native": "^0.46.1",
Xiaomi Redmi Note 4
Google Keyboard
I stumbled upon the same issue. Found out the autoCapitalize
was not working due to fontFamily
specified in style
prop.
Seems like it was failing silently. Will update here, if I find anything else.
Try to set autoCorrect to false and check if problem exist yet.
It does. autoCorrect
has nothing to do with it.
I have the same issue but found a workaround for my current needs.
The issue can't be re-produce via the simulator using your keyboard.
However, if you use the onscreen keyboard, then you can see the text is duplicated.
For my case, since the user can't use a 'keyboard' except for the on-screen keyboard provided.
In adding, it only became an issue when I use the text.toUpperCase()
Thus, setting the text state in lower case and autoCapitalize="characters"
seems to work fine for my case.
Of course, if you do not want the user to ever be able to enter lowercase, then this is an issue.
PS: I specified a fontFamily
in style and autoCapitalize
still work as expected
I am facing the same issue..
Any update on this issue . I just tried to use toUpperCase on my textinput. Its dupllicates the characters.
Has anyone found a solution for this bug?, I have the same problem in all samsung that have the predictive language activated
the problem is toUpperCase() , i use
@MedinaGitHub of course the problem is the use of toUpperCase()
. We use this to enforce uppercase and this causes this bug on Samsung devices.
Not only Samsung
Not only Samsung devices and I have the same behaviour with toLowerCase()
Exact same issue as shown by @john1jan.
React Native: 0.51.0
Android device: OnePlus 3
@kasterlod Did you success with that solution?
@lucinick Yes. In newer version of react-native its fixes so you don't need to use [react-native-text-input-reset] any more
@kasterlod Is it already fixed? In which React Native version did they fix this?
@kasterlod Thank for your reply, but my react-native version is 0.44.0 and I wonder that can [react-native-text-input-reset] help me?
I upgraded my react-native to the latest version 0.55.4 but the issue still isn't solved, any advice?
Still seeing this issue with React Native 0.56.0
:(
Issue is not fixed in the newest version. At least for me.
RN: 0.57.1
Samsung J5 with Android 7
Samsung Keyboard
Duplicate message on android when typing in Vietnamese keyboard, just on android, iOS work fine.
Has problem in Google keyboard with feature suggestion, just on android, iOS work fine.
This problem still happen with capitalized letters in any situation.
😔 This issue is 2 years old, and is affecting our app
The same on 0.57.4
Appears to be working on a Samsung S7 (React Native 0.57.4) with (suggested by nathvarun):
<TextInput>
...
secureTextEntry={true}
keyboardType="visible-password"
</TextInput>
autoCorrect set to false fixed the issue for me..
Just to remember that testing it on emulators will not show the real problem, I tested on my real device and the problem occurs.
This issue still happens om 0.57.7
... Exactly as shown by @john1jan
Just to remember that testing it on emulators will not show the real problem, I tested on my real device and the problem occurs.
For me It still happens on both. =(
I've managed to find the bug and in runtime trick it to make it work...
Apparently, when we setText natively, we have two different text informations.
(AGAIN, THIS BUG ONLY HAPPENS WHEN YOU USE UPPERCASE OF LOWERCASE)
So, I've end up on inner android classes and I've noticed that the dupe of characters happens on this line:
The reason why it happens is that we have two different texts.
Let's say that we've added "a" and then after onTextChange JavaScript event, we changed it to "A"...
On the native side, even though we see "A", somehow "a" still there.
When this line is executed:
We still are going to be able to see it on the visual element displaying the correct char.(line after)
Now, after this, we should have two versions of the text, therefore, the next char will be duped as we remained with "a" inside the native component and "A" on the visual part....
Here is the proof that we remained with "a" instead of "A" inside of the native component somehow:
Now, on: BaseInputConnection.java@843, it will try to replace the text "A" for "ab":
Logically, replacing "A"@Position:1, by "ab", we will end up with: "Aab"....
(Variables at the moment:)
AAAnddd, voila:
(Our text is now "Aab")
After all of that, our text.toUpperCase(), will be fired on JavaScript side, and the method receiver on native side is: [email protected]:359
Then if we inspect getText(), this instance will be with our correct text, but somehow, it will break when changing by default Android classes...
AND, IF WE execute this line every time on the Evaluate screen right after getText().replace....
The bug disappears:
Also, to reproduce it, just drop a TextInput like this:
<TextInput ref={(el) => this.input = el} onChangeText={(val) => { this.input.setNativeProps({text: val.toUpperCase()}); }}/>
and on ReactEditText.java@381, change:
getText().replace(0, length(), spannableStringBuilder);
for:
setText(spannableStringBuilder);
@hramos, Have a look mate! =D
Removed original quoting...
I guess this problem has nothing to do with react-native itself...
Happens to me on all Samsung devices (browser, with "Predictive Text" enabled) when I'm trying to make toUpperCase
and then put mutated string in the value
of the text input.
Appears to be working on a Samsung S7 (React Native 0.57.4) with (suggested by nathvarun):
<TextInput> ... secureTextEntry={true} keyboardType="visible-password" </TextInput>
This fix works but sometimes messes up my Gboard and slows it down and have to restart the phone afterwards/ Restart Gboard by force close.
+Keyboardtype visible-password is not compatible with iOS.
I started looking into this, and it looks like this isn't fully related to autocapitalize (though it might have some other impact).
Even if I remove autoCapitalize, the problem persists. For example with this input:
export class UpperCaseTextEntry extends Component {
state = {
text: "Test"
};
upperCaseIt = text => {
this.setState({ text: text.toUpperCase() });
};
render() {
const { text } = this.state;
return (
<TextInput
value={text}
onChangeText={this.upperCaseIt}
/>
);
}
}
Typing more than twice produces a duplicate.
Did you succeed with that solution?
Did you succeed with that solution?
Have a look on my previous comment (https://github.com/facebook/react-native/issues/11068#issuecomment-462778742), if you keen to edit RN java files you can just swap that line as I've described and it will work as a charm! :D
Did you succeed with that solution?
Have a look on my previous comment (#11068 (comment)), if you keen to edit RN java files you can just swap that line as I've described and it will work as a charm! :D
I am not able to get proper solution form your comment, can you please add more specific changes step by step to be done, Thanks
Did you succeed with that solution?
Have a look on my previous comment (#11068 (comment)), if you keen to edit RN java files you can just swap that line as I've described and it will work as a charm! :D
I am not able to get proper solution form your comment, can you please add more specific changes step by step to be done, Thanks
Sure, it is really simple!
https://github.com/facebook/react-native/issues/11068#issuecomment-462798961
this is the resolution.
You just have to change 1 file in order to fix this issue...
Does anyone know any other way to solve this bug? I've tried all the resolutions mentioned here, but none of them worked for me. I'm trying to set my characters to upper case with textTransform: 'uppercase
.
RN Version: 0.60.4
Does anyone know any other way to solve this bug? I've tried all the resolutions mentioned here, but none of them worked for me. I'm trying to set my characters to upper case with
textTransform: 'uppercase
.RN Version: 0.60.4
Mate! I'm also from RS! =D
The resolution for android comes by touching RN java files.
Give me a shout if you need some help with it.
@mauricioscotton Cool dude 😄 , but i tried your resolution and it doesn't work, first we tried to set uppercase using the autoCapitalize
prop, but it just work for iOS, when i tried to uppercase this bug started happening, i tried to set upper case with mask too.
@mauricioscotton Cool dude 😄 , but i tried your resolution and it doesn't work, first we tried to set uppercase using the
autoCapitalize
prop, but it just work for iOS, when i tried to uppercase this bug started happening, i tried to set upper case with mask too.
I believe that the code you're running is not the same..
Are you able to pop android studio and inject that code on run-time?
if you are able to insert that code, it will work (believe me, we had this issue on a production app and I just gave up doing it because I didn't wanted to lock it to a custom RN version.) but if you really need it, you can test it first by debugging those lines as I've mentioned and then if it works you can apply a patch and recompile libs if necessary.
But first try to debug and inject those lines (If you havent).
Cheers
I don't really need to do that, i just gave up from this issue to focus in the others that are more important for the project, but it was an annoying bug where i was losing too much time, i just let the characters to be lowercased 😊. Thanks for the help.
O problema não é de toUpperCase. Qualquer função que obtenha as entradas do input por parâmetro irá duplicar caracteres. A solução é resetar o input. Existe uma lib para isso: react-native-text-input-reset
O problema não é de toUpperCase. Qualquer função que obtenha as entradas do input por parâmetro irá duplicar caracteres. A solução é resetar o input. Existe uma lib para isso: react-native-text-input-reset
this gets the input too slow to type, is a workaround temporarily only unfortunately.
Truly shameful how long basic text input issues plague our Android product :)
Coming back to this thread since over a year to see nothing has really improved.
The only workaround we found to make the experience bearable was to hide the TextInput behind a normal Text component that does all text rendering. Lost selection/copy/paste etc features, had to create a custom caret, but still works better than the TextInput...
@mauricioscotton Care to make a PR to react-native to close out this issue? Has been open for three years now.
If you cannot find the time, I can debug this and submit a PR so we can close this out and release this fix.
Also, to reproduce it, just drop a TextInput like this:
<TextInput ref={(el) => this.input = el} onChangeText={(val) => { this.input.setNativeProps({text: val.toUpperCase()}); }}/>
and on ReactEditText.java@381, change:
getText().replace(0, length(), spannableStringBuilder);
for:
setText(spannableStringBuilder);
What I tried:
getText().replace(0, length(), spannableStringBuilder, 0, spannableStringBuilder.length());
Same issue persists
setText(spannableStringBuilder);
Sets the cursor to the beginning of every change results in backwards typing.
setText(spannableStringBuilder);
setSelection(spannableStringBuilder.length());
This works however the performance is terrible, some keyboard presses don't get registered. Append should take out the need to set the cursor position.
append(spannableStringBuilder);
The same issue persists
getText().clear();
append(spannableStringBuilder);
This seems to be the only fix; however, performance gets bad after many characters.
Making a PR with this change 🎉 Thank you @mauricioscotton for the initial debugging and narrowing down to that line.
secureTextEntry={Platform.OS === 'ios' ? false : true}
keyboardType={Platform.OS === 'ios' ? null : 'visible-password'}
autoCapitalize="characters"
This kinda makes the trick for both platforms
secureTextEntry={Platform.OS === 'ios' ? false : true} keyboardType={Platform.OS === 'ios' ? null : 'visible-password'} autoCapitalize="characters"
This kinda makes the trick for both platforms
But also, unfortunately, takes control over crucial keyboard styling away from you.
secureTextEntry={Platform.OS === 'ios' ? false : true} keyboardType={Platform.OS === 'ios' ? null : 'visible-password'} autoCapitalize="characters"
This kinda makes the trick for both platforms
Works for me! Thanks, man!
secureTextEntry={Platform.OS === 'ios' ? false : true} keyboardType={Platform.OS === 'ios' ? null : 'visible-password'} autoCapitalize="characters"
This kinda makes the trick for both platforms
Works for me! Thanks, man!
works for me too!
This problem persists on RN 62.2
@iagormoraes I got the same issue
Does anyone know any other way to solve this bug? I've tried all the resolutions mentioned here, but none of them worked for me. I'm trying to set my characters to upper case with
textTransform: 'uppercase
.RN Version: 0.60.4
This produces the same issue.
secureTextEntry={Platform.OS === 'ios' ? false : true} keyboardType={Platform.OS === 'ios' ? null : 'visible-password'} autoCapitalize="characters"
This kinda makes the trick for both platforms
this worked for me and saved my life
This issue still exists in RN 0.63, but not only with autoCapitalize="characters"
. The only solution is to not use controlled input, save the value to the state with onChangeText
, but don't control it.
secureTextEntry={Platform.OS === 'ios' ? false : true} keyboardType={Platform.OS === 'ios' ? null : 'visible-password'} autoCapitalize="characters"
This kinda makes the trick for both platforms
This does not work for me...
Most helpful comment