Material-ui: How to programmatically focus a TextField?

Created on 5 Sep 2015  路  14Comments  路  Source: mui-org/material-ui

StackOverflow: https://stackoverflow.com/questions/37949394/how-to-set-focus-to-a-materialui-textfield/44587705#44587705



Expand

I have this textfield:

<TextField ref="item" />

I want to focus this textfield when I click a button. I have this

React.findDOMNode(this.refs.item).focus();

but it doesn't work.

I tried using a simple <input type="text" ref="item" /> and there's no problem with it.

Please help.

TextField question

Most helpful comment

2 options

1.

<TextField autoFocus />
  1. If you have to put a slight time delay in to get the focus to happen.
function AutoFocusTextField(props) {
  const inputRef = React.useRef();

  React.useEffect(() => {
    const timeout = setTimeout(() => {
      inputRef.current.focus();
    }, 100);

    return () => {
      clearTimeout(timeout);
    };
  }, []);

  return <TextField inputRef={inputRef} {...props} />;
}

All 14 comments

Perfect! Thank you very much @oliviertassinari

just updating the source link in this issue for anyone who might find this.

focusNameInputField(){
  this.refs.nameInputField.focus()
}

render(){
  return <TextField ref='nameInputField' />
}

https://github.com/callemall/material-ui/blob/master/src/TextField/TextField.js#L330

For those who want to use it in a pure component :

...
const focusNameInputField = ref => {
  ref.input.refs.input.focus();
};

return (<TextField ref={focusNameInputField} />);
...

This's work too.

const focusUsernameInputField = input => {
  if (input)聽{
    input.focus();
  }
};

return <TextField inputRef={focusUsernameInputField} />

@ydeshayes @dogrocker can you please elaborate on what you mean by 'pure' component? is stateless component what you mean?
I thought we can't use ref within stateless component ????

btw, this.refs.item returns your the underlying react component,AKA backing instance;
React.findDOMNode(this.refs.item) return you the rendered DOM node.

if your component is a html element, they are interchangeable
http://www.webpackbin.com/E1txGgfff

Best not to use string refs anymore. ref callback is the way to go.

2 options

1.

<TextField autoFocus />
  1. If you have to put a slight time delay in to get the focus to happen.
function AutoFocusTextField(props) {
  const inputRef = React.useRef();

  React.useEffect(() => {
    const timeout = setTimeout(() => {
      inputRef.current.focus();
    }, 100);

    return () => {
      clearTimeout(timeout);
    };
  }, []);

  return <TextField inputRef={inputRef} {...props} />;
}

I couldn't get this to work without the setTimeout, for some reason. Slight typo in the above code fixed here:

const focusUsernameInputField = input => {
  if (input) {
    setTimeout(() => {input.focus()}, 100);
  }
};

I was not able to use the proposed solution with material-ui v1. So I ended up doing this, which is ugly... but works...

@saadtazi You have the rootRef property to get a direct reference on the native button.

Ohh, I totally missed the inputRef TextField prop. this is exactly what I needed!

Guys, I'm using Input and I got "ref is not defined" error. Then I changed it to TextField and I still get the same error. Also I get "focus is not defined" error on

this.refs.nameInput.focus();

Any idea why I get all these errors?
P.S. I'm using TypeScript & React
Thanks

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Bessonov picture Bessonov  路  93Comments

illogikal picture illogikal  路  75Comments

nathanmarks picture nathanmarks  路  100Comments

HZooly picture HZooly  路  63Comments

amcasey picture amcasey  路  70Comments