React-native: TextInput multiline={true} not functioning as expected

Created on 5 Mar 2017  路  84Comments  路  Source: facebook/react-native

Description

TextInput multiline set to true no longer does newline on enter press. just blurs the TextInput instead.

Reproduction

Just change from 0.41.2 to 0.42.0 using the default AutoExpandingTextInput Example from the TextInput Docs to see it happening

Additional Information

  • React Native version: 0.42.0
  • Platform: Android ( Possibly iOS havent tested )
  • Operating System: MacOS
Locked

Most helpful comment

Thanks @shubhomoy for your code. I created a wrapper component out of it for general use in this gist.
Works for me on Samsung without major issues so far. The only thing I noticed: When selecting text somewhere inside and pressing enter, the cursor jumps ahead too much.

All 84 comments

I can reproduce it on Android. But not on iOS.

<TextInput multiline style={{ height: 100, backgroundColor: '#ccc' }} />

It blurs on Sony's Swift Keyboard,
but it's working fine when I changed it to Google's GBoard

+1

It blurs on Samsung Galaxy S6 keyboard.
Like @HermantoTang said, it works fine with Google's GBoard or the default keyboard in the Android emulator.

Yeah it was happening to me on a Samsung s6

Google English keyboard works as in that Enter will give a new line. Google Japanese keyboard does not work. A chinese input method I have also does not work.

Android.

Had the same problem with SwiftKey Keyboard. Following fixed it for me:

12923

+1

12923 didn't fix our case. We tried to replace the entire ReactAndroid folder, but in vain.

We had to roll back to 0.41.2
Hope this is fixed in 0.43

@goodhyun have you built ReactNative from source?
https://facebook.github.io/react-native/docs/android-building-from-source.html

+1 on this, we need a fix for this for our app because it affects Samsung.

I have the same issue while using Expo. The Expo SDK 15 brought RN 0.42 and broke my input field.
See #13159.

Sorry @studio3w I didn't know that I had to rebuild RN again from source.
Even 0.43.1 didn't solve this issue, and I rebuilt 0.43.1 with #12923 fix and it just worked like a charm.

This is a really annoying issue though.

Doesn't work onContentSizeChange event in release 0.43.2. wtf

+1

Having same issue. :'( same version , using expo , swiftkey

+1

Can confirm onContentSizeChange also not working in 43.*

Below is useful to me, use expo SDK 17, RN 0.44, wrote by Typescript.
for multiline={true} not add new line and onContentSizeChange issue

https://gist.github.com/BCGen/9ba9f7d96459fd063e42bd53f9839217

+1 Same here for Sony Z5 Compact. Why isn't this fixed yet? I'm a SwiftKey user as well, it seems to affect only those. Native Sony Keyboard works like a charm.

I don't think it's just swift key, I'm using a bog standard emulator and have the issue.

Same here, totally failed on my three android devices, any updating?

Having same issue: pressed enter and got submit triggered not entering a newline.
It works with google English input method, but all Chinese input method failed.

Platform: android 7.1.1
Input Method: Google Chinese Input Method.
RN Version: 0.44.0

any update on this issue?

Same problem

I've solved setting the blurOnSubmit props to false: https://facebook.github.io/react-native/docs/textinput.html#bluronsubmit

<TextInput
    multiline={true}
    numberOfLines={4}
    blurOnSubmit={false}
/>

By default, blurOnSubmit is set to true. So every time you press enter on the keyboard, the TextInput loses focus. If instead you set this property to false, this does not happen and, with enter, go to a new line :+1:

@akajack It doesn't work for me. I tried it.

@kevinluvian How to apply it ? I tried modify it in node_modules then run-android, but doesn't work.

no, you need to recompile from source https://facebook.github.io/react-native/docs/android-building-from-source.html
or you can wait until my PR got merged and install react native as usual

@kevinluvian Thanks

+1 on SwitfKey

my solution:

                 <TextInput
                    multiline={true}
                    blurOnSubmit={false}
                    editable={true}
                    maxLength={40}
                    onChangeText={(txt) => {
                        this.setState({ myText: txt })
                    }}
                    value={this.state.myText}
                    onSubmitEditing={() => {
                        if (!this.state.myText.endsWith("\n")) {
                            let myText = this.state.myText;
                            myText = myText + "\n";
                            this.setState({ myText: myText })
                        }
                    }}
                    />

hope that helps

@renehauck It works, bug very slow...

@renehauck What if I want to add a newline in the middle of the text and not at the end?

