0

CHANGED, STILL NO ANSWER I followed this example: https://jsfiddle.net/4np9u17g/11/ I want to make it like there - after inputing value focus should go to next input. I use new syntax of refs and redux form, what am i doing wrong?

  constructor() {
    super();
    this.field1 = React.createRef();
    this.field2 = React.createRef();
    this.field3 = React.createRef();
    this.field4 = React.createRef();
    this.field5 = React.createRef();
    this.field6 = React.createRef();
  }

On change function (I made it really simple for now):

 onChange = (text) => {
   if (text.length === 1) {
    this.field3.focus();
}

};

Input component:

  InputComponent = ({ input, meta, ...rest }) => (
    <Input {...rest} keyboardType="numeric" maxLength={1} value={input.value} onChangeText={input.onChange} />
  );

And finally one of my redux form fields:

 <Field
    maxLength={
    id="2"
    ref={this.field1}
    style={styles.input}
    name="pinSix1"
    component={this.InputComponent}
    placeholder="*"
    onChange={this.onChange}
    secureTextEntry
  />
  <Field
    id="3"
    ref={this.field2}
    style={styles.input}
    name="pinSix2"
    component={this.InputComponent}
    placeholder="*"
    onChange={this.onChange}
    secureTextEntry
  />

And I get an error

undefined is not a function (evaluating '_this.field3.focus()')

jake-ferguson
  • 315
  • 3
  • 11
  • 32

2 Answers2

0

onChangeText() from TextInput is called with the text string which is inputted into that input field, not with an event object

Edit To answer your question on how to handle this. You will need to edit your onChange handler:

onChange = (text) => {
  if (text.length === this.maxLength /* or wherever maxLength comes from */ ) {
    this.refs[nextField].focus()
  }
};

Where nextField the name of the next input is, which you provide through the ref prop

You can also see this SO post for more information:

dentemm
  • 6,231
  • 3
  • 31
  • 43
  • I made it the simlest as it is possible to check if it works but still have one error: onChange = (text) => { if (text.length === 1) { this.field3.focus(); } }; I got error 'undefined is not a function (evaluationg '_this.field3.focus()') – jake-ferguson Jun 04 '18 at 12:17
  • you need to access this.refs['field3'].focus() – dentemm Jun 04 '18 at 12:19
  • It appears you are right, I edited the link in my answer which refers to a more up to date StackOverflow answer – dentemm Jun 04 '18 at 12:28
0

Okey, after hours of struggling here's what I had to do (As i said I am using new syntax of refs, React 16.3). I have created InputComponent with ref passed as props:

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Input } from 'native-base';

class InputComponent extends PureComponent {
  static navigationOptions = {
    header: null,
  };

  render() {
    const { input, externalRef, ...rest } = this.props;
    return (
      <Input
        {...rest}
        ref={externalRef}
        keyboardType="numeric"
        maxLength={1}
        value={input.value}
        onChangeText={input.onChange}
      />
    );
  }
}

InputComponent.propTypes = {
  input: PropTypes.object,
  externalRef: PropTypes.object,
};

export default InputComponent;

Then in my component where pin code inputs are implemented:

constructor() {
    super();
    this.field0 = React.createRef();
    this.field1 = React.createRef();
    this.field2 = React.createRef();
    this.field3 = React.createRef();
    this.field4 = React.createRef();
    this.field5 = React.createRef();
  }

  componentDidMount() {
    this.field0.current._root.focus();
  }

  onChange = (text, val, body, name) => {
    if (text.length === 1 && name !== '6') {
      this[`field${name}`].current._root.focus();
    } else if (text.length === 1 && name === '6') {
      this.field5.current._root.blur();
    }
  };

The issue here is was this horrible NativeBase Input which has the focus() and blur() function hard to access. Finally - one of my six Fields:

<Field
   externalRef={this.field0}
   style={styles.input}
   name="1"
   component={InputComponent}
   placeholder="*"
   onChange={this.onChange}
   secureTextEntry
 />

Right now when user inputs some numbers it goes to the next input and when he or she inputs in the last Field the blur() function runs.

jake-ferguson
  • 315
  • 3
  • 11
  • 32