In this practical case we will create an oData (Open Data Protocol) service from scratch and an Smart Table App in UI5 using a table from the sap.m. library.
The smart table creates a responsive table, grid table, tree table, or analytical table based on an OData (Open Data Protocol) service and its annotations. The table toolbar comes with additional built-in features, such as personalization, export to spreadsheet, and variant management.
Tools you need to be able to develop this application
- SAP Logon
- SAP Cloud Connector (SCC)
- SAP Cloud Platform (SCP) or SAP Business Technology Platform (BTP)
- SAP Web IDE or SAP BAS
In this application we are going to develop both the back-end and the front-end part
In the SEGW transaction we create a new project, give it the name "Z + our name" and choose the type "Service with SAP Annotations". (In this example we do not use Annotations, but the future may yes, if you do not create it of this type you will have to delete the oData and create it again since once created it does not let you change the type).
To create an Entity types we display our oData, right click, import and RFC / BOR Interface (In this case we are going to define our Entity types from an Export parameter of a function).
We give a name to the Entity type, we choose Target System Local (Since in our case we have the Front and the Back in the same machine, otherwise we would have to choose Remote and indicate our RFC Trusted).
We put the name of our function in which we have the export parameter to define our Entity
It displays all the parameters of our function, in this case we choose the table "ACTIVITYGROUPS" with all its fields (This table returns the ROLES of our user)
We display our Entity types and we can see that we care about the fields. There are types of data that it interprets as very restrictive Dates, decimals, amounts ... We must put these fields as Nullable since if the field is empty it throws an error.
To parameterize the filters and the ordering of the SmartTable records, the fields must be marked as Sortable and Filterable. Note: The FromDat and ToDat fields must have the Nullable property marked because otherwise when the call is made from the SmartTable it would give an error.
We generate our project from the button And it automatically generates the classes (We can change the name of the classes but it is not necessary)
We save the project in the package "Local Object" for this course.
We display the Runtime Artifacts folder that contains the classes of our oData, for this practical case we will only use the ZCL_XX_DPC_EXT class since it is the extension where we can redefine the methods of our Entity.
Inside our class we display the inherited methods and methods folder, here we will find the methods of our Entity with the following nomenclature:
- XX_GET_ENTITY -Returns us a single record.
- XX_GET_ENTITYSET -Returns us an internal table.
- XX_CREATE_ENTITY -Method to create a record.
- XX_UPDATE_ENTITY -Method to update a record.
- XX_DELETE_ENTITY -Method to Delete a record.
We look for the method we want to redefine, in our case XX_GET_ENITYSET since we are going to paint a table with several records.
Once the method is redefined, it will go to the Redefinitions folder, but it will leave the method empty with the input and output stops commented.
In our case, the parameter that we must fill will be ET_ENTITYSET which will return the call with information.
Inside the method we call the BAPI_USER_GET_DATAIL function which returns a table with the Roles of the executing user, to this function we pass the internal table Importing of our method so that the function returns it to us and we can process the data from UI5.
For error control we will use the Exception. /IWBEP/CX_MGW_BUSI_EXCEPTION
DATA: lt_return TYPE TABLE OF bapiret2.
CALL FUNCTION 'BAPI_USER_GET_DETAIL'
EXPORTING
username = sy-uname
TABLES
activitygroups = et_entityset
return = lt_return.
Finally we will register our service in SAP Gateway with the /n/IWFND/MAINT_SERVICE transaction. In my case the service is already registered, if your service is not registered we click on "Add Service".
We look for our service and click on it, then we add the service.
First we have to install Cloud connector and SAP JVM in our store, we can download them from. https://tools.hana.ondemand.com/#cloud
Once the two components are installed and registered in Hanatrial ondemand, we must access https://localhost:8443/ from the browser.
- User: Administrator
- Password: manage
Once inside we configure our user.
When our user is configured we go to the Cloud To On-Premise tab to configure the connection to our machine.
Finally we enter our SAP Cloud Platform to configure the connection to our SAP machine. https://account.hanatrial.ondemand.com/#/home/welcome
We go to the tab Connectivity -> Destinations, and add a new connection.
Before starting, we must have a user at https://account.hanatrial.ondemand.com/#/home/welcome to be able to enter SAP Web IDE.
We open our UI5 development environment in this case Webid, we right click on our Workspace, New and Project From Template.
We choose the SAPUI5 Application type, this will create a blank project but with the necessary structure for our App.
We give a name to our project "Z + our name" and we will put the same Namespace.
We choose the type of view that we are going to use, in this case XML, and we give our view / Controler a name.
Before starting to design the view of our application we have to configure the Manifest.json file where we define our oData service and our data model. To modify this file we can use 2 ways, Descriptor Editor (Graphical Interface) or Code Editor (Using Code), in this case I will use the graphical interface and I will put the code below.
In Service Catalog we look for our previously configured system, and then we look for our OData service.
In this example we select the default model and finish.
With Code Editor:
{
"_version": "1.12.0",
"sap.app": {
"id": "Z + our name.Z + our name",
"type": "application",
"i18n": "i18n/i18n.properties",
"applicationVersion": {
"version": "1.0.0"
},
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"sourceTemplate": {
"id": "servicecatalog.connectivityComponentForManifest",
"version": "0.0.0"
},
"dataSources": {
"Z + our name_SRV": {
"uri": "/sap/opu/odata/sap/Z + our name_SRV/",
"type": "OData",
"settings": {
"localUri": "localService/metadata.xml"
}
}
}
},
"sap.ui": {
"technology": "UI5",
"icons": {
"icon": "",
"favIcon": "",
"phone": "",
"phone@2": "",
"tablet": "",
"tablet@2": ""
},
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": true
}
},
"sap.ui5": {
"flexEnabled": false,
"rootView": {
"viewName": "Z + our name.Z + our name.view.View1",
"type": "XML",
"async": true,
"id": "View1"
},
"dependencies": {
"minUI5Version": "1.65.6",
"libs": {
"sap.ui.layout": {},
"sap.ui.core": {},
"sap.m": {}
}
},
"contentDensities": {
"compact": true,
"cozy": true
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "Z + our name.Z + our name.i18n.i18n"
}
},
"": {
"type": "sap.ui.model.odata.v2.ODataModel",
"settings": {
"defaultOperationMode": "Server",
"defaultBindingMode": "OneWay",
"defaultCountMode": "Request"
},
"dataSource": "Z + our name_SRV",
"preload": true
}
},
"resources": {
"css": [
{
"uri": "css/style.css"
}
]
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"async": true,
"viewPath": "Z + our name.Z + our name.view",
"controlAggregation": "pages",
"controlId": "app",
"clearControlAggregation": false
},
"routes": [
{
"name": "RouteView1",
"pattern": "RouteView1",
"target": [
"TargetView1"
]
}
],
"targets": {
"TargetView1": {
"viewType": "XML",
"transition": "slide",
"clearControlAggregation": false,
"viewId": "View1",
"viewName": "View1"
}
}
}
}
}
The first thing we do is import the libraries that we are going to use:
- sap.ui.core.mvc
- sap.m
- sap.ui.comp.smartfilterbar
- sap.ui.comp.smarttable
We define the smartTable tag with the following attributes:
- entitySet: We refer to the entity created in our oData.
- smartFilterId: It refers to the Id of our smartFilterBar
- tableType: Type of table that we want to show Help types
- showFullScreenButton: It shows us a button to see the table in full screen
- useExportExcel: It shows us a button to export the table in Excel
- demandPopin: Responsive mode on mobile devices.
- useVariantManagement: Generates variants for the layout of the fields.
- useTablePersonalization: Enable column customization.
- header: Name that appears in the Record Counter.
- showRowCount: Activate register counter.
- persistencyKey: Key name of our SmartTable.
- enableAutoBinding: Activate the call to our entity automatically.
It is not necessary to define the columns that are shown in the table since we will control it with the Annotations.
File View1.view.xml:
<mvc:View controllerName="ZGONZALOMB.ZGONZALOMB.controller.View1" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m"
xmlns:core="sap.ui.core" xmlns:smartFilterBar="sap.ui.comp.smartfilterbar" xmlns:smartTable="sap.ui.comp.smarttable"
xmlns:smartForm="sap.ui.comp.smartform" xmlns:smartField="sap.ui.comp.smartfield" xmlns:smartVariantManagement="sap.ui.comp.smartvariants"
xmlns:html="http://www.w3.org/1999/xhtml" xmlns:app="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1">
<Shell id="shell">
<App id="app">
<pages>
<Page id="page" title="{i18n>title}">
<content>
<smartFilterBar:SmartFilterBar
id="smartFilterBar"
entitySet="ActivitygroupsSet"
persistencyKey="SmartFilter_Explored"
considerAnalyticalParameters="true">
<smartFilterBar:layoutData>
<FlexItemData shrinkFactor="0"/>
</smartFilterBar:layoutData>
</smartFilterBar:SmartFilterBar>
<smartTable:SmartTable
id="LineItemsSmartTable"
entitySet="ActivitygroupsSet"
smartFilterId="smartFilterBar"
ableType="ResponsiveTable"
showFullScreenButton="true"
useExportToExcel="true"
beforeExport="onBeforeExport"
demandPopin="true"
useVariantManagement="true"
useTablePersonalisation="true"
header="Registros"
showRowCount="true"
persistencyKey="disposicion"
enableAutoBinding="true"
class="sapUiResponsiveContentPadding">
<smartTable:layoutData>
<FlexItemData growFactor="1" baseSize="0%"/>
</smartTable:layoutData>
</smartTable:SmartTable>
</content>
</Page>
</pages>
</App>
</Shell>
</mvc:View>
We create a folder with the name 'annotations' and within this we create the Annotations file, we leave the default name and select our oData service.
In our Annotations file we add a LineItem that governs the columns of our SmartTable and in our LineItem we add a DataField for each field that we want to show in a standard way in our table, referring in the value to the field of our entityset.
To add search aids to each field we select Select Targets.
We display our entity and select each of the fields that have search assistance.
Once the fields have been selected we have to add a list of values with the ValueList node, within this node we add our entityset in the CollectionPatch attribute that the search help will call and we also add the SearchSupported = true attribute.
In our ValueList we also add the Parameters node (It governs the columns that our search help shows), and we add the ValueListParameterInOut attribute by selecting our field, which will be the key field of our search aid and to finish if we want another column with a description field we add the ValueListParameterDisplay attribute with the description field of our entity.
To add a default filter to the SmartFilterBar, in our Entity Type inside Local Annotations we add a UI.SelectionFields and inside an Item where we will select the field that we want to show as a filter.
Code Editor anotation0.xml
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:Reference Uri="/sap/opu/odata/sap/ZGONZALOMB_SRV_01/$metadata">
<edmx:Include Alias="Metadata" Namespace="ZGONZALOMB_SRV_01"/>
</edmx:Reference>
<edmx:Reference Uri="https://wiki.scn.sap.com/wiki/download/attachments/448470968/UI.xml?api=v2">
<edmx:Include Alias="UI" Namespace="com.sap.vocabularies.UI.v1"/>
</edmx:Reference>
<edmx:Reference Uri="https://wiki.scn.sap.com/wiki/download/attachments/448470974/Common.xml?api=v2">
<edmx:Include Alias="Common" Namespace="com.sap.vocabularies.Common.v1"/>
</edmx:Reference>
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ZGONZALOMB.annotations.annotation0.ZGONZALOMB_SRV_01">
<Annotations Target="Metadata.Activitygroups">
<Annotation Term="UI.SelectionFields">
<Collection>
<PropertyPath>AgrName</PropertyPath>
</Collection>
</Annotation>
<Annotation Term="UI.LineItem">
<Collection>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="AgrName"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="FromDat"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="ToDat"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="AgrText"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="OrgFlag"/>
</Record>
</Collection>
</Annotation>
</Annotations>
<Annotations Target="Metadata.Activitygroups/AgrName">
<Annotation Term="Common.ValueList">
<Record Type="Common.ValueListType">
<PropertyValue Property="CollectionPath" String="ActivitygroupsSet"/>
<PropertyValue Property="SearchSupported" Bool="false"/>
<PropertyValue Property="Parameters">
<Collection>
<Record Type="Common.ValueListParameterInOut">
<PropertyValue Property="LocalDataProperty" PropertyPath="AgrName"/>
<PropertyValue Property="ValueListProperty" String="AgrName"/>
</Record>
<Record Type="Common.ValueListParameterDisplayOnly">
<PropertyValue Property="ValueListProperty" String="AgrText"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
This would be the result of our SmartTable UI5 App.
My.First.SmartTable.mp4
Back-end:
- ABAP
Gateway:
- oData
Front-End:
- UI5
- HTML
- CSS
- Gonzalo Meana - SAP Developer - GonzaloMB
- Tell others about this project 📢
- Invite someone on the team to have a beer 🍺 or a coffee ☕.
- Thanks for reading the project 🤓.
⌨️ whit ❤️ by GonzaloMB 😊