Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate one field based on another Field in redux Form

I am using redux-form, and my Component has several FieldArray. One of the FieldArray component generates table like shown in the screenshot. Here each row is a Field component including the checkbox. What I want to achieve is, if checkbox component on that row is checked, then only price field should be required.

I tried to solve this by using validate.js as described in docs, but since, this component has structure as:

<FirstComponent>
<FieldArray
  component={SecondComponent}
  name="options"
  fruits={fruitsList}
 />
</FirstComponent>

In my SecondComponent I am iterating over fruitsList and if length is greater than 1, then I render ThirdComponent. This component is responsible for generating the Fruit lists as show in the screenshot. Having some degree of nesting, when I validate with values, it has a lot of performance lag, my screen freezes until it renders the ThirdComponent. Each component has bit of Fields so can not merge them easily. Any easier way to solve this in elegant way would be helpful. The logic for validating is as follow:

props.fruitsList.map((fruit, index) => {
      const isChecked = values.getIn(['fruit', index, 'checked'])
      if (isChecked) {
        const price = values.getIn(['fruit', index, 'price'])
        if (price === undefined || price.length === 0) {
          errors.fruits[index] = { price: l('FORM->REQUIRED_FIELD') }
        }

      }
      return errors
    })

Form Sceenshot]

like image 977
Apan Madhesh Avatar asked Feb 08 '17 13:02

Apan Madhesh


Video Answer


1 Answers

The synchronous validation function is given all the values in the form. Therefore, assuming your checkbox is a form value, you have all the info you need.

function validate(values) {
  const errors = {}
  errors.fruits = values.fruits.map(fruit => {
    const fruitErrors = {}
    if (fruit.checked) { // only do fruit validation if it's checked
      if (!fruit.price) {
        fruitErrors.price = 'Required' // Bad user!!
      }
    }
    return fruitErrors
  })
  return errors
}

...

MyGroceryForm = reduxForm({
  form: 'groceries',
  validate
})(MyGroceryForm)
like image 68
Erik R. Avatar answered Sep 17 '22 18:09

Erik R.