Raziel
Raziel

Reputation: 1566

Cannot get input field to focus on click

So i am currently unable to focus on an input field - I have a card, which has a onClick handler. Once you clicked it - it brings up the input field, however, i cannot get the input field to focus:

The key area where things are going wrong are within renderTextField where i have set a reference, and then call this.myInput.focus() in handleClickInside, but still no luck.

Code below

import React, { Component } from 'react';
import { CSSTransition, transit } from 'react-css-transition';
import Text from './Text';
import Card from './Card';
import MenuIcon from '../icons/MenuIcon';

const style = {
  container: { height: '60px', width: '300px' },
  input: { border: 'none', fontSize: '14px', background: '#ff000000' },
  icon: { position: 'absolute', right: '10px', top: '18px' },
};

class Input extends Component {
  state = {
    clickedOutside: true,
    value: '',
  };

  componentDidMount() {
    document.addEventListener('mousedown', this.handleClickOutside);
  }

  componentWillUnmount() {
    document.removeEventListener('mousedown', this.handleClickOutside);
  }

  myRef = React.createRef();

  myInput = React.createRef();

  handleClickOutside = (e) => {
    if (!this.myRef.current.contains(e.target)) {
      this.setState({ clickedOutside: true });
    }
  };

  handleClickInside = () => {
    this.setState({ clickedOutside: false });
    this.myInput.current.focus();
  }

  renderField = () => {
    const { clickedOutside, value } = this.state;
    return (
      <div>
        <CSSTransition
          defaultStyle={{ transform: 'translate(0, -2px)' }}
          enterStyle={{ transform: transit('translate(0, -16px)', 150, 'ease-in-out') }}
          leaveStyle={{ transform: transit('translate(0, -2px)', 150, 'ease-in-out') }}
          activeStyle={{ transform: 'translate(0, -16px)' }}
          active={!clickedOutside || value.length > 0}
        >
          <Text>Password</Text>
          { this.renderTextField() }
        </CSSTransition>
      </div>
    );
  }

  renderTextField = () => {
    const { clickedOutside, value } = this.state;
    return (
      <input
        ref={this.myInput}
        style={style.input}
        type="text"
        value={value}
        placeholder={!clickedOutside ? 'Enter Password...' : null}
        disabled={clickedOutside}
        onChange={e => this.setState({ value: e.target.value })}
      />
    );
  }

  renderIcon = () => (
    <div style={style.icon}>
      <MenuIcon />
    </div>
  )

  render() {
    return (
      <div ref={this.myRef} onClick={this.handleClickInside} >
        <Card override={style.container}>
          { this.renderField() }
          { this.renderIcon() }
        </Card>
      </div>
    );
  }
}

export default Input;

Upvotes: 0

Views: 80

Answers (1)

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85545

First create a ref:

myInput = React.createRef();

Assign the ref:

ref={this.myInput}

Then, to focus myInput, use:

this.myInput.current.focus()

Upvotes: 1

Related Questions