简体   繁体   中英

Setting focus on an MUI Input component when clicking outside its area

I am creating an application with ReactJS and Material UI. I have an Input component inside a FormControl component. I would like to set the focus on the Input component when the user clicks in the FormControl (but still outside the Input component). How can this be achieved?

I have tried with refs but I was not able to do it:

<FormControl
    onClick={this.textInput.focus()}
    style={{ display: 'block', cursor: 'text' }}
>
<Input
  error={this.props.error}
  disabled={this.props.disabled}
  ref={(input) => { this.textInput = input; }}
/>
</FormControl>

I'm not very familiar with material-ui , but I think there are two problems here. Firstly, your value for onClick is not a function, so this will call focus when the component gets instantiated, on a ref that is not defined yet. You can fix this by wrapping the call: () => this.textInput.focus() (or create a method/instance property for it.)

Secondly, material-ui wraps the Input component in a withStyles higher-order component, and when you use ref , it refers to the wrapped component, which doesn't have a focus method. Instead, you can use the inputRef prop, which creates a ref to the actual input DOM element. (see https://material-ui-next.com/customization/api/#internal-components )

This code should work:

..
  <FormControl
    onClick={() => this.textInput.focus()}
    style={{ display: 'block', cursor: 'text' }}
  >
    <Input
      error={this.props.error}
      disabled={this.props.disabled}
      inputRef={(input) => { this.textInput = input; }}
    />
  </FormControl>
..

The problem might be with context and the way the click event is handled in the FormControl element.

Try this instead:

constructor(props) {
  super(props);
  this.setFocus = this.setFocus.bind(this);
}
setFocus() {
  this.textInput.focus();
}
render() {
  return(
    <FormControl
      onClick={this.setFocus}
      style={{ display: 'block', cursor: 'text' }}
    >
      <Input
        error={this.props.error}
        disabled={this.props.disabled}
        ref={(input) => { this.textInput = input; }}
      />
    </FormControl>
  );
}

As an annotation, is valid to remember that if you are using some sort of animation, it's possible that your input has'nt been created yet at the mounting of the main component. In this case, a setTimeout with a timer bigger than the animation time can help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM