Modify Master View of Fiori Purchase Requisition APp - sapui5

I am trying to modify the master view (S2.view.xml) of the Fiori Purchase Req Approval App. I need to add a footer to this view. I tried adding footer to the S2 view XML but it didnt work. So looked like the S2 controller, getHeaderFooter() needs modification. My questions
1) Is this a standard method? Why is it added to the controller
2) If I have to add footer, how do I add it to the Master view???
3) How do I suppress the method in case required?
Appreciate your help.
Thank you

1) Is this a standard method? Why is it added to the controller
You are supposed to override getHeaderFooterOptions in your controller.
2) If I have to add footer, how do I add it to the Master view???
The following code sample is to add two Buttons Test1 and Test2 to footer.
getHeaderFooterOptions : function() {
var oOptions = {
buttonList: [{
sI18nBtnTxt: "Test1",
onBtnPressed: function() {
}
}, {
sI18nBtnTxt: "Test2",
onBtnPressed: function(oEvent) {
}
}]
};
return oOptions;
},
For details about overriding getHeaderFooterOptions, see the documentation.
3) How do I suppress the method in case required?
You can't suppress the method.

Related

Passing Data Between Controllers While Navigating

I want to pass data between two controllers (in addition to routing parameters) and I would like to know the correct way to do this.
For example: when I navigate to pattern /order/{id}, I do this in the view controller:
this.getRouter().navTo("order", {
id: sOrderId
});
I want to pass additional JSON object which I don't want to be part of routing parameter.
What should I do in this case?
--edit
Wanted to add what I like to achieve with this
I want pass data from master to detail. Both master and detail page has individual routing patterns assigned. So user can land on master or detail directly. When they land on master - user can choose bunch of detail items, and navigate to first detail item, and from there navigate to other items he/she selected earlier on master. So what I want to pass is this selection from master controller to detail controller.
Note: If the intention is to pass selected keys from the main view to the detail view, see https://stackoverflow.com/a/48870579/5846045 instead.
Using a client-side model
Usually, data are stored separately in models instead of assigned to local variables and passing them around. Model data can be then shared with anything that can access the model (e.g. View for data binding).
Here is an example with a client-side model (JSONModel):
Create a JSONModel which is set on a parent ManagedObject. E.g. on the Component via manifest.json:
"sap.ui5": {
"models": {
"myModel": {
"type": "sap.ui.model.json.JSONModel"
}
}
}
In the controller A, set the object to pass before navigating:
const dataToPass = /*...*/
this.getOwnerComponent().getModel("myModel").setProperty("/data", dataToPass, null, true);
In the controller B, do something with the passed data. E.g. on patternMatched handler:
onInit: function() {
const orderRoute = this.getOwnerComponent().getRouter().getRoute("order");
orderRoute.attachPatternMatched(this.onPatternMatched, this);
},
onPatternMatched: function() {
/*Do something with:*/this.getOwnerComponent().getModel("myModel").getProperty("/data");
},
Using NavContainer(Child) events
There are several navigation-related events such as navigate,
BeforeHide, BeforeShow, etc. which contain both views - the source view (from) and the target view (to).
You can make use of the API data to pass the data.
Here is an example:
In the controller A:
onInit: function() {
this.getView().addEventDelegate({
onBeforeHide: function(event) {
const targetView = event.to;
const dataToPass = /*...*/
targetView.data("data", dataToPass);
}
}, this);
},
In the controller B:
onInit: function() {
this.getView().addEventDelegate({
onBeforeShow: function(event) {
/*Do something with:*/this.getView().data("data");
}
}, this);
},
See also the related documentation topic: Passing Data when Navigating
You can create a local model (usually a JSONModel) and set it to inside your app Component.
// inside Component.js
var model = new sap.ui.model.json.JSONModel({ foo: “bar”});
this.setModel(model);
Inside each controller you can use
var model = this.getOwnerComponent().getModel();
console.log(model.getProperty(“/foo”));

How to set ID of a XML-View in a component environment?

