9

I have an UI5-based app (1.66+), which works correctly, but there are huge empty spaces on the left and right sides of the screen (aka letterboxing is on):

Widescreen SAPUI5 app

I want to disable letterboxing to use the entire screen space.

I tried the following approaches so far:

  1. To use "fullWidth": true in sap.ui section of manifest.json
  2. To add desktop-related classes to the HTML-tag in index.html:
<html class="sap-desktop sapUiMedia-Std-Desktop sapUiMedia-StdExt-LargeDesktop">
  1. To add appWidthLimited: false to index.html:
<script>
    sap.ui.getCore().attachInit(function () {
        new sap.m.Shell({
            app: new sap.ui.core.ComponentContainer({
                height: "100%",
                name: "APPNAME"
            }),
            appWidthLimited: false
        }).placeAt("content");
    });
</script>

Just like it is described in «How to customise Shell container in SAPUI5».

But none of them works for me.

Update:
I succeeded to solve the issue via a static XML-template — just add <Shell id="shell" appWidthLimited="false"> to the main XML-template, but now I want to understand how to implement it via JS in new sap.m.Shell(…) definition.

The starting point for code experiments is below.

index.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>widescreen</title>
        <script id="sap-ui-bootstrap"
            src="../../resources/sap-ui-core.js"
            data-sap-ui-theme="sap_fiori_3"
            data-sap-ui-resourceroots='{"letterboxing.widescreen": "./"}'
            data-sap-ui-compatVersion="edge"
            data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
            data-sap-ui-async="true"
            data-sap-ui-frameOptions="trusted">
        </script>
    </head>
    <body class="sapUiBody">
        <div data-sap-ui-component data-name="letterboxing.widescreen" data-id="container" data-settings='{"id" : "widescreen"}' id="content"></div>
    </body>
</html>

Component.js:

sap.ui.define([
    "sap/ui/core/UIComponent",
    "sap/ui/Device",
    "letterboxing/widescreen/model/models"
], function (UIComponent, Device, models) {
    "use strict";

    return UIComponent.extend("letterboxing.widescreen.Component", {

        metadata: {
            manifest: "json"
        },

        init: function () {
            // call the base component's init function
            UIComponent.prototype.init.apply(this, arguments);

            // enable routing
            this.getRouter().initialize();

            // set the device model
            this.setModel(models.createDeviceModel(), "device");
        }
    });
});
Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
Mike
  • 14,010
  • 29
  • 101
  • 161

5 Answers5

14

Ok, so there seems to be many similar questions regarding how to disable/enable letterboxing. This answer should provide a solution for each case:

Standalone Apps

Look for the instantiation of sap.m.Shell in your project and configure appWidthLimited accordingly.

For example:

SAP Web IDE searching in project

In index.html or index.js

sap.ui.require([
  "sap/m/Shell",
  "sap/ui/core/ComponentContainer",
], (Shell, ComponentContainer) => new Shell({
  appWidthLimited: false|true, // <--
  // ...
}).placeAt("content"));

In root view

<Shell xmlns="sap.m" appWidthLimited="false|true">
  <App>
    <!-- ... -->

Of course, the Shell can be configured dynamically in JS too with myShell.setAppWidthLimited.

Note: if the letterboxing is never required, please reconsider whether <Shell> in your app is necessary at all. There is no purpose of sap.m.Shell if the app is displayed always in full width.

API reference: sap.m.Shell
UX guideline: Letterboxing


Apps on SAP Fiori launchpad (FLP)

The component / app …:

  • should not contain sap.m.Shell anywhere (please check the root view).
  • launches from FLP instead (no index.html).

Statically in manifest.json

"sap.ui": {
  "fullWidth": true|false,
  ...
}, 

Dynamically in runtime

// AppConfiguration required from "sap/ushell/services/AppConfiguration"
AppConfiguration.setApplicationFullWidth(true|false);

API reference: sap.ushell.services.AppConfiguration
UX guideline: Letterboxing


⚡ Limitations

Currently, the static setting "fullWidth": false is not supported by:

  • FLP on Cloud Foundry (deployed apps running in an iframe). SAP is looking into it.. The dynamic setting via sap/ushell/services/AppConfiguration can be used instead.
  • Apps generated via SAP Fiori elements - by design.
Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
1

According to Available OpenUI5 Versions the newest OpenUI5 version is 1.65.0. How is you app based on 1.66.0?

Setting appWidthLimited: false on the sap.m.Shell should do the work. Check out this example (plunker / github) (in the Plunker run preview in a new window)

Mike
  • 14,010
  • 29
  • 101
  • 161
piotr-koca
  • 94
  • 1
  • 5
0

You can achieve that removing the shell control from index.html:

