4

As the question says it all, I cannot focus the Semantic UI Search component programmatically.

I tried:

<Search
     category
     fluid
     loading={isItemLoading}
     onResultSelect={this.handleItemResultSelect}
     onSearchChange={this.handleItemSearchChange}
     placeholder='Search by name'
     results={itemResults}
     value={itemValue}
     ref={input => { this.itemSearch = input; }} />

and

this.itemSearch.setState({ focus: true, open: true });

This opens the results but does not focus the input for the user to retype.

Oleksandr Fediashov
  • 4,315
  • 1
  • 24
  • 42
  • Have you tried invoking the `.focus()` method on the `this.itemSearch` ref? If that doesn't work you can always use plain JS `document. querySelector` and invoke the `focus` method (not the cleanest solution but should work) – Grandas Oct 27 '17 at 01:07
  • 1
    There is no `.focus()` in the [Search](https://react.semantic-ui.com/modules/search) component. That is probably attached to the `input` inside the `Search` component but I cannot find a way to reach that. – Yehan Pemarathne Oct 27 '17 at 05:57

5 Answers5

4

For those who stumble on this old question: Search now has input prop. It looks like it accepts the same props as the semantic Input component. Get the Search's Input ref like this:

<Search input={{ref: r => this.searchInputRef = r}} />

And then use it like this:

focusSearchInput() {
  if (this.searchInputRef.focus) {
    this.searchInputRef.focus();
  }
}

It works for me

dletin
  • 49
  • 2
4

This worked for me

import React, { useEffect } from 'react'
import { Search} from 'semantic-ui-react'

const Form = (props) => {
   const searchRef = React.createRef();

   useEffect(() => {
      searchRef.current.focus();
   }, [])

   return (
      <div>
         <Search input={{ref: searchRef}} />
      </div>
   )
}

export default Form
Julio Ojeda
  • 767
  • 1
  • 6
  • 24
  • 1
    Worked perfectly for me, too. Thanks. For Typescript, I only had to add the type to *createRef* (*React.createRef()*) and null-check *current*. – voodoogiant Nov 26 '20 at 07:11
1

This is not pretty, but it'll do the trick. Don't tell anyone I proposed this.

<Search id="xyz" />
<Button onClick={() => document.getElementById('xyz').focus()}>Focus</Button>
user2962393
  • 1,083
  • 9
  • 12
0

If you create your own wrapper around the Search component, you can also use ReactDOM.findDOMNode and some jquery to avoid issues with using ids.

import React from 'react'
import { Search } from 'semantic-ui-react'

class SuperSearch extends React.Component {

    componentDidMount() {
        var search_bar = ReactDOM.findDOMNode(this)
        $(search_bar).find('input').get(0).focus()
    }

    render () {
        return (
            <Search></Search>
        )
    }
}
Roman Scher
  • 1,162
  • 2
  • 14
  • 18
0

Some how componentDidMount is called before the "ref" is obtained....

Here is the solution:

    <Search
      input={{ref: r => {
        if (r && r.inputRef) {
          r.inputRef.focus()
        }
      }}}

This will add focus when Search is shown in React..