Custom Form
Custom process forms can be useful if you need to render a form in a non-standard way. In the modeler, you can provide a form id, a list of form parameters and a list of outcomes for a custom form.
If you use an alternative UI technology (for example, react) then you need to get the form information and render the form using this information. You can obtain form information using the FormService
interface that has the following methods:
-
StartFormData getStartFormData​(String processDefinitionId)
-
TaskFormData getTaskFormData​(String taskId)
To render custom forms in the Start process or My tasks screens, you need to define the ProcessFormScreenCreator
for the custom
form type. To override the default ProcessFormScreenCreator
, you need to add the @Order
annotation.
Let’s look at the example of MyCustomProcessFormScreenCreator
that implements ProcessFormScreenCreator
:
@Component("samples_MyCustomProcessFormScreenCreator")
@Order(1) (1)
public class MyCustomProcessFormScreenCreator implements ProcessFormScreenCreator {
@Autowired
private ScreenBuilders screenBuilders;
@Override
public String isApplicableFor() { (3)
return "custom";
} (2)
@Override
public Screen createStartProcessScreen(CreationContext creationContext) { (3)
Screen screen = screenBuilders.screen(creationContext.getFrameOwner())
.withScreenId(creationContext.getFormData().getScreenId())
.withOpenMode(OpenMode.DIALOG)
.build();
if (screen instanceof AcceptsProcessDefinitionData) { (4)
((AcceptsProcessDefinitionData) screen)
.setProcessDefinitionData(creationContext.getProcessDefinitionData());
}
return screen;
}
@Override
public Screen createUserTaskScreen(CreationContext creationContext) { (5)
Screen screen = screenBuilders.screen(creationContext.getFrameOwner())
.withScreenId(creationContext.getFormData().getScreenId())
.withOpenMode(OpenMode.DIALOG)
.build();
if (screen instanceof AcceptsTaskData) { (6)
((AcceptsTaskData) screen).setTaskData(creationContext.getTaskData());
}
return screen;
}
}
1 | The @Order annotation indicates that this implementation of ProcessForScreenCreator will be used first. |
2 | ScreenCreator will be applied to custom process forms. |
3 | Overrides the method for creating a start process form. |
4 | Checks if the screen implements AcceptsProcessDefinitionData . In this case, it is necessary to set ProcessDefinitonData to the screen. |
5 | Overrides the method for creating a task process form. |
6 | Checks if the screen implements AcceptsTaskData . In this case, it is necessary to set TaskData to the screen. |
An example of the AcceptsProcessDefinitionData
interface:
public interface AcceptsProcessDefinitionData {
void setProcessDefinitionData(ProcessDefinitionData processDefinitionData);
}
An example of the AcceptsTaskData
interface:
public interface AcceptsTaskData {
void setTaskData(TaskData taskData);
}
XML descriptor of the custom start form that has only Start process button:
<window xmlns="http://jmix.io/schema/ui/window"
caption="msg://customStartForm.caption">
<layout>
<button id="startProcessBtn" caption="msg://startProcessBtn.caption"/>
</layout>
</window>
Screen controller of the custom start form:
@UiController("smpl_CustomStartForm")
@UiDescriptor("custom-start-form.xml")
public class CustomStartForm extends Screen implements AcceptsProcessDefinitionData {
private ProcessDefinitionData processDefinitionData;
@Autowired
private RuntimeService runtimeService;
@Subscribe("startProcessBtn")
public void onStartProcessBtnClick(Button.ClickEvent event) {
runtimeService.startProcessInstanceById(processDefinitionData.getId());
closeWithDefaultAction();
}
@Override
public void setProcessDefinitionData(ProcessDefinitionData processDefinitionData) {
this.processDefinitionData = processDefinitionData;
}
}
XML descriptor of the custom task form that has only Task complete button:
<window xmlns="http://jmix.io/schema/ui/window"
caption="msg://customTaskForm.caption">
<layout>
<button id="completeTaskBtn" caption="msg://completeTaskBtn.caption"/>
</layout>
</window>
Screen controller of the custom task form:
@UiController("smpl_CustomTaskForm")
@UiDescriptor("custom-task-form.xml")
public class CustomTaskForm extends Screen implements AcceptsTaskData {
private TaskData taskData;
@Autowired
private TaskService taskService;
@Subscribe("completeTaskBtn")
public void onCompleteTaskBtnClick(Button.ClickEvent event) {
taskService.complete(taskData.getId());
closeWithDefaultAction();
}
@Override
public void setTaskData(TaskData taskData) {
this.taskData = taskData;
}
}