onInit: function () {
this._oModel = this.getOwnerComponent().getModel();
},
onButtonPress: function (oEvent) {
//get Data
var sPath = oEvent.getSource().getBindingContext().sPath;
var oData = this.getView().getModel().getObject(sPath);
var that = this;
//busy on
this._busyDialog = new sap.m.BusyDialog({});
this._busyDialog.open();
//create
this._oModel.create("/DataSet", oData, {
success: function (oData) {
that._busyDialog.close();
sap.m.MessageToast.show(that.getResourceBundle().getText("ok"));
},
error: function (oError) {
that._busyDialog.close();
sap.m.MessageToast.show(that.getResourceBundle().getText("nok"));
}
});
},
Category: Fiori / SAPUI5
[SAPUI5] MyInbox: Integration of Detail View – EmbedIntoDetail
https://launchpad.support.sap.com/#/notes/2305401 (App to App Navigation CookBook.pdf)
https://blogs.sap.com/2020/07/31/fiori-my-inbox-integration-of-custom-detail-page/
Target:
Go to /n/ui2/fpld_cust and define a second target for your App, i.e. approve.
The approve target needs the “emdedIntoDetails” parameter:
SWFVISU:
Add the new target for your WF Task. Here you have access to all attributes of your Workitem-Container. Pass all your mandatory fields you’ve defined in your oData Entity.
Some examples: https://blogs.sap.com/2016/05/31/my-inbox-open-task-swfvisu-configuration/
If your missing some parameters, just add them in your Workitem Task and pass the values directly into it right from your Workflow Container. This looks much better.
Manifest:
Add a route to navigate via Inbox. The pattern has to match your inbox url.
"routes": [
{
"pattern": "",
"name": "master",
"target": "master"
},
{
"pattern": "DataSet/{Pernr},{Datum},{Infty}",
"name": "object",
"target": [
"master",
"object"
]
},
{
"pattern": "detail/LOCAL_INBOX/{wfInstanceId}/{taskPath}",
"name": "wfobject",
"target": "object"
}
Detail.Controller:
onInit: function () {
// Model used to manipulate control states. The chosen values make sure,
// detail page is busy indication immediately so there is no break in
// between the busy indication for loading the view's meta data
var oViewModel = new JSONModel({
busy: false,
delay: 0
});
this.getRouter().getRoute("object").attachPatternMatched(this._onObjectMatched, this);
//My Inbox Integration
this.getRouter().getRoute("wfobject").attachPatternMatched(this._onWFObjectMatched, this);
this.setModel(oViewModel, "detailView");
this.getOwnerComponent().getModel().metadataLoaded().then(this._onMetadataLoaded.bind(this));
},
_onWFObjectMatched: function (oEvent) {
this.getModel("appView").setProperty("/layout", "MidColumnFullScreen");
var compData = this.getOwnerComponent().getComponentData();
if (compData && compData.startupParameters && compData.startupParameters.PERNR && Array.isArray(compData.startupParameters.PERNR) &&
compData.startupParameters.PERNR[0]) {
var sPernr = compData.startupParameters.PERNR[0];
var sDatum = compData.startupParameters.DATUM[0];
var sInfty = compData.startupParameters.INFTY[0];
this.byId("detailPage").addStyleClass("myInboxPage");
this.getModel().metadataLoaded().then(function () {
var sObjectPath = this.getModel().createKey("/DataSet", {
Pernr: sPernr,
Datum: sDatum,
Infty: sInfty
});
this._bindView(sObjectPath);
}.bind(this));
}
},
[SAPUI5] uncheck checkbox if another one is selected
XML
<Checkbox id="Checkbox1" selected="{ path:'oModel>CB1' }" select="handleOrderSelected"></Checkbox>
<Checkbox id="Checkbox2" selected="{ path:'oModel>CB2' }" select="handleRejectSelected"></Checkbox>
controller.js
handleOrderSelected: function (oEvent) {
//Wenn Checkbox1 selektiert, setze Checkbox2 auf false.
var bSelected = oEvent.getParameter("selected");
if (bSelected) {
var bindingContext = oEvent.getSource().getBindingContext("oModel");
this.oModelTemplate.setProperty("CB2", "", bindingContext, false);
}
},
handleRejectSelected: function (oEvent) {
//Wenn Checkbox2 selektiert, setze Checkbox1 auf false.
var bSelected = oEvent.getParameter("selected");
if (bSelected) {
var bindingContext = oEvent.getSource().getBindingContext("oModel");
this.oModelTemplate.setProperty("CB1", "", bindingContext, false);
}
}
[SAPUI5] Copy Table Row
Button für das Kopieren einer Zeile hinzufügen.
<Table id="itemsTable" items="{oModel>/ITEMS}">
<columns>
<Column id="splitColumn" hAlign="Center" demandPopin="false">
<Text text="{i18n>SPLIT}"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Button press="onSplitPressed" id="SPLIT_ROW" icon="{= ${oModel>CUSTOM_ITEM} === true ? 'sap-icon://delete' : 'sap-icon://add'}"/>
</cells>
</ColumnListItem>
</items>
</Table>
Nur neu hinzugefügte Zeilen sollen auch wieder gelöscht werden dürfen, daher werden manuell hinzugefügte Zeilen markiert mit CUSTOM_ITEM = True;
Via Expression Binding wird dann das erforderliche Icon bestimmt.
onSplitPressed: function (oEvent) {
var oContext = oEvent.getSource().getBindingContext("oModel");
var path = oContext.getPath();
var oModel = oContext.getModel();
var oItems = oModel.getProperty("/ITEMS");
var index = path.substr(path.length - 1);
//selektiertes Item lesen
var oItem = oModel.getProperty(path);
//was soll passieren? Zeile hinzufügen oder entfernen?
if (oItem.CUSTOM_ITEM !== true) {
//Neues Item anlegen
var oNewItem = JSON.parse(JSON.stringify(oItem));
//Markiere neue Zeile, da nur diese auch wieder gelöscht werden darf
oNewItem.CUSTOM_ITEM = true;
// +1 weil Zeile soll ja nach der Aktuellen einfügt werden
index++;
oItems.splice(index, 0, oNewItem);
} else {
// Item löschen
oItems.splice(index, 1);
}
oModel.setProperty("/ITEMS", oItems);
},
[Fiori] Debug deployed Fiori App
When opening the Dev-Tools for a deployed Fiori App, it will look like this:
You won’t see any controller.js to debug.
What to do? Close the Debugger-Tools and hit CTRL+ALT+SHIFT+P to open the Technical Information Dialog
Check the Checkbox (or choose a specific controller) and reload the app.
It reloads with a new URL parameter and if you open the Dev-Tools, you will now see the controller.js.
Other options to debug or at least to collect some information about your app are the UI5 Diagnostics (hit CTRL+ALT+SHIFT+S) and the UI5 Inspector which is a Brower Addon.
[SAPUI5] Formatting numbers
https://experience.sap.com/fiori-design-web/formatting-numbers/#usage
https://sapui5.netweaver.ondemand.com/sdk/#/topic/91f3145e6f4d1014b6dd926db0e91070
a few examples: https://github.com/brooklynb7/HTML5/blob/master/sapui5-dist-static/test-resources/sap/ca/ui/demokit/explored/views/type/number.view.xml
<ObjectListItem
title="{income>Month}"
number="{ model : 'income', path : 'Cost', type: 'sap.ui.model.type.Integer', formatOptions: {groupingEnabled: true} }"
numberUnit="EUR" />
[SAPUI5] Deploying the ui5 sample app on debian
I’m deploying the openui5-sample-app to a Linux Container running Debian Buster. First update the packages and install Node.js.
apt update && apt upgrade -y
apt install curl -y
curl -sL https://deb.nodesource.com/setup_12.x | bash -
apt install nodejs -y
nodejs --version
Install PM2 (process manager to manage Node.js applications) and the UI5 Tooling
npm install pm2 -g
npm install --global @ui5/cli
Now clone the openui5-sample-app and build it
apt install git
git clone https://github.com/SAP/openui5-sample-app.git
cd openui5-sample-app/
ui5 build -a
cd ..
Run your project on port 8000. With “startup” it will automatically create a systemd script.
pm2 serve openui5-sample-app/dist/ 8000
pm2 startup
pm2 save
systemctl start pm2-root
systemctl status pm2-root
[SAPUI5] local ui5 development
1. Install node.js
2. Install UI5 Tooling
npm install --global @ui5/cli
3. Install Easy UI5 Generator, create a project and run it on your localhost
npm install -g yo generator-easy-ui5
yo easy-ui5
cd <your project name>
npm start
4. Set up a Github project and do your initial push
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/user/myUI5App.git
git push origin master
5. Install your favorite Editor, e.g. Visual Studio Code or Atom, and open your project to edit it