Skip to Content
Technical Articles

XML View Template – Make your UI Dynamic

XML Template is an existing concept in OpernUI5/SAPUI5 that allows us to create View/Fragments as templates to create the UI dynamically.

 

Importance of using the XML Template

  • The Concept is used when we want to make UI screen Dynamic.
  • We can make use of annotations that are coming with the OData service and create/hide any fields in UI or order them in the appropriate structure.
  • Templates are heavily used in FIORI elements to build UI dynamically using OData annotations.
  • Templates are often used in Product Development.
  • Most commonly used to display form fields or to display dynamic content in any drop-down menu.
  • We can create a single template by understanding common business use cases for a product/project so that we can just configure the template according to the use case.

What is required to create XML Template

  • Annotations:  Annotations plays a key role in XML Template. Annotations are the place where we say what data to be displayed, what data to be hidden, and in which format the data can be visualized.
  • MetaModel: The MetaModel can be fetched from the OData model. Which directly points to the annotations. The piece of code represents how to fetch the MetaModel.

MetaModel

//Use promise to make sure the metadata loaded properly
this.getOwnerComponent().getModel().metadataLoaded().then(function() {
                    // Fetch OData model from the component
                    var oDataModel = this.getOwnerComponent().getModel();
                    // Fetching MetaModel from the OData model
                    var oMetaModel = oDataModel.getMetaModel();
});
  • MetaContext: MetaContext specifies a specific annotation path.

MetaContext

oMetaModel.getMetaContext("/Orders")
  • Pre-Processing Statements: Pre-Processing statements are used in to create the xml template.    XML Template will be an XML file similar to view or fragments. Pre-processing statements we can    use from <template:*> tag using          namespace xmlns:template=”http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1.
  • with: The <template: with> instruction can be used to change a variable’s value or to add a variable with a new name.

 

<template:with path="meta>com.sap.vocabularies.UI.v1.Badge" var="badge">
    <!-- ... -->
</template:with>

meta here points to the root of the annotations for the provided context path.

  • repeat : The <template:repeat instruction iterates the sap.ui.model.ListBinding given by the list attribute.
<!-- Example shows iterating of Identification annotations(vocabulary)  -->
<template:repeat list="{meta>com.sap.vocabularies.UI.v1.Identification}" var="field">
  <Label text="{path: 'field>Label', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}" />
  <Text text="{path: 'field>Value', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}" />
</template:repeat>
 
<!-- Example shows iterating of Identification annotations(vocabulary) using startIndex and length  -->
<template:repeat list="{path:'entityType>com.sap.vocabularies.UI.v1.Identification',startIndex:1,length:3}" var="field">
  <!-- ... -->
</template:repeat>

The example shows how to iterate the annotations also how the startIndex and length are used to add some restricting to the loop.

  • if: The <template: if> instruction evaluates a condition expressed via existing SAPUI5 data binding features, such as extended syntax; in the preprocessing it is removed or replaced by its child elements based on the value of this condition. You set the condition to the test attribute of the if instruction. It is recommended to use expression binding if you need to write logical expressions or convert values into Booleans. The test condition is treated as a property binding and the result is converted to the Boolean type according to the usual JavaScript rules, with the exception of the string “false”, which is converted to the Boolean false for convenience.
<template:if test="{meta>ImageUrl}">
  <template:then>
    <m:Image src="{path: 'meta>ImageUrl', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}" />
  </template:then>
  <template:elseif test="{meta>TypeImageUrl}">
    <commons:Image src="{path: 'meta>TypeImageUrl', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}" />
  </template:elseif>
  <template:else>
    <commons:Text text="{path: 'meta>Title/Value', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}" />
  </template:else>
</template:if>

In the above example, you can also write by using only if statement. The above example shows more elaborated use of if/then/eleif/else.

  • Based on your annotation structure you can write your template to design the respective screen and decide the extensibility of your Screen design.

Below Code shows the Annotation structure

<Annotations Target="com.test.XMLTemplate.Order">
				<Annotation Term="com.sap.vocabularies.UI.v1.FieldGroup" Qualifier="General">
					<Record Type="com.sap.vocabularies.UI.v1.FieldGroupType">
						<PropertyValue Property="Data">
							<Collection>
								<Record Type="UI.DataField">
									<PropertyValue Property="Value" Path="OrderId"/>
								</Record>
								<Record Type="UI.DataField">
									<PropertyValue Property="Value" Path="Price"/>
								</Record>
								<Record Type="UI.DataField">
									<PropertyValue Property="Value" Path="OrderDesc"/>
								</Record>
								<Record Type="UI.DataField">
									<PropertyValue Property="Value" Path="SupplierDesc"/>
								</Record>
							</Collection>
						</PropertyValue>
						<PropertyValue Property="Label" String="General"/>
					</Record>
				</Annotation>
			</Annotations>

 

