SAP Fiori – Consume OData Service, CSS, i18n properties in UI5 Application
Overview:
In this blog, we will see,
- How to apply custom CSS Styles in SAP UI5 application?
- How to work with multiple language scripts (i18n properties) ?
- How to consume an OData service in SAP UI5 Application?
Detailed steps to create a SAP UI5 application can be found in following link:
SAP UI5 Application project Structure:
- Our SAP UI5 application’s project structure is as follows:
- Note: here exampleProject is same as of above blog reference “Create a Fiori app using Eclipse“
Apply custom CSS Styles in SAP UI5 application:
- We can apply custom CSS styles in SAP-UI5 application
- For this we need to maintain “Styles.css” under ‘WebContent’ folder as shown below:
- Styles.css: for example lets create a custom style for button.
-
/* Button Style */ .customCss_ForButton{ background-color: red; font-style: italic; height: 2.850rem; border-style: solid; border-color: greenyellow; }
-
- To apply this style to control view, we need to following things:
- Give reference of ‘Styles.css’ file in ‘Component.js’
- Use following to apply it to view controls
- Syntax: class=”customCss_ForButton
- for e.g.: <Button text=”{i18n>PgMst_BtnTxt1}” press=”pressGetMaterial” type=”Accept” class=”customCss_ForButton”/>
- Testing:
- Before custom style
- After Custom style
i18n Perperties in SAP UI5 application:
- We can maintain multiple language scripts for Labels, Titles, Header texts, Messages etc in SAP-UI5 application using i18n property concept.
- Based on default browser language, respective script can get automatically selected in SAP-UI5 application.
- Suppose, we want to have two language script in my SAP-UI5 application
- Hindi
- English
- Then i18n property path will look like as below [WebContent -> i18n -> scriptFiles]:
- Where:
- Hindi Script
- i18n_hi.properties
-
#Title for 'Master' page | Hindi script PgMst_Title =\u092B\u093F\u092F\u094B\u0930\u0940 \u092A\u0930\u0940\u0915\u094D\u0937\u0923 \u0938\u0902\u0916\u094D\u092F\u093E \u090F\u0915 PgMst_BtnTxt1 =\u0938\u0948\u092E\u094D\u092A\u0932 \u0906\u0939\u094D\u0935\u093E\u0928 PgMst_BtnTxt2 =\u0938\u0930\u094D\u0935\u093F\u0938 \u0906\u0939\u094D\u0935\u093E\u0928 PgMst_BtnTxt3 =\u0905\u0917\u0932\u093E \u092A\u0947\u091C #Title for 'Details' page | Hindi script PgDtl_Title =\u0935\u093F\u0938\u094D\u0924\u0943\u0924 \u092A\u0943\u0937\u094D\u0920 PgDtl_Lbl1 =\u0935\u093F\u0938\u094D\u0924\u093E\u0930 \u092A\u0943\u0937\u094D\u0920 \u092E\u0947\u0902 \u0906\u092A\u0915\u093E \u0938\u094D\u0935\u093E\u0917\u0924 \u0939\u0948
- English Script
- i18n.properties : default script if no lang found
- i18n_en.properties : when app is been accessed in browser
- i18n_en-US.properties : when app is been accessed within Eclipse-PlatForm
- same details is present in all three files
-
#Title for 'Master' page | English script PgMst_Title =Fiori Example-1 PgMst_BtnTxt1 =ModelJson PgMst_BtnTxt2 =ODataSrv PgMst_BtnTxt3 =NextPage #Title for 'Details' page | English script PgDtl_Title =Detail Page PgDtl_Lbl1 =Welcome to Detail Page
- In i18n property scripts we define variable and assign languages specific values to them
- To access i18n properties, we need to load them in SAP-UI5 application
- Load i18n properties references in ‘Component.js’ file
- Look at ‘get_i18nProperties: function()‘ which gets i18n file references
- And in ‘createContent : function()‘, its been accessed.
- ‘Component.js’
-
var gv_i18nBundle; jQuery.sap.declare("ZTEST_APP.Component"); sap.ui.core.UIComponent.extend("ZTEST_APP.Component", { metadata : { stereotype : "component", "abstract" : true, version : "1.0", library : "ZTEST_APP", //required for CSS reference includes : [ "css/Styles.css" ], //CSS style reference dependencies: { //external dependencies libs : ["sap.m", "sap.ui.commons", "sap.ui.ux3", "sap.ui.table", "sap.ui.layout" ], //the libraries that component will be using library : "sap.ui.core", //what library belongs your component to }, }, createContent : function() { // get i18n.properties var lv_oBundle = this.get_i18nProperties(); /* Note: i18nModel needs to be called before root view 'sap.ui.view' i.e. before view creation so that bundle can be accessed at onInit() of Master Page */ gv_i18nBundle = jQuery.sap.resources({url : lv_oBundle.oData.bundleUrl}); // create root view var oView = sap.ui.view({ id : "app", viewName : "ZTEST_APP.view.App", type : "JS", viewData : { component : this } }); // set i18n.properties oView.setModel(lv_oBundle, "i18n"); // set device model var deviceModel = new sap.ui.model.json.JSONModel({ isPhone : jQuery.device.is.phone, listMode : (jQuery.device.is.phone) ? "None" : "SingleSelectMaster", listItemType: (jQuery.device.is.phone) ? "Active" : "Inactive" }); deviceModel.setDefaultBindingMode("OneWay"); oView.setModel(deviceModel, "device"); // done return oView; }, get_i18nProperties: function(){ /* Set i18n model | for Use of Localized Texts in Applications Language: On Eclipse PlateForm: lv_Locale = en-US If BrowserDefaultLang English: lv_Locale = en If BrowserDefaultLang Hindi: lv_Locale = hi */ // Get browser's language var lv_Locale = window.navigator.language; var lv_i18nPath; if(lv_Locale){ lv_i18nPath = "/i18n/i18n_" + lv_Locale + ".properties"; } //set default English script "i18n.properties" if(lv_Locale != "hi" || lv_Locale != "en" || lv_Locale != "en-US"){ lv_i18nPath = "/i18n/i18n.properties"; } var lv_bundleUrl = $.sap.getModulePath("ZTEST_APP", lv_i18nPath); var lv_oBundle = new sap.ui.model.resource.ResourceModel({ bundleUrl : lv_bundleUrl, //"./i18n/i18n_en.properties" }); return lv_oBundle; }, });
- The i18n defined variables will be accessed in views
- To refer variable of i18n properties, following syntax is been used:
- Syntax: “{i18n>varName}“
- For Example: “{i18n>PgMst_Title}“
- View ‘Master.view.xml‘
-
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="ZTEST_APP.view.Master" xmlns:html="http://www.w3.org/1999/xhtml"> <Page title="{i18n>PgMst_Title}"> <content> <Bar> <contentLeft> <Button text="{i18n>PgMst_BtnTxt1}" press="pressGetMaterial" type="Accept" class="customCss_ForButton"/> </contentLeft> <contentMiddle> <Button text="{i18n>PgMst_BtnTxt2}" press="pressODataSrv" type="Emphasized" /> </contentMiddle> <contentRight> <Button text="{i18n>PgMst_BtnTxt3}" press="pressNextPage" type="Emphasized" /> </contentRight> </Bar> <List id="idList1" mode="{device>/listMode}" items="{/listItems}"> <StandardListItem title="{MATNR}" /> </List> </content> <footer> <Bar> </Bar> </footer> </Page> </core:View>
-
- View ‘Details.view.xml‘
-
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="ZTEST_APP.view.Details" xmlns:html="http://www.w3.org/1999/xhtml"> <Page title="{i18n>PgDtl_Title}" showNavButton="true" navButtonPress="backPress"> <content> <Label text="{i18n>PgDtl_Lbl1}" design="Bold" /> </content> <footer> <Bar> </Bar> </footer> </Page> </core:View>
-
- To refer variable of i18n properties, following syntax is been used:
- Testing:
- English-Script: When browser’s default language is English ‘en’, then script ‘i18n_en.properties’ is been referred in application
- Hindi-Script: When browser’s default language is Hindi ‘en’, then script ‘i18n_hi.properties’ is been referred in application
Consume OData service in SAP UI5 Application:
- In SAP-Fiori, one OData Service is been created which consumes RFC of SAP-R3 (back end) system
- Detailed steps to create a OData service, can be referred from below links:
- OData Service url is as below, which returns Material details from RFC of SAP-R3, which we will consume in SAP UI5 application
- /sap/opu/odata/sap/ZTEST_ODATA_SRV/MaterialListSet
- To consume this OData Service in SAP UI5 application, in ‘Master‘ Page, we create a button, and on click event of this button, we call OData-Service:
- Button Name: ODataSrv
- Button Event Name: pressODataSrv
- View ‘Master.view.xml‘:
- Here we define button control and its properties
- see code screen from above in i18n section
- ‘connectivity.js’
- Here we define OData Service url
- File path: ‘WebContent > view -> utils -> connectivity.js’
- Code:
-
//OData Service URL: when testing APP in Eclipse local environment var serviceUrl = "proxy/http/fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/"; //OData Service URL: when testing app in SAP FIORI LAUNCHPAD //var serviceUrl = "/sap/opu/odata/sap/ZTEST_ODATA_SRV/";
- When we plan to deploy UI5 application in SAP-Fiori server, we need to comment url ‘proxy/http/fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/‘
- and un-comment url “/sap/opu/odata/sap/ZTEST_ODATA_SRV/”
- because application when accessed from Fiori-Launchpad, it takes host and port details from Launchpad itself.
- View ‘Master.controller.js’:
- Controller page, weher event is handled to call OData Service.
- 1st when page load, we call OData-Service with url path “/sap/opu/odata/sap/ZTEST_ODATA_SRV/” and set its model to page view
- 2nd one button click event “pressODataSrv”, consume OData-Service’s specifc EntitySet url path for fecthing RFC details:
- Url path: “/sap/opu/odata/sap/ZTEST_ODATA_SRV/MaterialListSet”
- See functions:
- onInit : function()
- pressODataSrv: function()
- Code:
-
jQuery.sap.require("ZTEST_APP.view.utils.connectivity"); jQuery.sap.require("sap.m.MessageBox"); sap.ui.controller("ZTEST_APP.view.Master", { onInit : function() { //Load OData Service var oModel = new sap.ui.model.odata.ODataModel(serviceUrl, true); sap.ui.getCore().setModel(oModel); }, pressODataSrv: function(){ //Get list control reference var list = this.getView().byId("idList1"); //Frame Url with EntitySet var url = serviceUrl + "MaterialListSet"; //Call OdataService OData.read(url, function(data) { //Read output var result = data.results; //set JSONoutput to a JSONModel var oModel = new sap.ui.model.json.JSONModel(); oModel.setData({ listItems : result }); //Set output to ListControl list.setModel(oModel); }, function(err) { var errTxt = err.message + "\n" + err.request.requestUri; sap.m.MessageBox.show(errTxt, sap.m.MessageBox.Icon.ERROR, "Service Error"); }); }, pressNextPage: function(evt) { var context = evt.getSource().getBindingContext(); this.nav.to("Details", context); }, pressGetMaterial : function(evt) { var sample = $.sap.getModulePath("ZTEST_APP", "/model/sampleData.json"); var oModel = new sap.ui.model.json.JSONModel(sample); //Set JSONModeloutput to ListControl var list = this.getView().byId("idList1"); list.setModel(oModel); }, });
- Testing:
- Click on button “ODataSrv”
- Debug Screen-1, here we can url input
- Debug Screen-2, here we can see returned output
- Post Call -> output items get filled up in List
- Thus we have consumed OData Service in SAP UI5 Application.
Hi Dilip,
Thanks for your post. It was very helpful. I have issue in my app. In your debug screen-2 screenshot, you demonstrated that the "result" variable has a array of output materials.
I am using SAPwebide in my case. when I run the app and debug I am unable to see the debugger stop inside the Odata.read service call. It seems to perform a asynchronous call. I had my abap debugger placed in the entity set call method and I get the debugger stopped.
Thats a confirmation that service call is going through well. However I am unable to catch the result and bind it. Can you please suggest me typical step done in order to see the output?
I think the calls are going as batch calls and I don't know how to know when the calls are completed.
Dear Ransome Mathias
Please refer below inputs in your case:
Thanks & Regards
Dilip
Hi Dilip,
Thank you so much for your inputs. Really really helpful inputs.
Hi Dilip,
I have another issue which i logged about a month ago. I haven't been able to solve it on my own. If you could please respond with your suggestions on inputs that will be amazing. Here is the link for the question.
https://answers.sap.com/questions/459192/unable-to-run-standard-app-from-local-webide-even.html
Dear Ransome Mathias,
You can try following link suggestions and let us know, if that solved your issue
https://archive.sap.com/discussions/thread/3937860
Suggestions are like:
If problem is only in WebIDE, then respective library may not be available in your WebIDE.
Thanks & Regards,
Dilip
Hi Dilip, Thanks for the suggestion. Unfortunately that didn't work. Here is the strange observation.
I downloaded the standard app using the projec extension method to my SAPwebid, then the app works well. Right after i download the app and then see the project folder i see the index file automatically created. I can run the app from that and I don't see any issue.
But when i just do a normal download of the SAP app to web ide, I don't see the index file in the project. So I manually created it. I am sure about the index file is pretty fine. But somehow the app does not seem to start. I am not having any answers in the thead I created. 🙁
Dear Ransome Mathias
Have you tried all syntax of working index file with your erroneous project one ?
MeanWhile I’ll check same, to download sap app in WebIDE.
We are having practice to download/upload fiori-app to/from Eclipse, and there was no such issue with index file.
Thanks & Regards,
Dilip
Please see the index file. I think the code in the file is looks good. But i doesnt seem to lauch the app when i download just the app. when I import as an extension, webide creates a index file on its own and i am able to run the same app from the webide as an extension app without done any changes.
Dear Ransome Mathias
In your index.html, try something like below: (specially check on src and ComponentContainer)
I tried a couple of modification based on your index.html file
It didnt seem to work. Please try to download the Pruchase order create app or other standard app on your webide and see i you are able to run it standalone from your system.
I am using sapwebide personal edition.
Thanks for the detailed articles! They are really helpful.
I've got the problem that the default project template in eclipse looks completly different:
Do you have any suggestions?
Best Regards and thx again!!
Dear Former Member,
Thanks & Regards,
Dilip.
I went through your posts many times and am successfully able to create a custom app. Thanks a lot for you detail post. it was very helpful.
Swati...nice to know it....