Edit / Create Action | Form View
The edit and create views both show a form component and are quite similar.
The actions behave as follows:
Save
- checks required values, continues only if all required validations pass
- calls
savemutation- if mutation validation returns validationErrors - shows validation errors at the fields
- if mutation was successful - redirects to
showaction
Cancel
- redirects to
showaction without any further action
Form
Both actions will query all necessary data to render the form:
- all attributes (per configuration)
- all
assocToandassocToManyrelationships that are referenced by this entity's item - all items for any
assocToandassocToManyrelationships to populate the select / autocomplete controls (if this would be too much data, consider providing a custom query or - as always - implementing this in a custom component.)
Configuration
| Option | type | default | description |
|---|---|---|---|
| fields | (string|FieldConfig)[] | see below | what fields to show in the form and what control to use to capture input |
| query | QueryFn | custom query for all form data | |
| query | QueryFn | custom query for all form data |
FieldConfig
| Option | type | default | description |
|---|---|---|---|
| name | string | the name of the attribute or entity of the assoc or assocToMany | |
| type | string | the type from the domain configuration | the type of the attribute or entity of the assoc |
| label | string | ()=>string | lookup in resources or humanized field name | the column label for the field |
| list | boolean | dependent from the attribute / assoc type in the domainConfiguration | the column label for the field |
| prepareFormInput | Function | called before setting the field value in form | |
| sanitizeFormInput | Function | called before setting the field value in the save mutation | |
| disabled | boolean | false | disable input / read-only field |
| required | boolean | false | adds client-side required validation to field |
| list | boolean | value from domain configuration for field | effect on control |
| query | `()=>string | any` | part of query for this field, especially lookup |
| control | string | which control should be used to render this field / assoc | |
| options | (data:any)=>FormOptionType[] | generates the form options (if this is lookup field) from the data of the action query |
Label
If you do not provide a label, the default label will be looked up under this path in the resources of the AdminConfig.
['resources', locale, 'entities', entity, 'label', field]If no such entry exists, the humanized attribute name of the entity or the humanized name of the assoc entity will be used.
prepareFormInput / sanitizeFormInput
You can influence the value from the GraphQL API before it is presented to the user. Let's take as an example the price of a car. You decided in you entity configuration to manage the price of a car as an integer (of the smalles currency unit) e.g. cents instead of a float to avoid round issues and having to deal with fixed decimals on the server.
entity:
Car:
attributes:
license: Key
price: Int In your UI nonetheless you want to present the user with the € value. So we have to calculate this value before it is set to the form. We also have to calculate the Int value from the € before sending it to the save mutation. Of course, the usage of lodash (opens in a new tab) is absolutely optional.
const adminConfig:AdminConfig = {
entities: {
Car: {
edit: {
fields: [
'license',
{
name: price,
prepareFormInput: (value:any) => ( _.toNumber(value) / 100 ).toFixed(2),
sanitizeFormInput: (value:any) => _.round( _.toNumber( value ) * 100 )
}
]
}
}
}
}control
| default | implementation | |
|---|---|---|
| select | {list:true} | mat-select (opens in a new tab) or mat-autocomplete (opens in a new tab) if more then configured items |
| multiple | assocToMany | mat-select (opens in a new tab) |
| number | {type:'Int'|'Float'} | matInput (opens in a new tab) |
| datepicker | {type:'Date'|'DateTime'} | matDatepicker (opens in a new tab) |
| file | {type:'File'} | <input type="file"> |
| richtext | {mediaType:'richtext'} | ngx-quill (opens in a new tab) |
| chips | mat-chip-list (opens in a new tab) | |
| [any other] | matInput (opens in a new tab) |
If you need any other control, you have to create a custom route / custom component and implement the (whole) form yourself.