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

[TextInput] iOS Keyboard next/prev Buttons & tab Support #641

Closed
erikthedeveloper opened this Issue Apr 3, 2015 · 58 comments

Comments

Projects
None yet
@erikthedeveloper

erikthedeveloper commented Apr 3, 2015

I have been unable to find throughout the documentation, UIExplorer, or my own experiments a way to enable iOS keyboard navigation and submit elements. I feel like this is important and expected from users to be able to navigate between input elements and submit from the iOS keyboard.

This behavior is present/expected even on vanilla HTML forms accessed via iOS on the web.

If somebody already has a solution for this, please let me know 😄

Request

  • Activate iOS next/prev buttons on the TextInput and other user input elements
  • Enable grouping of input elements together as a "form"

Screen shot showing "next"/"prev" elements

project8

@erikthedeveloper erikthedeveloper changed the title from TextInput/User Input next/prev Buttons, Form Grouping, and "Go" Button Support - iOS to iOS Keyboard next/prev Buttons, Form Grouping, and "Go" Button Support Apr 3, 2015

@erikthedeveloper

This comment has been minimized.

erikthedeveloper commented Apr 3, 2015

Update 😑 should have updated before submitting, but updating react-native from 0.3.1 -> 0.3.4 resolved the returnKeyType issue.

Before update: returnKeyType property had no effect on the iOS keyboard.
Now: it does 😄

          <TextInput
            // ...
            returnKeyType='go'
          />

@erikthedeveloper erikthedeveloper changed the title from iOS Keyboard next/prev Buttons, Form Grouping, and "Go" Button Support to iOS Keyboard next/prev Buttons Support Apr 6, 2015

@kevinkam

This comment has been minimized.

kevinkam commented Apr 11, 2015

How to focus on the second TextInput?
I have set the first TextInput with property returnKeyType="next"
and second TextInput with property returnKeyType="go"
But when I click the "next" button, it just hide the keyboard and unfocus the first TextInput
How can I focus on the second TextInput?
Thanks!

@auser

This comment has been minimized.

auser commented Apr 20, 2015

bump

@brentvatne

This comment has been minimized.

Collaborator

brentvatne commented Apr 20, 2015

Discussed with @vjeux and @auser in irc, this is indeed an issue and if anyone is up for tackling it a PR would be very welcome. Just post in here if you are getting started on it. Otherwise I may look at it later this week.

@brentvatne brentvatne self-assigned this Apr 20, 2015

@erikthedeveloper

This comment has been minimized.

erikthedeveloper commented Apr 20, 2015

I would love to take a stab at it, but I'm not convinced I'm quite up to the task of a PR into react-native core 😅

I'll be very interested to check out your work if you get a PR submitted @brentvatne 😄

@ide

This comment has been minimized.

Collaborator

ide commented Apr 20, 2015

For single-line text fields, the onSubmitEditing handler (or similar) should suffice. What is missing from it to let you solve this use case?

@nicklockwood

This comment has been minimized.

Contributor

nicklockwood commented Apr 20, 2015

The back/forward form navigation buttons are a iOS browser feature, not a native iOS app feature. These buttons will show up automatically if you display an HTML form inside a WebView, but there is no API for displaying these buttons in native iOS apps, and any app that you have seen using them is either using a WebView, or has re-created the same feature natively using custom code (presumably for the purpose of making their native form behave more like a web form - a somewhat dubious UX decision IMHO).

It would certainly be possible to implement a facsimile of this feature right now as a native module, and if the demand is high enough then I expect someone will build it (maybe even us), but for the record, if I was developing a native iOS app and the designer asked for this, I would push back and suggest that they try to implement forms using native iOS app design patterns rather than iOS mobile web patterns.

You'll notice that the iOS Settings app never once uses this pattern, despite having pages and pages of form fields.

That said, we are currently investigating the best way to implement inputAccessory views (the docked bar that appears above the keyboard that can be used for adding additional application-specific controls), and once that is in place, it should be relatively simple to implement this feature in JS code.

@dvdhsu

This comment has been minimized.

dvdhsu commented Apr 20, 2015

Can the "return" key move to next text input field? Looking around the documentation, it seems like we can display the "return" key as a "next", but it won't actually move to the next input field -- it'll just dismiss the keyboard.