sap.ui.getCore().attachInit(function () {
    sap.ui.require(["sap/ui/core/ComponentContainer"], function (ComponentContainer) {
        new ComponentContainer({
            name: "yourProject",
            async: true,
            manifest: true,
            height: "100%"

        }).placeAt("content");

    });
});

instead of this:

<script>
    sap.ui.getCore().attachInit(function () {
        new sap.m.Shell({
            app: new sap.ui.core.ComponentContainer({
                height: "100%",
                name: "APPNAME"
            }),
            appWidthLimited: false
        })
        .placeAt("content");
    });
</script>
Geraldo Megale
  • 363
  • 1
  • 10
  • Could you please, elaborate your answer? I don't really get what does it mean «instead of this». I don't have such code in my index.html – Mike May 10 '19 at 08:17
  • OK, Can you post your index.html on your question? – Geraldo Megale May 10 '19 at 11:37
  • Okay. On your question you said on step 3: "To add appWidthLimited: false to index.html" and then you pasted the script on your index.html. My sugestion is that you remove completely the object sap.m.Shell. Check the code you pasted. There is an object called sap.m.Shell. Remove this object (check my example again). Cheers – Geraldo Megale May 10 '19 at 18:41
  • I just replaced `sap.m.Shell` code in index.html with your code snippet, there is no left-right margins anymore, but now «Title» header is duplicated and there is a vertical scrolling. I wondered what is the reason for such behaviour? – Mike May 10 '19 at 22:15
  • I’ll try to do an example. But I think my should be the accepted answer since you were able to remove the letterbox – Geraldo Megale May 12 '19 at 01:06
0

Static implementation via XML-template:

<mvc:View controllerName="letterboxing.widescreen.controller.index" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
    <Shell id="shell" appWidthLimited="false">
        <App id="app">
            <pages>
                <Page id="page" title="{i18n>title}">
                    <content></content>
                </Page>
            </pages>
        </App>
    </Shell>
</mvc:View>

For dynamic implementation via JS-controller with appWidthLimited: false in sap.m.Shell, see: https://stackoverflow.com/a/55867413

Mike
  • 14,010
  • 29
  • 101
  • 161
0

For some reason, AppConfiguration.setApplicationFullWidth(true); does not work for me. I don't have a valid application container.

I solved the problem in this, admittedly hacky, way: In my app controller, I added this implementation of the onAfterRendering method:

onAfterRendering: function () {
    var oElement = this.getView().byId("idAppControl").$();
    while (oElement && oElement.hasClass) {
        if (oElement.hasClass("sapUShellApplicationContainerLimitedWidth")) {
            oElement.removeClass("sapUShellApplicationContainerLimitedWidth");
            break;
        }
        oElement = oElement.parent();
    }
}

daniel kullmann
  • 13,653
  • 8
  • 51
  • 67
  • 1
    I'm not sure if such approach is a safe-one from the performance point of view. I'm not so familiar with UI5's internals, but I would try to avoid `window.setTimeout` with `while (oElement && oElement.hasClass)` inside since it might trigger heavy and undesired DOM re-rendering by calling a `removeClass` in a loop. I would try to figure out what is the original reason for your issue. – Mike Oct 30 '20 at 12:02
  • 1
    @MikeB. The code is actually just doing (removing a style class) what the "official" approach via `AppConfiguration.setApplicationFullWidth(true);` does. Ah, and I forgot to add a `break`. – daniel kullmann Oct 30 '20 at 12:10
  • ..and I also forgot the traversal through the dom tree. – daniel kullmann Oct 30 '20 at 12:16
  • 1
    As far as I understand, `AppConfiguration.setApplicationFullWidth(true);` is executed once, at the app startup. The question how often `window.setTimeout` is executed? And is there any real need to use `window.setTimeout` here? – Mike Oct 30 '20 at 12:19
  • 1
    The App Controller is also created only once. I need to use window.timeout because the actual html is rendered after the code is executed. I could probably also put it into another method, like `onAfterRendering` – daniel kullmann Oct 30 '20 at 12:47
  • 1
    @MikeB. I changed my answer to use the `onAfterRendering` method. – daniel kullmann Oct 30 '20 at 12:54
  • 1
    You might have a `sap.m.Shell` somewhere in your project. Could you please check again? As mentioned in https://stackoverflow.com/a/56137602/5846045, the app should not contain a Shell and launch from FLP. Does at least setting `fullWidth: true|false` in `manifest.json` work? – Boghyon Hoffmann Oct 30 '20 at 14:13
  • @BoghyonHoffmann The app does not have a `sap.m.Shell`, so I can't set the fullWidth there. I think I tried using `fullWidth` in `manifest.json`, but that didn't help. – daniel kullmann Nov 06 '20 at 09:45