Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigate to same Detail View with Animation in SplitApp

Tags:

sapui5

I'm using a Split App which has

  1. Master list
  2. 3 Detail Pages

MAster List shows a list of items ( here for example, bikes and cars list)

These are 3 detail pages:

  1. Message page: for not found/welcome page when nothing is clicked on master list.
  2. BikeProperties Page: which shows details if Bike is clicked.
  3. CarProperties Page: which shows if Car is clicked.

Now, the issue is when I click on Car Product, there is an animation shown which navigates from say welcome page to car page.

However, if I click again a car product, binding is updated with no animation.

Similarly, if I select a Bike at this point ( after selecting car), the navigation happens with animation.

So, to summarize,

  1. No animation is shown if same page is shown again in detail page.
  2. Animation is shown when different detail page is loaded.

However, what I want is , irrespective of which detail page is currently shown, the navigation should happen again with animation so consistency with animation is maintained.

Also, please note that I cannot use hash based routing as this split app needs to be displayed in a dialog box.

Below is the dummy code:

App.view.xml

<mvc:View controllerName="com.sap.SplitApp.controller.App" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" displayBlock="true"
xmlns="sap.m">
<Shell id="shell">
    <App>
        <SplitApp id="app">
            <masterPages>
                <Page>
                    <List items='{/items}' selectionChange="handleNavigate" mode='SingleSelectMaster'>
                        <items>
                            <StandardListItem title='{name}' info='{type}'/>
                        </items>
                    </List>
                </Page>
            </masterPages>
            <detailPages>
                <MessagePage title='Hello!' text='Select a Product'></MessagePage>
                <core:Fragment fragmentName="com.sap.SplitApp.fragments.BikeProperties" type="XML"/>
                <core:Fragment fragmentName="com.sap.SplitApp.fragments.CarProperties" type="XML"/>
            </detailPages>
        </SplitApp>
    </App>
</Shell>

App.controller.js

onInit: function () {
        var items = [
            {
                name: 'Thunderbird 500cc',
                type:'Bike'
            },
            {
                name: 'Swift',
                type:'Car'
            },
            {
                name: 'Bullet 350cc',
                type:'Bike'
            },
            {
                name: 'Polo',
                type:'Car'
            }
            ];
            var oModel = new sap.ui.model.json.JSONModel({ items: items});
            this.getView().setModel(oModel);
    },

    handleNavigate: function(oEvent) {
        var oBindingContext = oEvent.getParameter("listItem").getBindingContext();
        var oSplitApp = this.byId("app");
        var oDetailPage = null;
        if (oBindingContext.getProperty("type") === "Bike") {
            oDetailPage = this.byId('bikePage');
        } else {
            oDetailPage = this.byId('carPage');
        }
        oDetailPage.setBindingContext(oBindingContext)
         oSplitApp.toDetail(oDetailPage);
    }

BikeProperties.fragment.xml

<core:FragmentDefinition
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
xmlns:l="sap.ui.layout"
xmlns:f="sap.ui.layout.form"
xmlns:core="sap.ui.core"
>


<Page id='bikePage' title='Bike'>
        <Title text='{name}' />
    </Page>
</core:FragmentDefinition>

CarProperties.fragment.xml

<core:FragmentDefinition xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form"
xmlns:core="sap.ui.core">
<Page id='carPage' title='Car'>
    <Title text='{name}'/>
</Page>

like image 239
Rahul Bhardwaj Avatar asked Jul 18 '19 07:07

Rahul Bhardwaj


1 Answers

So since the API does not offer an obvious way to force an animaton, I looked at the source files. Your problem is probably from this line from NavContainer.js:

var oFromPage = this.getCurrentPage();
if (oFromPage && (oFromPage.getId() === pageId)) { // cannot navigate to the page that is already current
   Log.warning(this.toString() + ": Cannot navigate to page " + pageId + " because this is the current page.");
   return this;
}

As you can see from the comment, it is not intended to navigate/animate to the same page that is currently displayed.

One possible solution would be to use a second fragment for both car and bike and to navigate to car2 if you were to be on car1 previously, then to car2 again and so on. This is the best workaround I found.

The following are just some things I found and might be worth to take a further look at, but I couldn't get it to work properly.

I found another line in the source that could be used but there is a catch. The page title bar does not slide as expected. It gets invisible as you can see with this snippet added to your controller in the handleNavigate function:

var oFromPage = oSplitApp.getCurrentDetailPage();
if (oBindingContext.getProperty("type") === "Bike") {
    oDetailPage = this.byId("bikePage");
    if (oFromPage === oDetailPage) {
        sap.m.NavContainer.transitions.slide.to.call(this, this.byId("carPage"), this.byId("bikePage"), function callback() {});
    }
} else {
    oDetailPage = this.byId("carPage");
    if (oFromPage === oDetailPage) {
        sap.m.NavContainer.transitions.slide.to.call(this, this.byId("bikePage"), this.byId("carPage"), function callback() {});
    }
}

I also noticed that styleClasses are being used for proper transition. The fromPage gets some styles and the toPage too. But since in your case fromPage and toPage are the same, the styleClasses cannot be applied/removed as needed.

oToPage.addStyleClass("sapMNavItemSliding").addStyleClass("sapMNavItemCenter").removeStyleClass("sapMNavItemRight");
oFromPage.addStyleClass("sapMNavItemSliding").removeStyleClass("sapMNavItemCenter").addStyleClass("sapMNavItemLeft");

Using only the "oFromPrage-styleClasses" for your detailsPage results in some sort of "bouncing" from the left side. Using all, one after another, results in wrong navigation.

Maybe you can make some use of these information but as already said, using two car fragments and two bike fragments was the best solution (user-experience-wise) I found.

like image 79
Voyager Avatar answered Oct 07 '22 17:10

Voyager