Before you can start implementing your view-model we need to define what that is.
view-model: A data model that serves as a bridge between the form and the BE so that you can prefill/update/validate form data.
A view-model is a data class that implements the ViewModel
interface. The interface has a single method update(task: CamundaTask?)
that is used to update the view-model based on the data that is passed to it.
In case of a FormIO wizard you need to implement the update(task: CamundaTask?, page: Int?)
method. The page integer contains the current page of the user in the wizard. Going to the next or previous page will trigger this method and if an exception is thrown navigating to the next or previous page is blocked.
The update(task: CamundaTask?)
method is triggered when the update endpoint is called. This endpoint is called automatically when a change is made in the form.
data class TestViewModel(
val firstName: String,
val lastName: String,
val fullName: String = "$firstName $lastName",
val age: Int,
var adultPermissionRequired: Boolean = false
) : ViewModel {
override fun update(task: CamundaTask?): ViewModel {
if (this.age!! < 18) {
this.adultPermissionRequired = true
}
return this
}
}
After you define a ViewModel
you also need to define a loader.
A ViewModelLoader
is a class that is used to load the view-model.
The load(task: CamundaTask?)
method is used to load the view model. When the form is related to a user task, the task: CamundaTask is passed to this method.
The supports()
method is used to find the correct loader for the given form.
The getFormName()
method is used to get the form name to which this loader is connected.
The generic type that is passed to the ViewModelLoader
is used for validating the ViewModel
on start-up.
The ViewModelLoader
also needs to be registered as a bean in the Spring context.
@Component
class TestViewModelLoader : ViewModelLoader<TestViewModel> {
override fun load(task: CamundaTask?): TestViewModel {
return TestViewModel(
firstName = "",
lastName = "",
age = 0
)
}
override fun supports(formName: String): Boolean {
return formName == getFormName()
}
override fun getFormName(): String = "test"
}
On start up a class will validate that the structure of the ViewModel
matches the submission structure of the form. If not an error message will be printed in the logs. Note that extra properties may be included in the form.
Here is an example of the error message:
The following properties are missing in the view model for form (user-task-2): [age]
More info on the validation can be found here: Contract validation on ViewModel and Submission