# Form Architecture

## What is form for?

Initially a form component was invented to deal with Configuration Item (CI). This item is based on XL type system 
and therefore fully dynamic. In order to be able to render a component for that, it should know how to render such 
form based on provided metadata. Metadata contains definitions of each property of the type and corresponds to a 
property field in a form. Metadata for a form is based on type system, but not limited with that. It is a superset,
which contain more options to affect the rendering. 

We don't limit ourselves to use this form only for CIs, but also for other type of data. At this case same approach is 
applied by providing a metadata which describe fields for a form.

## What can form do apart from rendering

Form has more functionality then just render fields. There is also a logic to deal with
 * validations - some validation is embedded, like for example for required fields. For custom validation
  it is possible to provide own validators. Validators are triggered each time when user does any changes on a form -
  typed new letter, changes a value in drop down, etc. Apart from that it is also possible to provide validation 
  messages through _model_ (this is a data for each field in a form). This case is used when it is required to do an 
  entire form validation on the server side and to do validation for each change is too resource expensive. 
* pristinity - the information about which fields are modified by user. Once a form is only created all fields are 
pristine. All fields of form resets to a pristine state when updated data was saved.
* (validation) messages - keeps the information about which message for each field has to be shown to the user in case 
field has warnings or errors. 

## What is the difference between warning and error

Error indicates that a form can't be saved. Warning in its own turn shows that supplied data conforms the requirements 
described for this type of form, but it might lead to a problem of using it. 

## How to define validation for a form

First level of validation comes with the metadata description. It is possible to define a required field and at this case
user can't leave it blank. 

```json
{
    "required": true,
    ...
}
```

Once user started modifying the field error has to be displayed. In example with require field, if user started typing
some value and then wiped out what it was typed - error should be shown to the user. Second way to see error - is 
to have an attempt to save the form. All invalid fields should be highlighted and provided with corresponded messages.
Initially we don't show errors to not a form with too much of red colors.

Second place in metadata is _inputHint_ (example): 
```json
{
    "inputHint": {
      "kind": "ENUM",
      "rules": [],
      "values": [
        {"value":  "NONE", "label":  "NONE"},
        {"value":  "STOP", "label":  "STOP"},
        {"value":  "START", "label":  "START"},
        {"value":  "STOP_START", "label":  "STOP_START"}
      ]
    },
    ...
}
```
 
Currently input hints work only with fields of kind "STRING". In such case on a form instead of an input field 
is going to be rendered a dropdown with provided values in inputHint.   

![String field with input fields](./imgages/restart_strategy_options.png)

Warnings are displayed only when user tries to save CI (user should face a confirmation dialog whether he wants 
to save CI with warnings, keep in mind that this logic is not done as a part of the form yet, but rather has 
to be implemented in the product) or if existing CI is opened.

Second level of validation is done by provided custom validators. 
Syntax for validator is:
```javascript
    const validator = (fieldName, model) => ({
      condition: true/false,
      message: {
          show: true/false,
          text: 'Validation message what went wrong',
          type: 'ERROR'/'WARNING'
      }
    })
```

In validator you have an access to a name of the field and the value provided by user. Based on that you can perform
a validation. This validation is triggered each time when user make any changes in that field. Validators are provided
when form is created.

## Lifecycle of form and product