As @nicklockwood says, back/forward form navigation buttons aren't a native iOS app feature. Moving to the next field is, though. It'd probably be more important to implement that.

Edit: remove incomplete sentence.

@nicklockwood

This comment has been minimized.

Contributor

nicklockwood commented Apr 20, 2015

@dvdhsu unlike web forms, iOS has no natural concept of tabbing order, or the "next field", so we cannot easily replicate that automatically. If you register an event handler for onSubmitEditing, it should fire when the return key is pressed, and you can then call focus() on the next field in the form.

@nicklockwood

This comment has been minimized.

Contributor

nicklockwood commented Apr 20, 2015

@dvdhsu I've not actually tried building a form like this in practice, so if you find that it doesn't work, or if you have some ideas for how to make it simpler to implement, I'd be keen to hear them.

@brentvatne

This comment has been minimized.

Collaborator

brentvatne commented Apr 20, 2015

@nicklockwood - thank you the detailed response, your expertise is much appreciated.

@ide - you're right, that will work just fine for the most part. If you have a username and password field, you can just focus the password in the onSubmitEditing callback, easy. If you have several inputs, it seems preferable to have a more generalized focusNextField(currentField) function so that you don't have to hardcode the order of fields. This becomes a bit awkward because the event target is a node id number that refers to the node. So you have to set a ref on all of the inputs, then search through the refs until you find the one with the matching id, and then use the TextInput following that. Tabbing through inputs seems like a common enough use case that it would be worth simplifying a bit, can't say I have a good API in mind at the moment though.

@ide

This comment has been minimized.

Collaborator

ide commented Apr 20, 2015

@dvdhsu - there are a good number of cases where you might want the Next button to do something other than go to the next text field. For example you might want to transition to the next screen, or focus the next text field that doesn't yet have valid input (ex: if the user filled them out out-of-order).

For the use case you mentioned: if I understand it correctly, to move to the next field you could get refs to all of the text fields and then call this.refs[desiredTextField].focus(). This is pretty lightweight and opens the opportunity for custom logic like skipping over certain fields, etc.

@dvdhsu

This comment has been minimized.

dvdhsu commented Apr 20, 2015

@ide - yep, that's the use case I was referring to. Your solution is fine, but like @brentvatne notes, it'd be better to have some sort of function s.t. we didn't need to hardcode the transitions in for longer forms.

Also -- onSubmitEditing forces the keyboard to "jump" when moving between fields, since the keyboard is being dismissed and brought up again on every "submit".

If I have time over the next week, I'll have a think about this, and implement something.

Thanks!

@nicklockwood

This comment has been minimized.

Contributor

nicklockwood commented Apr 20, 2015

@dvdhsu Having the keyboard dismissed automatically onSubmitEditing is probably a bug - it doesn't match the native iOS behaviour.

I think it would make sense if we kept this as default behavior if onSubmitEditing isn't set (to avoid breaking existing code), but if onSubmitEditing is set then we disable it and leave it up to the JS to dismiss the keyboard.

@nicklockwood

This comment has been minimized.

Contributor

nicklockwood commented Apr 20, 2015

