Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to autofocus an input field in semantic-ui-react?

I'm having a difficult time autofocusing an input field with semantic-ui-react. The documentation doesn't seem to include an autoFocus prop and the focus prop doesn't place the cursor inside the input field as would be expected.

<Form onSubmit={this.handleFormSubmit}>
  <Form.Field>
    <Form.Input
      onChange={e => this.setState({ username: e.target.value })}
      placeholder='Enter your username'
      fluid />
  </Form.Field>
</Form>

EDIT: This code works:

<Form onSubmit={this.handleFormSubmit}>
  <Form.Input
    onChange={e => this.setState({ username: e.target.value })}
    placeholder="Enter your username"
    autoFocus
    fluid />
</Form>
like image 595
Matt MacPherson Avatar asked Mar 08 '18 16:03

Matt MacPherson


People also ask

How do I autofocus a react input field?

There are a few ways to autofocus a React input field. You can use the autoFocus prop. This will work, but there is a caveat that we will get to. In this case, remember to use autoFocus, not autofocus. If you use autofocus instead, React will never actually set the autofocus DOM attribute.

Does react’s focus() work on input?

But it doesn’t always work. If you add React to an existing application and render a component into a detached element, React will call focus() before the browser is ready, and the input will not be focused when it gets added to the DOM. So, instead of depending on React to call focus() on the input, we are going to do it ourselves.

Is the autofocus attribute honored in ReactJS?

The autofocus attribute is honored in ReactJS but only when the <input> element is re-rendered with React: autofocus is easy to use but only works when the <input> is initially rendered; since React intelligently only re-renders elements that have changed, the autofocus attribute isn't reliable in all cases.

How to autofocus the first input element in the form after render?

To autofocus the first input element in the form after render, we use useEffect () hook and call the focus () method inside the hook. The dependency array should be an empty array to prevent multiple calls of focus () method on re-render.


3 Answers

The focus prop is purely to add a focus effect on the input's appareance, it does not actually set the focus.

Any props unused by Semantic are passed down to the DOM element, so if you set an autoFocus prop, it should go down to the input.

However, as explained in the Form documentation:

Form.Input

Sugar for <Form.Field control={Input} />.

So your code should rather be:

const yourForm = (
  <Form onSubmit={this.handleFormSubmit}>
    <Form.Input
      onChange={e => this.setState({ username: e.target.value })}
      onSelect={() => this.setState({ usernameErr: false })}
      placeholder="Enter your username"
      error={usernameErr}
      iconPosition="left"
      name="username"
      size="large"
      icon="user"
      fluid
      autoFocus
    />
  </Form>
)

Note that this only works if you want the focus to happen right when the wrapper component is mounted. If you want to focus the input after it has been mounted, you have to use a ref and call the focus() method on it, just as showed in the documentation, like so:

class InputExampleRefFocus extends Component {
  handleRef = (c) => {
    this.inputRef = c
  }

  focus = () => {
    this.inputRef.focus()
  }

  render() {
    return (
      <div>
        <Button content='focus' onClick={this.focus} />
        <Input ref={this.handleRef} placeholder='Search...' />
      </div>
    )
  }
}

Hope that helps!

like image 160
Tydax Avatar answered Oct 27 '22 03:10

Tydax


In order to tell the input field to focus, you need to create a reference (ref) to the input field as follows:

import React, { useState, useRef } from 'react';
import { Input, Button } from 'semantic-ui-react';

const SearchInputExample = () => {
  const [searchValue, setSearchValue] = useState('');

  // Create reference to the input field
  const searchRef = useRef(null);

  const handleSearchValueChange = event => setSearchValue(event.target.value);

  return (
    <div>
      <Input
        placeholder="Search..."
        // Assign the ref created to a ref attribute
        ref={searchRef}
        value={searchValue}
        onChange={handleSearchValueChange}
      />
      <Button
        onClick={() => {
          setSearchValue('');
          // Use the ref assigned to put the focus inside the input
          searchRef.current.focus();
        }}
      >
        Clear search (and focus)
      </Button>
    </div>
  );
};

export default SearchInputExample;

You can read more about the useRef() hook here

like image 24
Kalman Avatar answered Oct 27 '22 03:10

Kalman


I would have assumed that semantic UI would pass all unknown props to the root element, the input. So if it does, you should be able to add the autoFocus attribute to it, if not, you will have to control which input is being focused in your state.

<Input placeholder='Search...' focus={this.state.focusedElement === "search"}/>
like image 39
Francis Malloch Avatar answered Oct 27 '22 05:10

Francis Malloch