Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate dynamically generated form in react using redux-form and revalidate?

I'm using "revalidate" to validate "redux-form" forms, but I'm facing this situation where there's a form that is generated dynamically based on an API response that I map over it and display the inputs inside the form.

Here's an example of how I normally validate "redux forms" with "revalidate ...

const validate = combineValidators({
    name: composeValidators(
        isRequired({ message: "Please enter your full name." }),
        hasLengthLessThan(255)({
            message: "Name can't exceed 255 characters."
        })
    )(),
    email: composeValidators(
        isRequired({ message: "Please enter your e-mail address." }),
        matchesPattern(IS_EMAIL)({
            message: "Please enter a valid e-mail address."
        })
    )()
});

export default compose(
    connect(
        null,
        actions
    ),
    reduxForm({ form: "signupForm", enableReinitialize: true, validate })
)(SignUpForm);

Now, how I go about doing a similar thing with the auto-generated forms?

like image 514
Ruby Avatar asked Mar 16 '19 13:03

Ruby


1 Answers

The idea is to get the dynamicFields from the ownProps which is the second argument of the validate function and use them as you please to populate the validation.

Since combineValidators is an high order function, after running it we call the resulting function with values as parameter.

// assuming dynamicFields an array like:
[
    {
        id: 1,
        name: 'age',
        component: 'input',
        label: 'Age',
        placeholder: 'Age'
    },
    {
        id: 2,
        name: 'size',
        component: 'input',
        label: 'Size',
        placeholder: 'Size'
    }
]
///////

const validate = (values, ownProps) => {
const staticValidations = {
    firstname: composeValidators(
        isRequired({ message: 'Please enter the first name.' }),
        hasLengthLessThan(255)({
            message: "Name can't exceed 255 characters."
        })
    )(),
    lastname: composeValidators(
        isRequired({ message: 'Please enter the lastname' }),
        matchesPattern('abc')({
            message: 'Please enter a valid lastname'
        })
    )()
}
const dynamicValidations = ownProps.dynamicFields.reduce((accu, curr) => {
    accu[curr.name] = isRequired({ message: 'Please enter ' + curr.name })
    return accu
}, {})

return combineValidators({
    ...staticValidations,
    ...dynamicValidations
})(values)

}

In this example I am just putting the isRequired but you can be more creative, e.g. passing a type to your dynamic field data and doing things like if type === ABC then do XYZ

A full codesandbox of the validation is provided here -> https://codesandbox.io/embed/py5wqpjn40?fontsize=14

like image 195
stilllife Avatar answered Nov 13 '22 19:11

stilllife