Skip to content

Latest commit

 

History

History
303 lines (273 loc) · 6.34 KB

FormGenerator.md

File metadata and controls

303 lines (273 loc) · 6.34 KB

FormGenerator

A react component which generates a tree of control objects & render the UI by keeping the same order in which the controls have been defined in fieldConfig.

How it works

  • It creates a new instance of FormGroup ( if controls property is an object ) or FormArray ( if controls property is an array ) if the control property is not supplied.
  • It renders the form UI according to the control-component mapping by keeping the same order in which they have been defined in fieldConfig.
  • You can define a parent control by passing the parent property.
  • If a control prop is defined then it just returns the same.

Props

onMount: (form: FormGroup|FormArray) => void 

A function callback called when a form has been rendered, the basic use case is to save the form instance for further uses.

onUnmount: () => void

A function callback called when a form has been unmounted.

fieldConfig: {[key: string]: any}

Field config has a set of properties which are required for the form configuration.

Properties of fieldConfig

controls: Array<{[key: string]: any}> | {[key: string]: any};

FormGenerator creates a FormGroup if the controls property is an object.

For example the following config will create a FormGroup with two form controls named username & password respectively.

const fieldConfig = {
  controls: {
    username: {
    ...
    },
    password: {
      ....
    }
  }
}

FormGenerator creates a FormArray if the controls property is an array.

For example the following config will create a FormArray with two form controls at index 0 & 1 respectively.

const fieldConfig = {
  controls: [
    {
      ... // item1
    },
    {
      ... // item2
    }
  ]
}

Nested Controls

You can also define the nested controls in the same way.

Example: Nested controls in FormGroup

const fieldConfig = {
  controls: {
    address: {
      controls: {
         city: {
           ...
         },
         country: {
           ...
         }
      }
    }
  }
}

The above example will create a structure like that:

{
  address: {
    city: "",
    country: ""
  }
}

Example: Nested controls in FormArray

const fieldConfig = {
  controls: [
    {
      // item1
      controls: {
        itemName: {
          ....
        },
        itemPrice: {
          ...
        }
      }
    }, 
    {
      // item2
    }
  ]
}

The above example will create a structure like that:

[
  {
    itemName: "",
    itemPrice: ""
  },
  "" // item2
]

formState: any|{ value: any, disabled: boolean }

You can use this property to define the initial state of the control.

Note:

Only works with FormControl

meta: {[key: string]: any};

You can pass an object of custom inputs to customize your component.

    render: (control: FormArray|FormControl|FormGroup) => React.ReactElement<any>|React.ReactElement<any>[];

A render function prop which returns a react component which needs to be re-render whenever the control state changes.

Note:

Only works with FormControl

For example:

const fieldConfig = {
  controls: {
    username: {
      render: TextInput // some react component to render an input,
      meta: {
        label: "Username"
      }
    },
    password: {
      render: TextInput,
      meta: {
        label: "Password",
        type: "password"
      }
    }
  }
}

index: number

To define at which index the controls has to be inserted if the parent control is an instance of FormArray.

Note:

Only works if the parent is FormArray.

options: AbstractControlOptions;

You can pass the AbstractControlOptions as options props.

For example:

const fieldConfig = {
  controls: {
    username: {
      render: TextInput // some react component to render an input,
      meta: {
        label: "Username"
      }
      options: {
        validators: Validators.required,
        updateOn: 'blur'
      }
    },
    password: {
      render: TextInput,
      meta: {
        label: "Password",
        type: "password"
      },
      options: {
        validators: Validators.required,
      }
    }
  }
}

control: AbstractControl;

An instance of AbstractControl control.

parent: AbstractControl;

An instance of FormGroup or FormArray class as a parent control.

Inject a component

FormGenerator generates the UI in the same order in which the controls have been defined in the formConfig, so sometime you may need to add a component in between the controls. FormGenerator provides this facility by defining a $field_ property to determine that the control is not need to be added so it just renders the component.

If the parent is FormGroup then you can inject a component by defining the control name starts with$field_.

For Example:

const fieldConfig = {
  controls: {
    $field_0: {
      render: () => <span>Username:</span>
    },
    username: {
      render: TextInput,
    },
    $field_1: {
      render: () => <span>Password:</span>
    },
    password: {
      render: TextInput,
      meta: {
        label: "Password",
        type: "password"
      }
    }
  }
}

If the parent is FormArray then you can inject a component by defining the control's index starts with$field_.

const fieldConfig = {
  controls: [
    {
      index: "$field_0"
      render: () => <span>Item1:</span>
    },
    {
      render: TextInput
    },
    {
      index: "$field_1"
      render: () => <span>Item2:</span>
    },
    {
      render: TextInput
    }
  ]
}

You can also access the root control object by using the $field_ control & subscribe the component for the form state changes by just defining the isStatic property as false.

For example:

const fieldConfig = {
  controls: {
    username: {
      render: TextInput,
    },
    password: {
      render: TextInput,
      meta: {
        label: "Password",
        type: "password"
      }
    },
    $field_0: {
      isStatic: false,
      render: ({ invalid }) => <button disabled={invalid}>Submit</button>
    },
  }
}