Search code examples
sapui5

Focus handling in ResponsivePopover / Dialog / Popover


I struggle to understand the automatic focus handling in SAPUI5 and how to change its default behavior:

Let's say I have a ResponsivePopover with a SearchField in it. When I open the popover, the SearchField gets focused automatically.

However when there is an <endButton> aggregation with a Button in it, it gets the focus instead.

Try it out here: JSbin: Focus in ResponsivePopover

function showPopover(oEvent) {
  var oRespPopover = new ResponsivePopover({
    showHeader: true,
    title: "title",
    content: [
      new SearchField(),
      // ...
    ],
    /*
    endButton: new sap.m.Button({
      text: 'close',
      press: function(oEvent) {
        oRespPopover.close();
      }
    }),
    */
    afterClose: function(oEvent) {
      oEvent.getSource().destroy();
    }
  });
  oRespPopover.openBy(oBtn);
};

General question

Where is defined which Control gets the focus and how can I change this behavior? I checked the Implementing Focus Handling documentation on this topic, but did not manage to achieve anything.

My specific case

How can I prevent that the SearchField gets the focus (because that triggers the keyboard on mobile devices), without having an EndButton aggregation?


Solution

  • If the target focus control has a stable ID, you can assign that ID to the initialFocus association of the sap.m.ResponsivePopover, sap.m.Dialog, or sap.m.Popover so that the target control gets focused even if there are buttons in the end/beginButton aggregation.

    Focus on the popover is set in the sequence of beginButton and endButton, when available. But if a control other than these two buttons needs to get the focus, set the initialFocus with the control which should be focused on. src

    In XML:

    <ResponsivePopover initialFocus="myFocusableControl"><!--Same for Dialog, Popover, ...-->
      <content>
        <SomeFocusableControl id="myFocusableControl" />
      </content>
    </ResponsivePopover>
    

    Or in JS (Controller):

    new ResponsivePopover({ // Same for Dialog, Popover, ...
      initialFocus: this.getView().createId("myFocusableControl"),
      content: [
        new SomeFocusableControl({
          id: this.getView().createId("myFocusableControl"),
        }),
      ],
      // ...
    });
    

    Note: For mobile devices, initial focus does not trigger opening the on-screen keyboard.

    Setting initialFocus to input controls doesn't open the On-Screen keyboard on mobile device as, due to browser limitation, the On-Screen keyboard can't be opened with JavaScript code. The opening of On-Screen keyboard must be triggered by real user action. src