Now that I think about it, we could probably implement select-next field automatically as well by making the following changes:

  • If the field's returnKey type is set to "next", the default behaviour of onSubmitEditing will be to focus() on the next field inside the parent. We can also support tabbing with the actual tab key for external keyboards.
  • Next field would be determined by the order of textfields inside their parent view. It could then be manually overridden either by adding a tabindex property to TextField (which matches the web convention) or with an explicit nextField attribute (although then we'd have to decide if that should be a ref or a reactID)

@vjeux would you be in favour of something like this? And if so, @ide, @dvdhsu, do you feel like creating a pull request to implement some or all of the above? (I'll be happy to finish the job if you can at least make a start with it)

@brentvatne

This comment has been minimized.

Collaborator

brentvatne commented Apr 20, 2015

@nicklockwood - that sounds fantastic to me

@vjeux

This comment has been minimized.

Contributor

vjeux commented Apr 20, 2015

@nicklockwood that works with me.

@admmasters

This comment has been minimized.

Contributor

admmasters commented Apr 28, 2015

@nicklockwood late to the party here - but that sounds like a happy balance. Any ETA on this?

@brentvatne

This comment has been minimized.

Collaborator

brentvatne commented Apr 28, 2015

@admmasters - @auser mentioned in irc that he was interested in doing this. @auser - is that still the case? If you're too busy I can have a look at it soon

@auser

This comment has been minimized.

auser commented May 21, 2015

@brentvatne Yes, I hope to get to it this weekend.

I've had a bit of personal junk going on lately. I'll check in with you on irc.

@brentvatne brentvatne changed the title from iOS Keyboard next/prev Buttons Support to [TextInput] iOS Keyboard next/prev Buttons Support May 28, 2015

@brentvatne brentvatne removed their assignment Jun 4, 2015

@danscan

This comment has been minimized.

Contributor

danscan commented Jun 29, 2015

+1 any update on this?

@williamriancho

This comment has been minimized.

williamriancho commented Jul 10, 2015

I don't think that it's a good idea to implement this in an "automatic" way.
It will probably prevent developers of having non linear behavior. For instance, you can focus an empty mandatory field when the user press "next" at the last field.
Furthermore, the "next" label is just a label. Technically, you can put whatever you want, it should not influence the button's behavior.

I think that we just have two problems here:

  • Firstly, the next button should not hide the keyboard. The normal behavior in the Apple SDK is that: as long as an input is focused, the keyboard is visible. To hide the keyboard, the input has to release the focus in his Primary Action Triggered (onSubmitEditing in react-native). If the focus jumps from an input to another, the keyboard doesn't move but his type can change.
  • Secondly, we should have a simpler way to focus another input from the onSubmitEditing. I have to admit that I'm not a react-native expert (neither react) but I tried to set the focus of the next element and I didn't find any other solution that to refer the next TextInput element instance in a global variable. I didn't find any way to focus the next input using the ReactElement instance.
@dsibiski

This comment has been minimized.

Contributor

dsibiski commented Jul 28, 2015

I've implemented a blurOnSubmit prop for TextInput that I think solves this problem. PR here: #2149

Basically, it allows for backward compatibility by defaulting to true, however, the main idea goes with the normal iOS convention that the keyboard should technically stay there even on submit. One day the default value of true could be deprecated.

In the case of switching to different fields...the user would set blurOnSubmit to false (currently) and the keyboard would not dismiss. However, the onSubmitEditing callback would still fire and they would be able to programmatically do what @ide described earlier, by simply calling focus() on the ref of their choice. No keyboard "jumping" to deal with. :)

It's not an automated way to manage all of this as way mentioned above, but it's a simple solution that works.

@lrettig

This comment has been minimized.

Contributor

lrettig commented Feb 4, 2016

+1 would love to see progress on the original issue raised here--I would love to see a built-in "next" feature for TextInput, as well as support for tabs for hardware keyboards

@igorlimansky

This comment has been minimized.

igorlimansky commented Feb 7, 2016

+1, any news or workaround ways, guys? how did you solve it in your projects?

@lrettig

This comment has been minimized.

Contributor

lrettig commented Feb 8, 2016

This works reasonably well as a workaround: http://stackoverflow.com/questions/32748718/react-native-how-to-select-the-next-textinput-after-pressing-the-next-keyboar

With this system, if using an attached keyboard, hitting enter works, but hitting tab doesn't

@brentvatne

This comment has been minimized.

Collaborator

brentvatne commented Mar 6, 2016

I think this is a very important issue because it's a common requirement -- pretty much every app has forms and it sucks that everyone needs to come up with a one-off solution for how to handle this. We need tabindex. This is a significant undertaking, we should look at building it on a separate project and if it becomes mature enough then maybe integrating it back into core.

You will want to look at, in detail, how this is handled on iOS, Android, and web, understand the strengths and weaknesses of each, and try to build the best implementation around that, which ideally would have a web-like API.

I created a ProductPains issue for this here: https://productpains.com/post/react-native/keyboard-nextprev-buttons-tab-support/

@Knotschi

This comment has been minimized.

Knotschi commented Apr 15, 2016

I am using react native with clojurescript and reagent.
I just had a really hard time implementing this to focus the next text input after submit the previous one.

I would not like to have an automatic behaviour for this.

What I am missing is a simple "focus" property. If a value is set for this property this text input field should have focus as long as this property is true and should not have focus when the property is false.

In this way I can easily just save in my state object which field has the focus.
On submit I would just update my state with the information that the current input should not have focus but the next one should have the focus.

@lrettig

This comment has been minimized.

Contributor

lrettig commented Apr 15, 2016

@Knotschi see http://stackoverflow.com/a/35070812/2397068 for one implementation of this

@Knotschi

This comment has been minimized.

Knotschi commented Apr 15, 2016

yeah, I saw this and just added an answer for reagent. I still think there should be a focus prop in react native

@brentvatne

This comment has been minimized.

Collaborator

brentvatne commented Apr 15, 2016

@Knotschi - what would you expect the framework to do if two or more TextInputs have focus set to true at the same time?

@danscan

This comment has been minimized.

Contributor

danscan commented Apr 15, 2016

@brentvatne would it be possible for the focus prop's true value to work similarly to StatusBar?

(The most recently mounted TextInput w/ focus === true becomes focused.)

@mkonicek mkonicek added the Icebox label Jul 29, 2016

@mkonicek

This comment has been minimized.

Contributor

mkonicek commented Jul 29, 2016

Hi there! This issue is being closed because it has been inactive for a while.

But don't worry, it will live on with ProductPains! Check out its new home: https://productpains.com/post/react-native/textinput-ios-keyboard-nextprev-buttons-tab-support

ProductPains helps the community prioritize the most important issues thanks to its voting feature.
It is easy to use - just login with GitHub. GitHub issues have voting too, nevertheless
Product Pains has been very useful in highlighting the top bugs and feature requests:
https://productpains.com/product/react-native?tab=top

Also, if this issue is a bug, please consider sending a pull request with a fix.
We're a small team and rely on the community for bug fixes of issues that don't affect fb apps.

@mkonicek mkonicek closed this Jul 29, 2016

@GantMan

This comment has been minimized.

Contributor

GantMan commented Sep 9, 2016

This worked fine for me. Tab from UN to Password, then to login by just swallowing the tabs. Not the finest solution but it will work for someone :)

  handleChangeEmail = (text) => {
    // capture tabs
    if (text.match(/.+\t/)) {
      this.refs.password.focus()
    } else {
      this.setState({ email: text })
    }
  }

  handleChangePassword = (text) => {
    // capture tabs
    if (text.match(/.+\t/)) {
      this.handleLogin()
    } else {
      this.setState({ password: text })
    }
  }
