Dynamic forms with angular
- angular
In this post I am going to explain my approach to generate dynamic forms with angular. Therefore I set up a small ng-cli based project called formdef that shows a working sample.
- Dynamic forms with angular
- Dynamic forms with angular - improved
See the sample application hosted by StackBlitz in action here.
My requirement
If your frontend runs on top of some restful backend you usually end up consuming some json based objects in the client - your viewmodels. Such a viewmodel then somehow gets presented to the user within a form. The form itself allows to create, modify or delete that data by applying the changes to the viewmodel and sending it back to the appropriate api endpoint.
If you have a small application with just a couple of forms it is totally fine to create the required form templates for each specific purpose. But my daily business requires me to write quite a lot of forms. That’s where my approach to dynamic forms with angular can help.
The goal: Generate a form based on a viewmodel and a form definition.
The idea
The basic workflow of what I came up looks like this:
- take a viewmodel
- take the appropriate form definition for that viewmodel
- create a FormGroup by merging viewmodel with form definition
- render it with a Component
The contracts
Before I start to explain the concept let’s briefly have a look at our contracts. An Editor
is the interface to any kind of input element, i.e. input, checkbox, select, etc. The Slot
on the other hand defines the structure of our form and should reflect the viewmodel object graph. Additionally the Slot
carries the information about the different editors.
1 | export interface Editor { |
Register form definitions
The FormdefRegistry
acts as the application wide registry for form definitions. Simple as that…!
1 | () |
The heart - the FormdefService
The FormdefService
has all it needs to merge our viewmodel together with the form definition. The result is a FormGroup
that can be used like described in the Reactive Forms section in the fabulous angular tutorials.
1 | () |
Our example viewmodel represents a contact and looks like this:
1 | public viewModel = { |
The form definition object to our contact viewmodel looks like this:
1 | export class ContactSlot implements Slot { |
The result of the merging operation will be a FormGroup
.
Rendering the form - the FormdefComponent
In order to display the dynamic form to the user I came up with the SlotComponent
, a component that has the ability to render the tree of a particular Slot
recursively. It is hosted within the FormdefComponent
.
If you want to play around then it is now time to go here!
Benefits
- The submitted FormGroup value is equal to our viewmodel and can easily be used in a put or post request dependent of what you want to achieve.
- Within the application I have a common forms/ux experience.
- The form definitions could also be part of an api instead of hard coding it in the client.
Summary
The formdef module shown in the sample app contains the required logic to satisfy my requirements. For sure there is lot’s of room to improve but so far I am happy.
What are your experiences with dynamic forms in angular?
Let me know… Thomas