Below code shows the view template with respect above Annotation structure

<mvc:View controllerName="com.test.XMLTemplate.controller.View1" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
	displayBlock="true" xmlns="sap.m" xmlns:smartForm="sap.ui.comp.smartform" xmlns:smartField="sap.ui.comp.smartfield"
	xmlns:template="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1">
	<App id="idAppControl">
		<pages>
			<Page title="{i18n>title}">
				<content>
					<!--aliasing the annotation helper-->
					<template:alias name=".AH" value="sap.ui.model.odata.AnnotationHelper">
						<template:with path="meta>com.sap.vocabularies.UI.v1.FieldGroup#General" var="fieldGroup">
							<template:if test="{meta>com.sap.vocabularies.UI.v1.FieldGroup#General}">
								<smartForm:SmartForm>
									<smartForm:layout>
										<smartForm:Layout labelSpanXL="3" labelSpanL="3" labelSpanM="3" labelSpanS="12" emptySpanXL="0" emptySpanL="0" emptySpanM="0" emptySpanS="0"
											columnsXL="1" columnsL="1" columnsM="1"></smartForm:Layout>
									</smartForm:layout>
									<smartForm:Group label="{path:'fieldGroup>Label',formatter:'.AH.format'}">
										<template:with path="fieldGroup>Data" var="data">
											<template:repeat list="{data>}">
												<smartForm:GroupElement>
													<smartField:SmartField value="{path:'data>Value',formatter:'.AH.simplePath'}"/>
												</smartForm:GroupElement>
											</template:repeat>
										</template:with>
									</smartForm:Group>
								</smartForm:SmartForm>
							</template:if>
						</template:with>
					</template:alias>
				</content>
			</Page>
		</pages>
	</App>
</mvc:View>
  • Annotation Helper: A collection of methods that help to consume OData Version 4.0 annotations in XML template views. The AnnotationHelper connects all the pieces related to XML templating: It knows the OData meta model and its structure as well as the OData v4 annotations. The AnnotationHelper offers formatter functions and helper functions. API spec can be found at https://sapui5.hana.ondemand.com/#/topic/dbec058964f545e4bb3b7e9fbaa0602d.

 

How to parse XML View Template into a View/Fragment

The XML Template in UI5 is created by using XML Preprocessor. The XML Template will be passed to XML preprocessor along with the metamodel and the metacontext. The XML preprocessor is used to create a view as well as fragments. Following code snippets will describe how to create a view and fragment out of XML Template.

// Code is written in onAfterRendering of controller of view where you want to use this template as a fragment. Code describing using template as fragment
// Output of this particular code will be UI5 Fragment
 
this.getOwnerComponent().getModel().metadataLoaded().then(function() {
                    var oDataModel = this.getOwnerComponent().getModel();
                    var oView = this.getView(); // This is the view in which the content will be pushed
                    var oMetaModel = oDataModel.getMetaModel();
                    //The content of page is preprocessed by XML View templating
                    var oFragment = XMLTemplateProcessor.loadTemplate("com.test.Demo.templates.Page", "fragment");
                    oMetaModel.loaded().then(function() {
                        var oProcessedFragment = XMLPreprocessor.process(oFragment, {
                            caller: "XML-Fragment-templating"
                        }, {
                            bindingContexts: {
                                meta: oMetaModel.getMetaContext("/Orders")
                            },
                            models: {
                                meta: oMetaModel
                            }
                        });
                        oFragment = sap.ui.xmlfragment({
                            fragmentContent: oProcessedFragment
                        }, this);
                        oView.getAggregation("content")[0].addContent(oFragment);
                        this.bFirstTime = true;
                    }.bind(this));
                }.bind(this));
 
 
 
// Code is written in component. Code describing Template as a view.
// Output of this particular code will be UI5 View
 
 
    /* pass the metacontext and metamodel to the preprocessor */
            oMetaModel.loaded().then(function () {
                var oTemplateView = sap.ui.view({
                    preprocessors: {
                        xml: {
                            bindingContexts: {
                                meta: oMetaModel.getMetaContext(sPath)
                            },
                            models: {
                                meta: oMetaModel
                            }
                        }
                    },
                    type: sap.ui.core.mvc.ViewType.XML,
                    viewName: "com.test.XMLTemplate.view.View1"
                });

The output of this snippet will be your actual view/Fragment.

 

The full example can be found in my git repo https://github.com/rahulinamdar/XML_Template

I hope this blog is helpful.

Be the first to leave a comment
You must be Logged on to comment or reply to a post.