Sergio Pellegrini
Sergio Pellegrini

Reputation: 87

Redux Form Dynamic Field Level Validation

I have a dynamic form field that is required based on the value of a form selected field. ie If the value of a certain field is "Yes" then the comment box is required and if "No" then it is not required.

If I initially select "Yes" and touch and blur the comment field the validation will return the required error. But after if I switch to "No" and back to "Yes" the validation error no longer occurs. If I type into the comment box and remove the validation will occur again.

I am using field level validation and have also use sync validation with the same issue.

<Field name={`${fieldId}.comment`}  validate={condition.required ? [required] : []} label={condition.label} className="form-control" component={renderTextField} />

Where condition is the check to see whether the field should be required.

The logic is correct as the validation work on initial selection and if you fill the comment field and remove the text but it just does not seem to receive the validation error.

Thanks in advance

Upvotes: 4

Views: 5748

Answers (3)

Calixto
Calixto

Reputation: 585

Another option... I try aways separate this conditions in another file:

Validate.js :

export const required = value => value ? undefined : 'Campo obrigatório!'
export const maxLength = max => value =>
  value && value.length > max ? `Máximo de ${max} caracteres` : undefined
export const maxLength60 = maxLength(60)
export const number = value => value && isNaN(Number(value)) ? 'Precisa ser numérico' : undefined
export const minValue = min => value =>
  value && value.length < min ? `No mínimo ${min}` : undefined
export const minValue4 = minValue(4)
export const emailvalid = value =>
  value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value) ?
  'Email inválido' : undefined

Also in your form you can just do:

    <Field
      name="email"
      cilIcon="cil-user"
      label="Email:"
      placeholder="Digite seu email"
      component={InputWithLabel}          
      type="text"          
      validate={ 1 === 2 ? [required, emailvalid, maxLength60] : []}
    />
    <Field
      name="password"
      cilIcon="cil-lock-locked"
      label="Senha:"
      placeholder="Digite sua senha"
      component={InputWithLabel}
      type="password"
      validate={[required, maxLength60, minValue4]}
    />

Upvotes: 0

It works fine for me. allValues were the key of success. In my case, I need to verify if exists phone or cell, if one of them exists then don't validate, but if both are empty then validate both.

    validatePhone = (value: any, allValues: any) => {
      const isRequired = allValues.contactCell === undefined
      if (isRequired && !value) 
        return 'Phone is required';
    }

    validateCell = (value: any, allValues: any) => {
      const isRequired = allValues.contactPhone === undefined
      if (isRequired && !value) 
        return 'Cell is required';
    }

    <Field id="contactPhone" name="contactPhone" label="Phone" className="TextField" 
                 validate = {this.validatePhone} component={RenderTextField}/>
    <Field id="contactCell" name="contactCell" label="Cell" className="TextField" 
                 validate = {this.validateCell} component={RenderTextField}/>

Upvotes: 0

jakee
jakee

Reputation: 18566

Quote from the Redux-Form Field component docs (v 6.8.0):

validate : (value, allValues, props) => error [optional]

Allows you to to provide a field-level validation rule. The function will be given the current value of the field, all the other form values, and any props passed to the form. If the field is valid, it should return undefined, if the field is invalid, it should return an error (usually, but not necessarily, a String).

You're trying to pass the error value in to the Field directly, but the validate prop is meant to accept a validation function that is used to determine validity. You should do something like this:

const validateComment = (value, allValues, props) => {
  // naturally you do something else here if the value
  // used to determine whether this field is required or
  // not is not managed by the same redux form
  const isRequired = allValues.commentRequired === 'Yes'

  if (isRequired && !value) return "Can't be empty."
}

<Field
  name={`${fieldId}.comment`}
  validate={ validateComment }
  label={condition.label}
  className="form-control"
  component={renderTextField}
/>

Hope this helps!

Upvotes: 9

Related Questions