mr.abdo
mr.abdo

Reputation: 485

How to change focus to another component when Enter key is pressed

How can I change the focus to description field in TaskCard component, after enter key be pressed on InputField component?

That's the father component

export default class Task extends Component {

  constructor(props) {
    super(props)
    this.state = { cardID: '', list: [] }
    this.handleAdd = this.handleAdd.bind(this)
    this.handleChange = this.handleChange.bind(this)
    this.handleEdit = this.handleEdit.bind(this)
    this.handleRemove = this.handleRemove.bind(this)
    this.refresh()

  }
  handleAdd = (event, cardID) => {
        ...
  }

  handleChange(e) {
    ...
  }

  handleEdit = (e, task) => {    
    task.description = e.target.value
    axios.put(`${URL}/${task._id}`, task)
      .then(resp => this.refresh(this.state.description))
  }

  refresh() {
    ...
  }

  handleRemove = task => {
    ...
  }

  render() {
    return (
      <Fragment>        
        <Row className="card-columns">
          <taskCard title="Task Board" cardID='1' color='blue-violet'
            handleAdd={this.handleAdd}
            handleChange={this.handleChange}
            handleEdit={this.handleEdit}
            description={this.state.description}
            list={this.state.list}
            handleRemove={this.handleRemove}          
          />
      </Fragment >
    )
  }
}

The TaskCard component contains the description input field. That's the field who needs to receive the focus:

    const TaskCard = props => {

      const renderRows = () => {
        const list = props.list || []

        return list.map(task => (
          task.cardID === props.cardID &&
            <InputField task={task} 
              handleChange={props.handleChange}
              handleEdit={props.handleEdit}
              handleRemove={props.handleRemove}  
              />
        ))
      }

      return (
        <Fragment>           
                {renderRows()}

                <Form>
                    {/* input who needs to receive focus */}
                    <Form.Control className='input-field description' name='description' type="text" placeholder="Insert a task"
                      onChange={props.handleChange}
                      onKeyPress={event => {
                        if (event.key === 'Enter') {
                          props.handleAdd(event, props.cardID)
                          event.target.value= ''
                          event.preventDefault()
                        }
                      }}
                    />
                </Form>
        </Fragment >
      )
    }

export default TaskCard

Input field component is where the user edit a task and press Enter. When Enter is pressed, the task is modified and I'd like to focus on description field in TaskCard component

const InputField = props => {

  return (
    <Fragment>
      <Row>
        <Col xs={12} style={{paddingRight: 0}}>
          <Form>
            <Form.Group controlId="formBasicEmail">
              <Form.Control className='inputs-field' type="text" name={props.task._id}
                placeholder={props.task.description}             
                onChange={props.handleChange}
                onKeyPress={event => {
                  if (event.key === 'Enter') {
                    props.handleEdit(event, props.task)
                    event.preventDefault()

                  }
                }}
              />
            </Form.Group>
          </Form>
        </Col>        
      </Row>

    </Fragment >
  )
}

export default InputField

Upvotes: 0

Views: 35

Answers (1)

Travis James
Travis James

Reputation: 1939

Use refs to get a reference to the input in TaskCard and pass it to the input you want to focus:

    const TaskCard = props => {

      // useRef here
      const inputRef = useRef(null)

      const renderRows = () => {
        const list = props.list || []

        return list.map(task => (
          task.cardID === props.cardID &&
            <InputField task={task} 
              handleChange={props.handleChange}
              handleEdit={props.handleEdit}
              handleRemove={props.handleRemove}  
              />
        ))
      }

      return (
        <Fragment>           
                {renderRows()}

                <Form>
                    {/* input who needs to receive focus */}
                    ...
                      // pass ref here
                      ref={inputRef}
                      }}
                    />
                </Form>
        </Fragment >
      )
    }

export default TaskCard

Then in the <InputField /> Component pass the ref:

<InputField task={task} 
              handleChange={props.handleChange}
              handleEdit={props.handleEdit}
              handleRemove={props.handleRemove} 
              // pass the ref down
              inputRef={inputRef} 
              />

Then from within the <InputField /> component call it where ever you call the handleEdit function like this:

() => {
   props.handleEdit()
   props.inputRef.current.focus()
}

Upvotes: 1

Related Questions