Formik: Add a prop to track if a field has focus (active)

Created on 15 May 2018  路  6Comments  路  Source: formium/formik

Feature

Add functionality to keep track which field is active. Consider exposing it through the new meta prop (https://github.com/jaredpalmer/formik/issues/343)

Similar to the implementation in final-form: https://github.com/final-form/react-final-form#metaactive-boolean

Implementation Info

This would require adding onFocus handler.

Most helpful comment

Tracks 'onFocus' and 'active' will be great. Its not hard to implement, its similar to the 'touched' flag.

@Andreyco, is there any discussion on that? Can we send a pull request?

All 6 comments

I suggest creating custom Field component

class CustomField extends React.Component {
  state = {
    focused: false,
  };

  render() {
    return (
      <Field name={props.name}>
        {fieldProps => {
          return props.children({
            ...fieldProps,
            field: {
              ...fieldProps.field,
              onFocus: () => {
                this.setState({ focused: true });
              },
              onBlur: event => {
                this.setState({ focused: false });
                fieldProps.field.onBlur(event);
              },
            },
          });
        }}
      </Field>
    );
  }
}

Why is this closed? This seems like a valid feature request.

Here's a higher order component, which can be used to wrap/adapt Redux-Form components in order for them to work with Formik. It also adds the missing meta.active property.

import React from 'react';
import { LIVE_RULE, BLUR_RULE } from 'components/form/formValidationRules';

export const formikalize = WrappedComponent => (class extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            active: false
        };

        this.handleFocus = this.handleFocus.bind(this);
        this.handleBlur = this.handleBlur.bind(this);
        this.formiField = props.field;
    }

    handleBlur(ev) {
        this.setState({active: false});
        this.formiField.onBlur(ev);
    }

    handleFocus(ev) {
        this.setState({active: true});
    }

    render() {

        const {field, form} = this.props;

        const events = {
            onFocus: this.handleFocus,
            onBlur: this.handleBlur,
            onChange: field.onChange // passing the event to Formik
        };

        const props = {
            // `input` is a property specific to Redux-React
            input: {
                name: field.name,
                value: field.value,
                ...events
            },
            meta: {
                active: this.state.active,
                touched: form.touched[field.name],
                error: form.errors[field.name],
                submitting: form.isSubmitting
            },
            ...this.props // pass in all other properties assigned to the Field (i.e. `ClassName`)
        };

        return(<WrappedComponent {...props} />)
    }
});

Here's how it can be used:

import { formikalize } from './Formikalize';
import { FormFieldText } from './FormFieldText';

export const FormikFieldText = formikalize(FormFieldText);

@Andreyco, I've been starting at those code for good 20 minutes. could you please give a quick example on how to use it? not sure where props is coming from.

thanks

Tracks 'onFocus' and 'active' will be great. Its not hard to implement, its similar to the 'touched' flag.

@Andreyco, is there any discussion on that? Can we send a pull request?

I'm disappointed this was closed. Formik handles touched, why not active? Seems like basic functionality that would save a lot of boilerplate if it were handled by Formik.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jaredpalmer picture jaredpalmer  路  3Comments

giulioambrogi picture giulioambrogi  路  3Comments

najisawas picture najisawas  路  3Comments

pmonty picture pmonty  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments