Dynamic forms with angular - improved
- angular
In my very first post (see Dynamic forms with angular) I explained how I manage to have dynamic forms in angular. Since that time I applied this solution several times and so far it made my angular programming days a bit easier.
- Dynamic forms with angular
- Dynamic forms with angular - improved
In this post I will introduce another feature I added - the SlotHostComponent
. It will allow you to inject custom form parts in your dynamic form. I normally try to group forms into meaningful fieldsets or in angular-ish FormGroup
s. I then create a Slot
for each group. I basically treat a Slot
as one fieldset in HTML language spoken.
And as you probably can imagine, having different Slot
-types instead of only the default ones (Slot
and ArraySlot
) can be quite useful.
For the sake of this post I created a sample on StackBlitz that showcases the parts you need to respect in order to place a custom Slot
within an angular form.
The “custom-slot.component” sample
The sample that I created does not actually do something meaningful. On the other hand it shows the possibilities I gained after having the SlotHostComponent
implemented. If you open StackBlitz and go the the “Custom” route you will see a nested form with two Slot
s. The first one shows some personal data. The second one shows the json serialized output of the actual underlying Slot
-data you have as a programmer and the respective Form
-model the FormGroup
carries.
Pieces you need
In order to implement a custom Slot
you will need to prepare the following pieces:
- a
Slot
-model: Within this model you define the structure of your FormGroup. It also inherits from theSlot
class so we get all the properties to work with. - a custom-slot.component: Within this component we provide the markup we would like to be rendered for our custom form. It inherits from
BaseSlotComponent
so we get access to the underlying properties like the slot-property and the form-property. - the
SlotComponentRegistry
: This new service which is located within the formdef-directory is used to register customSlot
s. - a host component of the actual form
Based on the list in the “Peaces you need” we are now going to look at some implementation details for the CustomSlotComponent
sample.
The slot
model
The CustomSlot
model defines the structure of our form. It is a fairly simple form with a nested “Address” slot.
1 | export class CustomSlot implements Slot { |
The custom-slot.component
The CustomSlotComponent
-component is our main component of interest. Here we make advantage of the underlying slot
and form
- property in order to implement the functionality and behavior we would like to achieve.
In the template you can clearly see that we have direct access to the slot
or form
- property. For this dumb component and the demo’s sake we just serialize the slot
value as a json string. I did the same with the form.value
property to actually see their values on the screen.
1 | ({ |
The SlotComponentRegistry
In order to let the angular application know of our custom slot component we need to tell the SlotComponentRegistry
about it.
The snippet below shows how the CustomSlotComponent
needs to be registered.
1 | export class CustomModule { |
Don’t forget to add your custom slot component to the
entryComponents
!
The host component of the actual form
On this component we host the FormDef
-element (see tw-formdef). This is usually the component you route to when to create or edit some object. In our case the model is the hard coded viewmodel
-object.
1 | ({ |
Benefits
The above approach helped me to find the right mix between always writing angular forms from scratch over an over again and the dynamic forms generation approach I described in my first post. Now I have the possibility to create my own slots that differ from the default implementations.
The benefits in short I think are:
- still have a generic data driven form generation approach
- inject custom slots like:
- chart slot that depends on slot data
- different styling or arrangement of controls than default slots
- direct access to slot data and FormGroup control instance within custom slot component
If you came up with some similar or other approach I would be interested in, just leave a comment.
I hope this post could help you in some kind or the other.
Cheers Thomas