Skip to content
r-kohale9 edited this page Dec 5, 2019 · 2 revisions

Here we will see how to create forms using formik:

Step 1-

Define the validation part by creating a field schema by doing this initailly, you can keep track of all the fields you want to create and their properties.

import {
  minLength,
  required,
  validate,
  maxLength
} from "@gqlapp/validation-common-react";
const componentNameFormSchema = {
  fieldA: [required, minLength(3)],
  fieldB: [required, maxLength(10)],
  fieldC: []
};
  • 'required' means that the user cannot skip this field.

Step 2-

Next, define default values for corresponding fields, submission handling, and validation by linking the above schema with the values.

import { withFormik } from "formik";

const ComponentNameWithFormik = withFormik({
  // By default is false, self explanatory.
  enableReinitialize: true,

  // Assign the default values with respect to names of the fields default values may be assigned from props or hard coded.
  mapPropsToValues: props => ({
    fieldA: "",
    fieldB: props && props.fieldB ? props.fieldB : "",
    fieldC: "fieldC"
  }),

  // Form submission handling, this part recieves an input called values i.e values of the form field entered by the user
  async handleSubmit(values) {
    console.log("values", values);
  },

  // Link the schema created initailly with the values.
  validate: values => validate(values, componentNameFormSchema),

  displayName: "Forms" // helps with React DevTools
});

Step 3-

Create form component and add fields

import { Form } from "antd";
import { RenderField, Button } from "@gqlapp/look-client-react";
import { FieldAdapter as Field } from "@gqlapp/forms-client-react";

class ComponentName extends Component {
  render() {
    // While using formik the formik passed some helpful tools to the components such as touched, setinitialvalues etc through props to the component.
    const { values, handleSubmit } = this.props;

    return (
      <Form onSubmit={handleSubmit}>
        <Field
          name="fieldA"
          component={RenderField}
          placeholder="bleh"
          type="text"
          label="FieldA"
          value={values.fieldA}
        />
        <Field
          name="fieldB"
          component={RenderField}
          placeholder="bleh"
          type="text"
          label="FieldA"
          value={values.fieldB}
        />
        <Field
          name="fieldC"
          component={RenderField}
          placeholder="bleh"
          type="text"
          label="FieldA"
          value={values.fieldC}
        />

        <Button type="submit">Submit</Button>
      </Form>
    );
  }
}

Step 4:

Link the component with the properties defined in Step 2

export default ComponentNameWithFormik(ComponentName);

Basic form Skeleton

import React, { Component } from "react";
import { Form, Select, Radio } from "antd";
import PropTypes from "prop-types";
import { withFormik } from "formik";
import {
  RenderField,
  Button,
  RenderSelect,
  RenderCheckBox,
  RenderRadioGroup,
  RenderUpload,
  RenderDateRangePicker,
  RenderAutoComplete
} from "@gqlapp/look-client-react";
import {
  minLength,
  required,
  validate,
  maxLength
} from "@gqlapp/validation-common-react";
import { FieldAdapter as Field } from "@gqlapp/forms-client-react";

const RadioButton = Radio.Button;
const dataSource = [{ name: "foo" }, { name: "bar" }, { name: "baz" }];

const formsFormSchema = {
  renderField: [required, minLength(3)]
};

class Forms extends Component {
  state = {
    // FOR RENDERAUTOCOMPLETE
    dataSource: []
  };
  searchResult(query) {
    var items = dataSource.filter(
      item =>
        item.name.toUpperCase().includes(query.toUpperCase()) ||
        (item.profile &&
          ((item.profile.firstName &&
            item.profile.firstName
              .toUpperCase()
              .includes(query.toUpperCase())) ||
            (item.profile.lastName &&
              item.profile.lastName
                .toUpperCase()
                .includes(query.toUpperCase()))))
    );
    return items;
  }

  // FOR RENDERAUTOCOMPLETE
  handleSearch = value => {
    this.setState({
      dataSource: value ? this.searchResult(value) : []
    });
  };
  render() {
    const { values, handleSubmit } = this.props;
    const array = ["foo", "bar", "baz"];

    return (
      <Form onSubmit={handleSubmit}>
        <Field
          name="renderField"
          component={RenderField}
          placeholder="Render Field"
          type="text"
          label="Render Field"
          value={values.renderField}
        />
        <Field
          // disabledDate={disabledDate}
          name="dateRange"
          component={RenderDateRangePicker}
          value={values.dateRange}
          // onChange={v => setDateRange(v)}
        />
        <Field
          name="renderAutoComplete"
          dataSource={this.state.dataSource.map(item => item.name)}
          component={RenderAutoComplete}
          label="renderAutoComplete"
          value={values.renderAutoComplete}
          // onSelect={this.onSelect}
          onSearch={this.handleSearch}
        />
        <Field
          name="renderSelect"
          component={RenderSelect}
          type="select"
          label="Render Select"
          value={values.renderSelect}
        >
          {array.map((e, idx) => (
            <Select.Option key={idx} value={e}>
              {e}
            </Select.Option>
          ))}
        </Field>
        <Field
          name="renderCheckBox"
          component={RenderCheckBox}
          label="Render Check Box"
          checked={values.renderCheckBox}
        />
        <Field
          name="renderRadioGroup"
          component={RenderRadioGroup}
          type="text"
          label="Render Radio Group"
          value={values.renderRadioGroup}
        >
          {array.map((e, idx) => (
            <RadioButton key={idx} value={e}>
              {e}
            </RadioButton>
          ))}
        </Field>
        <Field
          name="renderUpload"
          component={RenderUpload}
          type="text"
          // setload={this.props.setload}
          label="Render Upload"
          // value={}
        />
        <Button color="primary" type="submit">
          Submit
        </Button>
      </Form>
    );
  }
}

Forms.propTypes = {
  values: PropTypes.object,
  handleSubmit: PropTypes.func
};

const FormsWithFormik = withFormik({
  mapPropsToValues: () => ({
    renderField: ""
    // renderSelect: ''
  }),
  handleSubmit(values, { props: { onSubmit } }) {
    console.log("values1", values);
    // onSubmit();
  },
  validate: values => validate(values, formsFormSchema),
  displayName: "Forms" // helps with React DevTools
});

export default FormsWithFormik(Forms);

Clone this wiki locally