Using annotation in melies model to render a custom component

Overview and detail view in the master-detail layout designed by A12 for business application has already provided a range of components such as selection box, text line/area, checkbox, radio box, etc. for you to display data in a form. However, customer’s requirements are often very diverse. For instance, a customer may want to display an image preview in the detail view which has not been supported yet.

Understand about that diversity, A12 gives a powerful extension point here called annotation which not only allows you to render a custom component in the view but also can be used for many purposes. In this post, we will take rendering an image view as an example to see how can we use annotation in melies model.

First of all, you need to create an annotation for the field that you want to replace by your custom component which is able to display an image.
For example, I will create an annotation with the name display-image like below in melies model xml file:

<annotation name="display-image">
    <display-image>Description</display-image>
</annotation>

After that, you need to implement your custom component - React component to display an image and hook that into the renderer of the control/field you want to replace. Below is an example of overriding a createControl function to hook the custom component ImagePreview into a control in grid.

import * as ReactView from "@com.mgmtp.a12/form-engine/lib/main/view/react-view";

export class CustomWidgetFactory extends ReactView.DefaultReactWidgetFactory {

	static ANNOTATION = "display-image";

	// control in grids
	createControl(
		services: ViewServices,
		control: Melies.Control,
		editor: Editor,
		context: GroupInstance,
		width: number
	): React.ReactElement<{}> {
		if (control.annotations[CustomWidgetFactory.ANNOTATION]) {
			return React.createElement(
				ImagePreview,
				{
					key: control.getUiId(),
					component: control,
					editor: editor,
					context: context,
					fieldInstance: control.findFieldInstance(context),
					width: width,
					factory: this,
					services: services
				}
			);
		} else {
			return super.createControl(services, control, editor, context, width);
		}
	}
...
}

Finally, you need to pass that CustomWidgetFactory as a variable into EngineOptions.widgetFactory and the FormEngine will take the part of rendering that custom React component when it finds the match annotation in the xml file.

Annotation can be used for the other purposes like rendering a file upload section, display a WYSIWYG editor for the text area, etc. Hopefully, after reading this post, you will be able to use annotation to achieve your goal.

great to have annotations interface documented. thanks!
small additions:

  • this feature is not supported only by the the UI model (xml) . It is even supported by the ui designer (Melies) itself (add annotation). So analists can stay on pure modeling side.
  • annotatins do not work just for rendering. They can be used for any call of JS (e.g. custom calculations, call of any services such as file selection, file upload/download gadgets …)

Note: Examples for above mentioned use cases from A12 based systems operational at customer premises (<PROJECT_NAME>) can be found here <INTERNAL_LINK>

end advertizing