I have a formik fieldarray where every row would have 3 dropdowns. And I would like to have a validation schema which works this way:
If email is selected in the first dropdown, then the value given in the 3rd dropdown(it has allowAdditions) to be validated if a valid email id is given or not.
If a <, <=, >, >= operator is selected in the second dropdown,then the value given in the 3rd dropdown(it has allowAdditions) to be validated if it has a number only.
Before achieveing this, I tried to give a simple validation to validate if the length od the 1st dropdown is greater than 6. Though the validation worked, no warning message is shown as it comes with normal FormInput in formik. Not sure if this is because it is a dropdown.
Validation:
const validationSchema = object().shape({
rows: array().of(
object().shape({
value: string().min(4, "too short").required("Required")
})
)
});
Formik:
<Formik
initialValues={{ rows: initialValues }}
onSubmit={(values) => {
// transform the rows to add the condition key for each row object
const output = values.rows.map((row, index) => {
if (index === 0) {
return { ...row, condition: "if" };
} else {
return { ...row, condition: "and" };
}
});
console.log(output);
}}
validationSchema={validationSchema}
>
{({ handleSubmit, values, setFieldValue }) => (
<Form onSubmit={handleSubmit} className={"rulesetForm"}>
<pre>{JSON.stringify(values, null, 2)}</pre>
<FieldArray
name="rows"
render={({ push, remove }) => {
return (
values.rows.length > 0 &&
values.rows.map((row, index) => {
const mainFieldOptions = getMainFieldOptions(
values.rows,
index
);
return (
<Grid key={`mainfield-operation-value-${index}`}>
<Grid.Row className={"rulesetGrid fluid"}>
{index === 0 ? (
<p className="condition"> If</p>
) : (
<p className="condition"> And</p>
)}
<Dropdown
name={`rows.${index}.mainField`}
className={"dropdown fieldDropdown"}
widths={2}
placeholder="Field"
fluid
selection
options={mainFieldOptions}
value={row.mainField || ""}
onChange={(e, { value }) => {
setFieldValue(`rows.${index}.mainField`, value);
}}
/>
<Dropdown
name={`rows.${index}.operation`}
className={"dropdown operationDropdown"}
widths={2}
placeholder="Operation"
fluid
selection
options={operation}
value={row.operation}
onChange={(e, { value }) =>
setFieldValue(`rows.${index}.operation`, value)
}
/>
<Dropdown
name={`rows.${index}.value`}
className={"dropdown valueDropdown"}
widths={1}
placeholder="Value"
fluid
search
allowAdditions
selection
multiple
options={dropDownOptions}
value={row.value}
onAddItem={handleAddition}
onChange={(e, { value }) =>
setFieldValue(`rows.${index}.value`, value)
}
/>
{values.rows.length - 1 === index && (
<Icon
className={" plus icon plusIcon"}
onClick={() => push(initialValues[0])}
/>
)}
{values.rows.length !== 1 && (
<Icon
className={"minus crossIcon"}
onClick={() => remove(index)}
/>
)}
</Grid.Row>
</Grid>
);
})
);
}}
/>
<div>
<div style={{ marginTop: "1rem" }}>
<Button
floated="right"
type="submit"
variant="contained"
primary={true}
>
Submit
</Button>
</div>
</div>
</Form>
)}
</Formik>
Here is the sandbox link: https://codesandbox.io/s/semantic-ui-example-forked-lmqi9?file=/example.js:1826-6181
Any help is really really appreciated and would mean a lot. Thanks in advance