SAP Fiori: Back button in fragments - sapui5

I am working on a SAP Fiori app and I am stuck in this problem for about 2 weeks with no result. I have a "create" fragment which is attached to "Detail" view.
When I open the "create" fragment and want to go back to the main detail view, the back button doesn't work therefore I have to refresh the app.
I guess the back button doesn't work the same way between views & between fragments.
Here's my back button function :
cancel: function() {
var oHistory = sap.ui.core.routing.History.getInstance(),
sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
// The history contains a previous entry
history.go(-1);
}
},
Here when I display sPreviousHash, it's undefined. Why?

Where is the back button that you are referring to?
I would expect that the fragment is a dialog and therefore that there is no back button. A close button is needed which will result in the fragment being closed. Depending on the requirements, the back navigation could then be done from the controller where the fragment was created.
Fragments are a technique to reuse UI parts, but are not part of the MVC concept. You cannot navigate directly to/from a fragement and this has to be done using views. Therefore the history is not available in a fragment. The BROWSER back button will take you to the previous screen in the BROWSER history.

Controller of the view in which the fragment as a dialog is opened.
_initializeReviewDialog: function() { this._oReviewDialog = sap.ui.xmlfragment(this.getView().getId(), "ReviewDialog", this);
this.attachControl(this._oReviewDialog);
},
Event in View that triggers the dialog opening
onEditReviewPressed: function(oEvent) {
if (!this._oReviewDialog) {
this._initializeReviewDialog(); }
}
this._oReviewDialog.open();
},
onReviewDialogOKPressed: function(oEvent) {
this._oReviewDialog.close();
},
Add fragment as a Dependent, so that models and events from owning view/controller are know
attachControl: function(oControl) {
var sCompactCozyClass = this.getOwnerComponent().getContentDensityClass();
jQuery.sap.syncStyleClass(sCompactCozyClass, this.getView(), oControl);
this.getView().addDependent(oControl);
},
FragmentDefinition
<core:FragmentDefinition id="ReviewDialogFragment" xmlns="sap.m" xmlns:l="sap.ui.layout"
xmlns:core="sap.ui.core">
<Dialog id="reviewDialog" >
<content>
... </content>
<beginButton>
<Button id="btnOK" text="{i18n>xbut.ok}" press="onReviewDialogOKPressed"/>
</beginButton> </Dialog>
</core:FragmentDefinition>

Related

FlexibleColumnLayout on second view not working SAP UI5

I am building a view with hardcoded data. which comes from home screen to the next view which is supposed to be a split view screen.
I am using FlexibleColumnLayout and inside of it begin and end layout to call views from my view folder. I have been following this tutorial. and even then my split view is not expanding on click.
My aggregation looks like this (I am not sure if it is correct):
App -> (View1, FCLView)
FCLView -> (MasterVIew, DetailView)
FCLView:
<mvc:View displayBlock="true" height="100%" xmlns="sap.f" xmlns:mvc="sap.ui.core.mvc">
<FlexibleColumnLayout id="flexibleColumnLayout" backgroundDesign="Solid">
<beginColumnPages>
<mvc:XMLView id="beginView" viewName="Ui5.Ui.view.MasterView"/>
</beginColumnPages>
<midColumnPages>
<mvc:XMLView id="detailView" viewName="Ui5.Ui.view.DetailView"/>
</midColumnPages>
</FlexibleColumnLayout>
</mvc:View>
component.js
...
getHelper: function () {
var oFCL = this.getRootControl().byId('flexibleColumnLayout'),
oSettings = {
defaultTwoColumnLayoutType: sap.f.LayoutType.TwoColumnsMidExpanded,
initialColumnsCount: 2
};
return FlexibleColumnLayoutSemanticHelper.getInstanceFor(oFCL, oSettings);
}
MasterViewController
...
onListItemPress: function (oEvent) {
MessageToast.show("here");
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
var oFCL = this.oView.getParent().getParent();
oFCL.setLayout(fioriLibrary.LayoutType.TwoColumnsMidExpanded);
}
I am following this tutorial
The scenario is, I have my first fullscreen view (View1) in which there's a button and it will navigate to second view which is a split view. (table and on clicking a row, the detail view will expand).
I am new to SAP, any kind of help would be appreciated.
It is difficult to debug your code excerpts, because there are several other things that can go wrong. (e.g. did you configure the use the sap.f.router instead of the sap.m.router in the manifest?)
The easiest way to start with a FlexibleColumnLayout is to begin with the UI5 MasterDetail-Template
This can be downloaded from Github or easily created in the WebIDE with a few clicks (new Project from template -> select Master Detail Application)
You can read more about the Template in the Demokit

Getting the oData in the event handler of Fiori Launchpad header event

I would like to check for data changes when the user clicks on the back button in the Fiori Launchpad. I have the following code
onAfterRendering: function() {
sap.ui.getCore().byId("backBtn").attachPress(this, function(oEvent) {
oEvent.preventDefault();
});
}
Within the function I would like to access the oData and other variables of the main controller. However when I press the back button the "this" object is the header control's view.
How can get the view of the page content and also access the oData and other parameters of the controller associated to the content view.
In order to access the current context you have to call the event handler function within that specific context, so therefore a binding is needed on that function.
onAfterRendering: function() {
sap.ui.getCore().byId("backBtn").attachPress(this, function(oEvent) {
oEvent.preventDefault();
}.bind(this));
}
If usage of sap.m.Page is an option than navButtonPress builtin event can be used:
View.xml:
<mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc">
<Page navButtonPress="onNavBack">
...
Controller.js:
onNavBack: function(oControlEvent) {
var oController = this;
var oView = this.getView();
}
the event listener will be triggered every time the button is pressed in the Fiori Launchpad header.

