Skip to Content
Technical Articles
Author's profile photo Vaibhav Agarwal

Part 1 – Custom Dynamic Form control based on OData Metadata Annotations


In this blog I am showcasing a Dynamic Custom Control which can be used to render a form in any UI Application with minimal code. It uses the OData metadata annotation to render control in form field. It supports message handling and perform validation on correctness of values based on data type of that field.

There is a similar kind of Smart Form control available but this Form Control offers far more flexibility and developer have to write much less code to declare it.

So lets start with the looking at Form control in Display and in Edit Mode.

                                                Figure 1: Sales Order Form in Display Mode


                                                Figure 2: Sales Order Form in Edit Mode


Control Features

Details of Control Type Supported in the control

This control supports varied control types. The usage of these control type and their configuration are based on annotation provided in the metadata of the property. By default this control uses 8 control types which are used commonly in any form. These are listed below along with what annotation to be used.

Additionally this control also supports loading of control type different from default one or overriding of default behavior of these control types (Refer control property propertyMap for more details  regarding this).

Date Picker

Assign Edm.Type = Edm.DateTime or Edm.DateTimeoffset in the entity to that.  an

Note:- Also Provide a custom annotation sap:display-format="Date"

Time Picker

Assign Edm.Type = Edm.Time in the entity.

Note:- Do not provide sap:display-format="Date" annotation


Date Time Picker

Assign Edm.Type = Edm.DateTime or  Edm.DateTimeoffset in the entity.

Note:- Do not provide sap:display-format="Date" annotation


Text Area

MaxLength in the entity should be more than 50 to render a TextArea control.


Amount-Currency Type Control

Assign sap-unit=’Name of the Currency property’ annotation to to Amount property as it is              done in this example – sap-unit=”CurrencyCode” is assigned to NetAmount.


Yes-No Option Control (CheckBox like)

Assign sap-isCheckBox=’true’ annotation to the property for which a ComboBox with option            yes/no is required. It can be interpreted as a Checkbox.


Assign sap:value-list=”fixed-values annotation to the property for which ValueHelp is to be            rendered. Also assign the name of the property as a reference to the ValueHelp Entity to                    load data in the ValueHelp.



By default Input control will be loaded

Field Control

This control uses Field Control feature of OData to dynamically update the visual configuration of Control type. These 4 types of Configuration are as follows:-

1. Mandatory

Pass 7 to Field Control value (here Uxfc01) at the time of fetching data.

2. Read only

Pass 1 to Field Control value (here Uxfc01) at the time of fetching data.

Additionally it also uses sap:creatable and sap:updatable annotation in entity to make a field as read only.

Note: Later will take preference over the former in case of conflict.

3. Hiding fields

Pass 0 to Field Control value (here Uxfc01) at the time of fetching data.

Additionally it also uses sap:visible annotation in entity to hide a field.

Note: Later will take preference over the former in case of conflict.

4. Optional

Pass 3 to Field Control value (here Uxfc01) at the time of fetching data.

In this case the default behavior of the control will be used.

Validations & Checks

Control itself validates whether any field in the form is invalid or not.

It verifies that all the mandatory fields are having values, fields are having valid values or not (based on Edm.Type)


Properties available in this control

Name Type Default Value Description
string Specifies Name of the OData entity
string null Title of the form
string null Specifies mode in which control needs to be Rendered. “E” for Edit mode and “D” for display Mode

Specifies Explicit list of fields to display. All other fields will be ignored.

Example of Usage

<Form includeOnlyFields=”F1,F2,F3″ />

boolean true Specifies whether to use split form layout (with two form containers)
boolean false If set to true then all the fields in the Form becomes mandatory

Specifies name of the OData Model.

Note:- Use this property only when odata model has some name

string Specifies the path in the binded model(Name of the model is stored in the property modelName) where Form data is stored
string Name of the Binded Model where data of the Form is stored
string[] []

Specifies name of the field which have to be marked as mandatory and those are not configurable by the user.

Example of Usage

<Form mandatoryFields=”F1,F2,F3″ />




Using this property a user can handle:-

1. Custom Behavior of default types*

