Search code examples
reactjsreact-reduxredux-formreact-redux-form

Redux-form password validation only after both fields touched


Currently on my custom component I'm using an SFC that looks like:

export const InputField = field => (
  <div>
    <TextField required={field.required} invalid={field.meta.touched && !!field.meta.error}
     label={field.label} {...field.input} type={field.type} />
    {field.meta.touched && !!field.meta.error && (<TextFieldHelperText persistent
    validationMsg>{field.meta.error}</TextFieldHelperText>)}
  </div>
);

(Here TextField and TextFieldHelperText are styled components).

This is all good for text inputs that are only concerned about themselves, but on a Password field, closely followed by a Password confirm field I don't want the field to be marked as invalid until the password confirm field is also touched... but I can't figure out how to get a reference to the password confirm field and say essentially:

invalid={field.meta.touched && otherField.meta.touched && !!field.meta.error}

I feel like I'm missing something obvious!


Solution

  • Wrap both fields into a wrapper component, use state of the parent component for storing info about touched fields and pass a prop if the validation possible. Something like this

    class PassFields extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          passTouched: false,
          passConfirmTouched: false,
        }
      }
    
      handlePassFocus = (e) => {
        this.setState({ passTouched: true })
      }
    
      handlePassConfirmFocus = (e) => {
        this.setState({ passConfirmTouched: true })
      }
    
      render() {
        const canBeValidated = this.state.passTouched && this.state.passConfirmTouched
        return (
            <div className="form">
                <PassField
                    {...this.props}
                    onFocus={this.handlePassFocus}
                    canBeValidated={canBeValidated}
                />
                <PassConfirmField
                    {...this.props}
                    onFocus={this.handlePassConfirmFocus}
                    canBeValidated={canBeValidated}
                />
            </div>
        )
      }
    }

    And you now can use something like this

    <TextField 
      required={field.required} 
      invalid={field.canBeValidated && !!field.meta.error}
      onFocus={field.onFocus}
    ...