jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
33.88k stars 2.79k forks source link

Formik Validation in a Field Array #1816

Open bsabhiram opened 5 years ago

bsabhiram commented 5 years ago

Hello I have a formik form where I am showing an array of text using Field Array. I want to have validation when for any text field, the number of characters are more than 28.

How do I do this ?

Below is my code:-

import Drawer from "components/atoms/Drawer"; / import Input from "components/atoms/Input"; import InputGroup from "components/atoms/InputGroup"; import Label from "components/atoms/Label"; / import Scrim from "components/atoms/Scrim"; import DrawerBody from "components/molecules/DrawerBody"; import { Field, FieldArray, Form, FormikErrors, FormikProps, withFormik } from "formik"; import { ITrackedPage } from "hocs/withAppDynamics"; import as React from "react"; import { Box, Flex, Text } from "rebass"; import as AmenitiesActions from "store/amenities/actions"; import { IAmenity, IAmenityRanking } from "store/amenities/models"; import DrawerHeader from "./DrawerHeader"; // import ErrorMessage from 'components/atoms/ErrorMessage';

interface IAmenitiesDrawerProps { drawerOpen: boolean; onDrawerClose: () => void; tenantAssessmentId: string; actions: typeof AmenitiesActions; maxRank?: number; }

interface IAmenitiesDrawerValues { amenitieslist: IAmenity[]; }

const InnerForm: React.FC< IAmenitiesDrawerProps & ITrackedPage & FormikProps

= ({ errors, drawerOpen, onDrawerClose, handleChange, values, setValues, isValid, tenantAssessmentId, sendAnalyticsData, actions }) => {

const handleDrawerClose = () => { onDrawerClose(); };

return ( <>

  <Drawer isOpen={drawerOpen} direction="right" drawerWidth="700px">
    <DrawerHeader handleCloseDrawer={handleDrawerClose} />
    <DrawerBody p={5}>
      <Flex mb={4}>
        <Box flex={1}>
          <Text fontWeight="light" fontSize={4} mt={3} mb={4}>
            Add custom amenities
          </Text>
        </Box>
      </Flex>
      <Form>
      <FieldArray
          name="amenitieslist"
          render={arrayHelpers => (
            <div>
            {// values.amenitieslist && values.amenitieslist.length > 0 ? (
              values.amenitieslist.map((amenity, index) => (
                <div key={index}>
                  <Field name={`amenitieslist.${index}.name`} />
                  <button
                    type="button"
                    onClick={() => arrayHelpers.remove(index)} // remove a amenity from the list
                  >
                    -
                  </button>
                  {errors.amenitieslist}
                </div>
              ))}
              <button type="button" onClick={() => arrayHelpers.push({ id: "", name: "", imageUrl: '', description: '', tenantAssessmentId })}>
                {/* show this when user has removed all amenities from the list */}
                Add a Amenity
              </button>
          </div>
        )}
        />
        <div>
            <button type="submit">Submit</button>
          </div>
</Form>
    </DrawerBody>
  </Drawer>
</>

); };

export const AmenitiesDrawer = withFormik<IAmenitiesDrawerProps, IAmenitiesDrawerValues>({ enableReinitialize: true, handleSubmit: (values, {props}) => { const seed: number = props.maxRank? props.maxRank : 0; const amenityRankings: IAmenityRanking[] = values.amenitieslist.map((a, index)=>({ amenityId: 1, rank: index + 1 + seed, amenityName: a.name, customAmenity: true })); console.log(amenityRankings); console.log(props.actions.customSaveAmenities); console.log(props.tenantAssessmentId); props.actions.customSaveAmenities(props.tenantAssessmentId, amenityRankings); }, mapPropsToValues: ({tenantAssessmentId}) => ({ amenitieslist:[{id: 0, name: '', imageUrl: '', description: '', tenantAssessmentId}] }), validate: values => { const errors: FormikErrors<{ validAmenity: string }> = {}; console.log('In the Validate method'); const { amenitieslist } = values;

const amenityValid = amenitieslist[0].name.length < 28;
if (!amenityValid) {
    console.log('Amenity is not valid');
  errors.validAmenity = "Amenity needs to be atmost 28 characters";
  console.log(errors);
}

return errors;

} })(InnerForm);

bsabhiram commented 5 years ago

No one is answering this question ?

vigneshwaran-chandrasekaran commented 5 years ago

It's not a issue, put your code in codesandbox and ask for help