Using SearchField Inside Popover Keeps on Emitting 'select' Event and Rerenders Popover

I am using a custom control for a popover like this:
sap.ui.define([
"sap/m/Popover"
], function(Popover) {
"use strict";
return Popover.extend("name of controle", {
init: function() {
Popover.prototype.init.apply(this, arguments);
this.oPopup.setAutoClose(false);
},
renderer : "sap.m.PopoverRenderer"
});
});
And I am using this popover custom control like this:
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:path="path to custom popover"
>
<path:CustomPopover
placement="Left"
contentHeight="80%"
contentWidth="25%"
>
<path:content>
<!-- xmlview that has search field in it -->
</path:conent>
</path:CustomPopover>
</core:FragmentDefinition>
Now, if I use this fragment to create Popover, then the select event keeps on emitting for that search field.
2017-02-15 09:53:47.456659 Event fired: 'select' on Element sap.m.SearchField#__field0 - sap.ui.core.UIArea
This popover works fine in chrome even after continuous emission of an event but in Internet Explorer, it keeps on rerendering, so not able to use it. How to fix this?

Ionic Tab not move to its position after back from single page

this is Ionic version 1 question:
i have 4 tabs, each of the tab have it's content, one of them have a list inside it...
so if we have a list inside 3rd tab, then we choose the list and go to single page with back button...
after i tab the back button, it back to 1st tab, not to 3rd tab...
it seems that it cannot remember the position by default, i have tried some workaround like this...
i set the tab just before it enter the previous page:
$scope.$on("$ionicView.beforeEnter", function (event, data) {
$ionicTabsDelegate.select($scope.maintabindex);
});
with this on-select on each tab:
<ion-tab title="Forum" icon-on="ion-tab-fa-headphones" icon-off="ion-tab-fa-headphones" on-select="tabSelected()" href="#/app/home">
and then i have this function:
$scope.tabSelected = function () {
$scope.maintabindex = $ionicTabsDelegate.selectedIndex();
};
the problem is, the on-select method executed after i back to the parent page (*with tab page), so it cannot working well, because $ionicTabsDelegate.selectedIndex() on-select always give 0 index after i back from the single page to the tabbed page
any idea?
The ionic go back button should work in those scenarios, be sure that the child's view route is using the same ui-view as the parent tab. If that is the case and it is still not working, it's better for you to override the backbutton on the childs view to go to the parent.
Like this:
<ion-nav-bar ng-controller="MyCtrl">
<ion-nav-back-button class="button-clear"
ng-click="myGoBack()">
<i class="ion-arrow-left-c"></i> Back
</ion-nav-back-button>
</ion-nav-bar>
function MyCtrl($scope, $ionicHistory) {
$scope.myGoBack = function() {
$ionicHistory.goBack();
};
}
You can even replace the myGoBack() function with $state.go('parent-tab-view')

No ionic back button visable following view change via $state.go ionic

I have 2 views as follows
.state('tab.matches', {
url: '/matches',
views: {
'tab-matches': {
templateUrl: 'templates/bant-tab-matches.html',
controller: 'MatchesCtrl'
}
}
})
.state('tab.matches-detail', {
url: '/matches/:matchId/:userId/:userName',
views: {
'tab-matches': {
templateUrl: 'templates/bant-tab-matches-detail.html',
controller: 'MatchesDetailCtrl'
}
}
})
I have a button on a different view which on click calls a function in the controller as follows:
$scope.messageUser = function (postInfo) {
$state.go('tab.matches-detail', { matchId: var1, userId: var2, userName: var3 });
}
This redirects to the tab.matches-detail view as expected but a back button is not present. I would like the back button to redirect back to the parent view being tab.matches, or the view I originally redirected from. If I navigate from tab.matches to tab.matches-detail (when I have not redirected by $state.go) the back button is present. I however am going direct to tab.matches-detail when $state.go is called. As such I can no longer access tab.matches as if I click on another tab and then return to tab.matches it displays tab.matches-detail with no way to access the parent state of tab.matches. I can't figure out how to get the back button to display. I need this to be controlled from the controller rather than a href in the view as I need to call similar functionality from an Actionsheet where the logic is all controller side.
Apologies for the rather verbose explanation but I want to be clear on the issue.
Thanks in advance for your help.
Anthony
To resolve this issue I set the back button in the view as not visible by setting hide-back-button="true" in the <ion-view> tag, then added a button for the header as follows:
<ion-nav-buttons side="left" class="button-clear customButton">
<div class = "buttonMatchesInner" ng-click="matchesGoBack()">
<i class="ion-chevron-left matchLeftIcon"></i>
</div>
</ion-nav-buttons>
With the click event calling:
$scope.matchesGoBack = function() {
$state.go('tab.matches');
}