@TheoGit

This comment has been minimized.

TheoGit commented Sep 29, 2016

@lrettig that solution was perfect - thanks!

@danstepanov

This comment has been minimized.

danstepanov commented Dec 1, 2016

So I'm trying to shift focus from my username field to my password field and refs are deprecated while everything else doesn't seem to work in the most recent version of RN, any updates on this?

@mateusreis

This comment has been minimized.

mateusreis commented Dec 2, 2016

@danstepanov same here... :(

@bufke

This comment has been minimized.

bufke commented Dec 21, 2016

I don't see any way to capture physical keyboard tab keys. They don't trigger a onChangeText so I can't sniff for them. On 39.02.

@gisenberg

This comment has been minimized.

gisenberg commented Jan 11, 2017

Any update on this?

@cstafie

This comment has been minimized.

cstafie commented Mar 23, 2017

Bump.

@douglasjunior

This comment has been minimized.

douglasjunior commented Aug 3, 2017

If anyone has an interest, take a look at https://github.com/douglasjunior/react-native-keyboard-manager

@zackify

This comment has been minimized.

zackify commented Aug 25, 2017

@danstepanov if you want to move on enter to the next fields, check this out: https://github.com/zackify/react-native-autofocus

@ronaldozanoni

This comment has been minimized.

ronaldozanoni commented Oct 14, 2017

@douglasjunior's answer helped me. Thank you, Douglas

@tonycoco

This comment has been minimized.

tonycoco commented Jun 30, 2018

How is this discussion dead? Seems like a necessary tool to have a sort of tabindex for fields. Without it and with multiple TextInput within a component visually has a keyboard on iOS that feels non-native.

@facebook facebook locked as resolved and limited conversation to collaborators Jul 23, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.