Using the user can override the the default behavior of the control type and provide their own custom behavior.

2. Custom Control type factory**

Using this user can even user their own control factory if the default one does not suites to their requirement.

*  Let say there is requirement to override enabled property of LifeCycleStatus field then it can be done in following manner

      enabled: // Handling of enable property


** Let say there is requirement to use a checkbox type control instead of default Yes/No ComboBox for field then it can be done in following way

  CreatedByBp: {
     editFactory: // bind method name which returns checkBox control factroy which                                          // will be rendered in edit mode,

     displayFactory: // bind method name which returns checkBox control factroy                                                 //  which will be rendered in display mode


Control Events

changeFieldValue – The event is fired when value in any form field control is changed

Visibility: public 

Param Type Description
oControlEvent sap.ui.base.Event
getParameters object
event of the control which is fired by particular form fied
The name of an updated field
New field value
Name in the Entity type passed in the property entityTypeName

Now lets create a Sales Order App which is using this form control.

OData project created for this example
                                                            Soheaderdata Entity

Fields to be shown in the control is determined by the properties defined in the Entity(here Soheaderdata). Please note that properties shown in Figure 1 & 2 are same as defined in the Entity.

Value defined in the label section of the entity is used as Label of form field.

Code to fetch data

Download source code of the Form Control 

Source Code Snippet for Sales Order App

<mvc:View controllerName="" 
	<App id="idAppControl">
			<Page title="Custom Form Sample">
					<c:Form id="idSalesOrderDetails" 
								  title="Sales Order Details" 
								  dataPath="/data" />
							<Button text="Save" visible="{=${FormDataModel>/displayMode} !== 'D'}" press="onSalesOrderSave" />
							<Button text="Edit" visible="{=${FormDataModel>/displayMode} === 'D'}" press="onSalesOrderEdit" />
							<Button text="Display" visible="{=${FormDataModel>/displayMode} !== 'D'}" press="onSalesOrderDisplay"/>
Control declaration

], function (Controller, JSONModel, MessageToast) {
	"use strict";
	return Controller.extend("", {
		onInit: function () {
			var oJsonModel = new JSONModel({
				data: {},
				displayMode: "D"
			this.getView().setModel(oJsonModel, "FormDataModel");
			var oDataModel = this.getOwnerComponent().getModel();
			var sPath = "/SoheaderdataSet('500000000')";, {
				success: this._onSalesOrderReadSuccess.bind(this),
				error: this._onSalesOrderReadFail.bind(this)
		onSalesOrderEdit: function () {
			this.getView().getModel("FormDataModel").setProperty("/displayMode", "E");
		onSalesOrderDisplay: function () {
			this.getView().getModel("FormDataModel").setProperty("/displayMode", "D");
		onSalesOrderSave: function(){
		_onSalesOrderReadSuccess: function (oResponse) {
			this.getView().getModel("FormDataModel").setProperty("/data", oResponse);
		_onSalesOrderReadFail: function () {"Error in Reading Sales Order Details");

Note:- In the above code snippet refresh method defined in the control needs to be called on change of the mode of the screen.

As you can see in the above code snippet, with such a minimal code we have rendered a full fledged form control which differentiate it with Smart Form Control.

Download source code of the example used in this blog  from this git repo

Note:- This control renders TypeAhead, SingleSelect ValueHelp, MultiSelect ValueHelp controls(Custom) which I will be showcasing in the next blog .


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli

      Nice blog and the link is not working(maybe it's an internal SAP link). Could you please share the public repo?

      Author's profile photo Vaibhav Agarwal
      Vaibhav Agarwal
      Blog Post Author

      Mahesh, Project Git Links has been updated with public repo. Please try to download the code now

      Author's profile photo Pierre Dominique
      Pierre Dominique


      Your Git repository is on the internal SAP GitHub Enterprise so it cannot be accessed from the outside. If you want to share your code with the community, you should put it on



      Author's profile photo Vaibhav Agarwal
      Vaibhav Agarwal
      Blog Post Author

      Hi Pierre,

      Project Git Links  has been updated with details. Please try to download the code now.