Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
maxrupp
Explorer

Introduction


Fiori Elements are becoming increasingly popular. They provide a framework to generate SAPUI5 apps at runtime based on metadata annotations.

Instead of generating a whole application, developers can also use Smart Controls for their existing apps, to add tables, forms, etc. in a fast way. These controls use annotations that add semantics and structures to the data, provided by the user.

In this example I want to illustrate the field control annotation in order to change the state of certain input fields dynamically.

The first screen of our demo app shows a table (SmartTable) with a list of customers. By selecting a customer, there will be a navigation to the detail page, where customer data can be edited in a form (SmartForm).

Annotations and Smart Controls


The Entity-Type Customer within our metadata.xml file comes with an Id and a Customername.
<EntityType Name="Customer" sap:content-version="1">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.String" Nullable="false" MaxLength="10" sap:label="Customer ID" sap:creatable="false" sap:updatable="false"/>
<Property Name="Customername" Type="Edm.String" Nullable="false" MaxLength="40" sap:label="Customer" sap:creatable="true" sap:updatable="true"/>
</EntityType>

We use SmartFields for displaying the values. This control can be used as standalone, for example in XML views:
<smartField:SmartField value="{Id}" id="id"/>
<smartField:SmartField value="{Customername}" id="customer"/>

...in combination with a SmartTable (our first screen):
<smartTable:SmartTable id="smartTable" entitySet="Customers"
initiallyVisibleFields="Id,Customername"
customData:useSmartField="true">
...
</smartTable:SmartTable>



...or with a SmartForm (our detail page):
<smartForm:SmartForm id="smartForm" entityType="Customer">
<smartForm:Group label="Customer Details" id="detailGroup">
<smartForm:GroupElement id="idGroupElement">
<smartField:SmartField value="{Id}" id="id"/>
</smartForm:GroupElement>
<smartForm:GroupElement id="customerGroupElement">
<smartField:SmartField value="{Customername}" id="customer"/>
</smartForm:GroupElement>
</smartForm:Group>
...
</smartForm:SmartForm>



If the SmartForm or SmartTable control is in "editmode", Id is still readonly, whereas Customername can be edited, due to the appropriate annotation within metadata.xml file ( sap:creatable="true" sap:updatable="true").

Dynamic Field Control


So far, so easy!

However... as these annotations are static, in certain cases it might be necessary to provide a dynamic functionality for some fields.

For example: Some customers should have a Street and a City field as well. For others, these two values should even be updatable. It is impossible to express this up-front via metadata annotations.

In that case, the annotation sap:field-control can help!

We adjust the metadata.xml:
<EntityType Name="Customer" sap:content-version="1">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.String" Nullable="false" MaxLength="10" sap:label="Customer ID" sap:creatable="false" sap:updatable="false"/>
<Property Name="Customername" Type="Edm.String" Nullable="false" MaxLength="40" sap:label="Customer" sap:creatable="true" sap:updatable="true"/>
<Property Name="Street" Type="Edm.String" Nullable="true" MaxLength="30" sap:label="Street" sap:field-control="UX_FC_Address"/>
<Property Name="City" Type="Edm.String" Nullable="true" MaxLength="30" sap:label="City" sap:field-control="UX_FC_Address"/>
<Property Name="UX_FC_Address" Type="Byte"/>
</EntityType>

We've added a new property UX_FC_Adress to the Entitytype Customer. Furthermore, we need the properties Street and City. Each of them has an additional Attribute: sap:field-control="UX_FC_Address".

<Property Name="Street" Type="Edm.String" Nullable="true" MaxLength="30" sap:label="Street" sap:field-control="UX_FC_Address"/>

<Property Name="City" Type="Edm.String" Nullable="true" MaxLength="30" sap:label="City" sap:field-control="UX_FC_Address"/>

The value of the UX_FC_Adress property defines, if these new fields are hidden(value = 0), read-only(value = 1), optional(value = 3) or mandatory(value = 7).

Within our backend there should be an appropriate logic, to set the value of UX_FC_Address for each customer. As our application is running with mockdata, we are using the following json-file to illustrate the different data for each Customer:
[
{"Id": "1", "Customername": "CustomerA", "Street": "StreetA", "City": "CityA", "UX_FC_Address": 0 },
{"Id": "2", "Customername": "CustomerB", "Street": "StreetB", "City": "CityB", "UX_FC_Address": 1 },
{"Id": "3", "Customername": "CustomerC", "Street": "StreetC", "City": "CityC", "UX_FC_Address": 3 },
{"Id": "4", "Customername": "CustomerD", "Street": "StreetD", "City": "CityD", "UX_FC_Address": 7 }
]

In the last step we have to add our new fields to our SmartForm:
<smartForm:Group label="Customer Details" id="detailGroup">
<smartForm:GroupElement id="idGroupElement">
<smartField:SmartField value="{Id}" id="id"/>
</smartForm:GroupElement>
<smartForm:GroupElement id="customerGroupElement">
<smartField:SmartField value="{Customername}" id="customer"/>
</smartForm:GroupElement>
</smartForm:Group>
<smartForm:Group label="Address" id="addressGroup">
<smartForm:GroupElement id="streetGroupElement">
<smartField:SmartField value="{Street}" id="street"/>
</smartForm:GroupElement>
<smartForm:GroupElement id="cityGroupElement">
<smartField:SmartField value="{City}" id="city"/>
</smartForm:GroupElement>
</smartForm:Group>

By running the application, we can see that CustomerB, CustomerC and CustomerD have additional values Street and City. However, these values are invisible for CustomerA.



Our SmartForm behaves also different, based on the selected Customer: For CustomerB, only the Customername is editable:



...for CustomerD the values Street and City are shown as mandatory input fields in our form:


Conclusion


Using the field-control Annotation is an easy way to dynamically change the behavior of the UI without additional UI5 coding. The SmartControl is a wrapper for other controls. It interprets OData metadata to determine the control that has to be instantiated. The OData entity is derived from the control's binding context.
9 Comments