Laura Silvani
Laura Silvani

Reputation: 757

Handle Redux-form events

Not really sure how to do this, quite new in the Redux-Form world. I have a custom component for my inputs with an onFocus event that displays an unordered list and an onBlur event that hides it. I am also attaching an onClick event to the items because I would like to change the value of the input field once I click on a list item but the click event never fires because blur fires first. Not sure if I am addressing my code properly. Here is my custom component:

import React, { Component } from 'react'
import pageStyles from '../../../styles.scss'

class MyInput extends Component {

  constructor(props) {
    super(props);
    this.state = {
      dropdownIsVisible: false,
      dropdownCssClass: 'dropdown'
    }
    this.handleFocus = this.handleFocus.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }

  handleFocus () {
    this.setState({
      dropdownIsVisible: true,
      dropdownCssClass: ['dropdown', pageStyles.dropdown].join(' ')
    })
  }

  handleBlur () {
    this.setState({
      dropdownIsVisible: false,
      dropdownCssClass: 'dropdown'
    })
  }

  handleClick () {
    console.log('here I am')
  }

  render() {
    const {
      input: {
        name,
        value,
        onFocus
      },
      label,
      hasOptions,
      options,
      cssClass,
      meta: {
        touched,
        error
      }
    } = this.props

    if(options) {
      var listItems = options.map((item) =>
        <li key={ item.id } onClick={ this.handleClick }>{ item.name }</li>
      )
    }

    return (
      <div className={ cssClass }>
        <label>{ label }</label>
        <input name={ name } id={ name } type="text" onFocus={ this.handleFocus } onBlur={ this.handleBlur } autoComplete="off" />
        { hasOptions === true ? <ul className={ this.state.dropdownCssClass }>{ listItems }</ul> : null }
        { touched && error && <span className="error">{ error }</span> }

      </div>
    )
  }
}

export default MyInput

Upvotes: 1

Views: 535

Answers (1)

Maxim Kuzmin
Maxim Kuzmin

Reputation: 2614

Use lodash debounce function. This function adds delay before function calling, so you can cancel it in case of nested element click.

Add in constructor:

this.handleBlur = debounce(this.handleBlur, 100);

replace handleClick:

handleClick () {
  if(this.handleBlur.cancel){
    this.handleBlur.cancel()
  }
  console.log('here I am')
}

Upvotes: 1

Related Questions