@iRoachie you can get the cursor position in the TextInput from onSelectionChange={(event) => this.setState({ cursorPosition: event.nativeEvent.selection.start })} and in onSubmitEditing to use something like splice for strings. See example

<TextInput
  multiline
  blurOnSubmit={false}
  onChangeText={(text) => {
    this.setState({ text });
  }}
  value={this.state.text}
  onSelectionChange={(event) => this.setState({ cursorPosition: event.nativeEvent.selection.start })}
  onSubmitEditing={(event) => {
    const { text, cursorPosition } = this.state;
    let newText = text;
    const ar = newText.split('');
    ar.splice(cursorPosition, 0, '\n');
    newText = ar.join('');
    this.setState({ text: newText });
  }}
/>

Yea I tried I already. However the cursor doesn't move to the newline like you'd expect. The cursor stays where it is and the new line is below

@iRoachie
you can set TextInput selection

const { end, start } = this.state.cursorPosition;

<TextInput 
  onSelectionChange={(event) => this.setState({ cursorPosition: event.nativeEvent.selection })}
  selection={{ start, end }} 
/>

and after add new line set cursorPosition to next position (start of new line)

const newPosition = this.state.cursorPosition.end + 1;

this.setState({ cursorPosition: { end: newPosition, start: newPosition });`

is this issue solved yet?

any updates? does anyone know where is this issue coming from?

Seems to be fixed in 0.45

Nope. Still no effect on multiline. updated to RN 0.45. Using Samsung Galaxy S6. Works fine in Google Keyboard though.

Same here. Updated and no effect on multiline.

This is a serious issue..not able to publish the app due to this.
@nikolay-radkov tried your code too. works fine but its inserting 2 newlines successively plus cursor remains in the same position when inserting new line from the middle of the text.

@shubhomoy to prevent the 2 newlines, you should debounce the function because some Android's version dispatch it twice. I did:

On constructor:

this.onSubmitEditing = debounce(this._onSubmitEditing, 100, true);

The _onSubmitEditing function:

_onSubmitEditing(event) {
            const { shortProductDescription, cursorPosition } = this.state;

            let newText = shortProductDescription;
            const ar = newText.split('');
            ar.splice(cursorPosition, 0, '\n');
            newText = ar.join('');

            this.setState({ shortProductDescription: newText });
    }

On TextInput: onSubmitEditing={this.onSubmitEditing.bind(this)}
For the position issue, try what @BCGen said above. I didnt yet.

EDIT
npm install debounce
then import it.

thanks @vendramini for the debounce tip. Did the trick.
As far as the position issue from middle of the text is concerned, I found a dirty trick...
here's my code

In constructor
this.onSubmitEditing = this.onSubmitEditing.bind(this);

Inside class

onSubmitEditing = _.debounce(this._onSubmitEditingNote, 100, true);

_onSubmitEditingNote() {
        const { noteText, cursorPosition } = this.state;
        let newText = noteText;
        const ar = newText.split('');
        ar.splice(cursorPosition.start, 0, '\n');
        newText = ar.join('');
        if(cursorPosition.start === noteText.length) {
            this.setState({ noteText: newText });
        }else{
            this.setState({ 
                noteText: newText, 
                selection: {
                    start: cursorPosition.start + 1,
                    end: cursorPosition.end + 1
                }
            });
        }
    }

In render function
```
blurOnSubmit = {false}
selection = {this.state.selection}
onSelectionChange={(event) => this.setState({ cursorPosition: event.nativeEvent.selection, selection: event.nativeEvent.selection })}
onChangeText = {(text) => {this.setState({noteText: text})}}
value = {this.state.noteText}
onSubmitEditing={this.onSubmitEditing} />

Please check for edge cases

Thanks @shubhomoy for your code. I created a wrapper component out of it for general use in this gist.
Works for me on Samsung without major issues so far. The only thing I noticed: When selecting text somewhere inside and pressing enter, the cursor jumps ahead too much.

Can confirm this issue is still active with swiftkey and latest react-native (0.45.1)

@catchin Thanks for sharing. Your solution works fine on its own, but when combined with the "autogrow" feature illustrated by the official example (https://github.com/facebook/react-native/commit/481f560f64806ba3324cf722d6bf8c3f36ac74a5), things become very buggy.

Have you guys tried to implement both "multiline" and "autogrow" on android?

Why hasn't @studio3w 's fix been merged yet? This is a serious deal-breaker for many scenarios, we better ask proper attention on this.

I really hope this will be fixed in 0.46... confirmed in 0.44.2 and 0.45.1

@irrigator Yes, however, I implemented "autogrow" differently: I set the following prop:
numberOfLines={this.props.value.split('\n').length}

@catchin that doesn't seem like it would handle line wrapping...

@Ehesp No, it does not. But https://github.com/facebook/react-native/pull/13890 should.

I tested with 0.46.1 and it seems that it wasn't fixed yet, an Input with multiline and blurOnSubmit={false} still does not add a new line on Android with a keyboard other than default (e.g. Swiftkey) :(

One work around, for those of you who are super desperate, is to put a text area in a webview, and communicate the data back and forth.

The work arounds above (mostly work). But it's still not perfect.

All those who are posting work around just one question. Is React Native all about work around ??. I see that even normal functionalities are not working :(

@rajsuvariya No, it is not. This bug was fixed recently. Do you still experience this problem on master?

@vspedr Have you tested it on master branch?

@shergin No. I am using stable version 0.46.3. When will these changes be published in the stable version? If it is already please let me know the version.

The following is my code which is not working with 0.46.3.

<TextInput
     placeholder={'Add Message (250 words)'}
     multiline={true}
     blurOnSubmit={false}
     onChangeText={(text) => this.setState({
        messageText: text
     })}
     value={this.state.messageText}
     />

@rajsuvariya Sorry, I am unaware of release schedule. It should be in stable in the end of the next month.

0.48.0-rc.0 and 0.47.1 are not yet good.

People, I did a search and I found other related issues opened here in github. Did someone solve this or got a better workaround than inserting newline on demand?

Tried to Build ReactAndroid from source from: https://facebook.github.io/react-native/docs/android-building-from-source.html, with this patch: https://github.com/facebook/react-native/commit/e6941990ef1ee4fd757d8dacebdd4be00438e3a7.

Bug still persist on Samsung keyboard and Google Chinese keyboard. Don't think this will be resolved anytime soon since this has been dragging for months. Meanwhile using wrapper class from https://gist.github.com/catchin/47afe706256604959c13dc25e7bb9383, while waiting for patch.

@holyxiaoxin That's sad. Probably different keyboard has different problems. 馃槩
Could you please share exact keyboard app name (or app id) which does not work for you?

@vendramini That issue discuss iOS specific problem, this one discuss Android specific one.

@shergin Bug reproduced on ASUS ZenUI keyboard, Android 7.0, Expo SDK 20 / RN 0.47 ... Please try installing this keyboard

@ceefour Thank you! I will try!

It still has errors on Samsung Galaxy S6 keyboard also S7 keyboard.
It works fine with Google's GBoard or the default keyboard in the Android emulator.

Agree with @poongnewga , this seems to be a behavior of certain third-party keyboards (which are in common usage). I think it's independent of Android version or manufacturer, since with my Asus Zenfone 3, I see similar behavior as him, i.e. the bug only occurs when I use ZenUI keyboard, and disappears when I switch to GBoard.

@shergin can you point to commit where this was fixed?

Finally this is fixed in 0.48. Setting blurOnSubmit={false} does it.

Fixed new line and prioritise blurOnSubmit in multiline text input (e694199) - @kevinluvian

@zhangzhhz While I appreciate if it's really "fixed", the docs say

blurOnSubmit?: bool #

If true, the text field will blur when submitted. The default value is true for single-line fields and false for multiline fields.

Why the need to set to it false when it should default to false in the first place!

Probably to maintain backward comparability

@ceefour Do you mean that in your opinion it should be always false by default or you mean that the current behavior does not respect the docs?

@shergin it doesn't respect the docs, so either one should be changed to match the other. I prefer behavior stated in the docs. much less "unexpected surprise" that way. AFAIK React Native is the only framework where setting "blurOnSubmit=false" explicitly is required on multline text input. Same component in Ionic and Xamarin just works out of the box.

I've tried it with Expo v20 and manually moving to react-native 0.48.1.
Still no luck with Swiftkey

@codewithpassion, have you tried explicitly setting blurOnSubmit={false}?

@ceefour The adb6646016944fb17fd4cb3824f38a42d4785176 finally fixes issue with wrong default value on Android! 馃帀

Thanks @rsnara!

Nope. Still seeing this on 0.49.0. Had to manually set blurOnSubmit={false} to get it to work.

@suvodeep-pyne Yep. Starting on 0.50.

I added this line and it worked correctly:
style={{minHeight: 150, height: 'auto'}}

<TextInput
    onChangeText={val => this.setState({ text: val})}
    value={this.state.text}
    multiline
    style={{minHeight: 150, height: 'auto'}}
/>

@sturmenta your solution worked for me!

Was this page helpful?
0 / 5 - 0 ratings