I want to access a view's controller from a custom module with some utility functions. Basically you can do this that way:
var oController = sap.ui.getCore().byId("__xmlview1").getController();
The problem is that the above coding will not work in a real environment because __xmlview1is dynamically created by the framework. So I tried to find a possibility to set the ID of the view during instantiation. The problem is - I could not find one:
Trying to give the view an ID in the view.xml file does not work:
<mvc:View
controllerName="dividendgrowthtools.view.dividendcompare"
id="testID"
xmlns="sap.m"
...
Trying to set the ID in the router configuration of the component does not work either:
...
name: "Dividend Compare",
viewId: "test",
pattern: "Dividend-Compare",
target: "dividendcompare"
...
The problem is that I do not have direct control over the instantiation of the XML view - the component respectively the router does it.
So, is there a solution for that problem? Or at least a save way to get the view ID by providing the name of the view?
You should have a look at the SAPUI5 EventBus.
I am pretty sure, you want to let the controller to do something with the dividentcompare view. With the SAPUI5 Eventbus, you can publish actions from one controller to another witout braking MVC patterns.
In your dividendcompare.controller.js:
onInit : function() {
var oEventBus = sap.ui.getCore().getEventBus();
oEventBus.subscribe("MyChannel", "doStuff", this.handleDoStuff, this);
[...]
},
handleDoStuff : function (oEvent) {
var oView = this.getView();
[...]
}
Now, in your anothercontroller.controller.js:
onTriggerDividendStuff : function (oEvent){
var oEventBus = sap.ui.getCore().getEventBus();
oEventBus.publish("MyChannel", "doStuff", { [optional Params] });
}
You are now able to get the view from the dividentcontroller in every case from every other controller of your app. You dont access the view directly, this would brake MVC patterns, but can pass options to its controller and do the handling there.

Hiding UI element from fragment.xml in standard App

I want to hide few UI elements from My Travel and Expense (Standard App). I have tried in different approaches but I am not able to achieve what i want. Here is my requirement:
In My Travel and Expense App (TRV_TE_CRE), I want to hide the following UI elements:
GenericClaim.fragment.xml - Button id="costAssignmentButton"
I have added the extension project for TRV_TE_CRE and tried as below:
In component.js I added the following statement to hide
customizing:
{
"sap.ui.viewModifications": {
"mytravelandexpense.view.GenericClaim": {
"costAssignmentButton": {
"visible": false
},
},
},
Result: not working
Extended the GenericClaim.controller.js:
I added the below code in hookmethod
this.byFragmentId("costAssignmentButton").setVisible(false);
Result : whole claim page is not loading
By using access key I have commented the UI code in GenericClaim.fragment.xml
Result : not getting hide
Instead of the fragment ID, you can access the element ID from the view. Add this method in your view controller.
onAfterRendering : function(){
var buttonToHide = this.getView().byId("costAssignmentButton");
buttonToHide.setVisible(false);
},

How to Implement Master Detail in Ionic Framework?

I am trying to use Ionic Framework to build a simple Master Detail List application. I can capture the tap event on the list item but how can I load the details view after that.
.controller('TasksController',function($scope){
$scope.tasks = [
{ title : "Collect Coins" },
{ title : "Eat Mushroom" },
{ title : "Find the princess" }
];
$scope.showTaskDetails = function() {
alert('show Task details');
}
});
In the showTaskDetails event. How can I load a different view like Details.html?
The Master Detail pattern is a very easy pattern to implement in Ionic, but you're going about it wrong. You want to set up the details as a separate view and route in your application.
I suggest reading my article on the topic.
http://mcgivery.com/ionic-master-detail-pattern/

Get passed data on next page after calling "to" from NavContainer

I am on my way building a Fiori like app using SAPUI5. I have successfully built the Master page, and on item click, I pass the context and navigate to Detail page.
The context path from Master page is something like /SUPPLIER("NAME"). The function in App.controoler.js is as follows:
handleListItemPress: function(evt) {
var context = evt.getSource().getBindingContext();
this.myNavContainer.to("Detail", context);
// ...
},
But I would like to know how I can access this context in the Detail page. I need this because I need to use $expand to build the URL and bind the items to a table.
There is an example in the UI5 Documentation on how to deal with this problem using an EventDelegate for the onBeforeShow function which is called by the framework automatically. I adapted it to your use case:
this.myNavContainer.to("Detail", context); // trigger navigation and hand over a data object
// and where the detail page is implemented:
myDetailPage.addEventDelegate({
onBeforeShow: function(evt) {
var context = evt.data.context;
}
});
The evt.data object contains all data you put in to(<pageId>, <data>). You could log it to the console to see the structure of the evt object.
Please refer the "shopping cart" example in SAP UI5 Demo Kit.
https://sapui5.hana.ondemand.com/sdk/test-resources/sap/m/demokit/cart/index.html?responderOn=true
Generally, in 'Component.js', the routes shall be configured for the different views.
And in the views, the route has to be listened to. Please see below.
In Component.js:
routes: [
{ pattern: "cart",
name: "cart",
view: "Cart",
targetAggregation: "masterPages"
}
]
And in Cart.controller.js, the route has to be listened. In this example, cart is a detail
onInit : function () {
this._router = sap.ui.core.UIComponent.getRouterFor(this);
this._router.attachRoutePatternMatched(this._routePatternMatched, this);
},
_routePatternMatched : function(oEvent) {
if (oEvent.getParameter("name") === "cart") {
//set selection of list back
var oEntryList = this.getView().byId("entryList");
oEntryList.removeSelections();
}
}
Hope this helps.