How to disable or enable letterboxing and adjust UI5 for the widescreen?
Asked Answered
R

5

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");
        }
    });
});
Rosenthal answered 24/4, 2019 at 14:21 Comment(0)
C
15

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 its appWidthLimited property accordingly.

For example:

SAP Web IDE searching in project

In index.html or in a module assigned to data-sap-ui-on-init

sap.ui.require([
  "sap/m/Shell",
  "sap/ui/core/ComponentContainer",
], (Shell, ComponentContainer) => new Shell({
  appWidthLimited: false|true, // <-- default: 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 not required, consider removing sap.m.Shell entirely. There is no real purpose of sap.m.Shell if the application always runs with full width or embedded in FLP.

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


Apps on SAP Fiori launchpad (FLP)

The app or component …:

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

Statically in manifest.json

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

Documentation: Descriptor for Applications, Components, and Libraries

Dynamically at runtime

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

According to SAP Fiori design guidelines, switching the letterbox state during runtime is allowed:

Letterboxing can be switched on or off [...] for individual pages within an application. [...]

In some cases, applications may need to have the flexibility to change the width at runtime for different views. [...] Apps can change the width in the AppConfiguration service at runtime for different views.

* The API setApplicationFullWidth, however, is deprecated since UI5 1.120. If you really need switching the letterbox state during the application runtime, please create a new customer ticket at https://me.sap.com/getsupport with the component CA-FLP-FE-UI.

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


⚡ Limitations

Currently, the static fullWidth setting has no effect in:

  • FLP on Cloud Foundry in BTP (Deployed apps running in an iframe). SAP is still looking into it.
    ✅ FIXED since SAPUI5 1.120 (somewhere around 1.120.7)
  • Apps generated via SAP Fiori elements — by design.
Chibouk answered 14/5, 2019 at 19:44 Comment(3)
Perfect answer, thanks a lot for making distinction between the two scenarios !Exon
I am absolutely dumbfounded who this is STILL an issueLoriannlorianna
@Loriannlorianna The issue with the FLP on CF should be fixed by now. Could you try again?Chibouk
T
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)

Tableland answered 26/4, 2019 at 12:14 Comment(0)
G
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>
Goodman answered 26/4, 2019 at 16:40 Comment(5)
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.htmlRosenthal
OK, Can you post your index.html on your question?Goodman
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). CheersGoodman
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?Rosenthal
I’ll try to do an example. But I think my should be the accepted answer since you were able to remove the letterboxGoodman
R
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

Rosenthal answered 10/5, 2019 at 7:35 Comment(0)
K
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();
    }
}

Kalila answered 30/10, 2020 at 11:55 Comment(8)
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.Rosenthal
@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.Kalila
..and I also forgot the traversal through the dom tree.Kalila
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?Rosenthal
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 onAfterRenderingKalila
@MikeB. I changed my answer to use the onAfterRendering method.Kalila
You might have a sap.m.Shell somewhere in your project. Could you please check again? As mentioned in https://mcmap.net/q/1149190/-how-to-disable-or-enable-letterboxing-and-adjust-ui5-for-the-widescreen, the app should not contain a Shell and launch from FLP. Does at least setting fullWidth: true|false in manifest.json work?Chibouk
@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.Kalila

© 2022 - 2024 — McMap. All rights reserved.