softshipper
softshipper

Reputation: 34071

The scrollToSection method does not scroll

I have a ObjectPageLayout that is divided two sections, that it looks like:

<Page id="floatingFooterPage" enableScrolling="false" showNavButton="true" navButtonPress="onNavButtonPress">
    <content>
        <uxap:ObjectPageLayout id="ClassDetail" showHeaderContent="true">
            <uxap:headerTitle>
                <uxap:ObjectPageHeader></uxap:ObjectPageHeader>
            </uxap:headerTitle>
            <uxap:headerContent>
                <f:SimpleForm editable="false" layout="ResponsiveGridLayout" singleContainerFullSize="false">
                    <f:content>
                        <Label text="{i18n>charsClass}"/>
                        <Text text="{ClassInfo>/classNum} {ClassInfo>/classNumDescr}"/>
                        <Label text="{i18n>charsClassType}"/>
                        <Text text="{ClassInfo>/classType} {ClassInfo>/classTypeText}"/>
                    </f:content>
                </f:SimpleForm>
            </uxap:headerContent>
            <uxap:sections>
                <uxap:ObjectPageSection title="{i18n>charsCharsSel}" id="SecChars">
                    <uxap:subSections>
                        <uxap:ObjectPageSubSection >
                            <uxap:blocks>
                                <mvc:XMLView width="100%" viewName="ch.mindustrie.ZMM_OBJECTS_CLASSES.view.CharacSelection" id="CharacSelection"/>
                            </uxap:blocks>
                        </uxap:ObjectPageSubSection>
                    </uxap:subSections>
                </uxap:ObjectPageSection>
                <uxap:ObjectPageSection title="{i18n>charsObject}" id="SecObject">
                    <uxap:subSections>
                        <uxap:ObjectPageSubSection >
                            <uxap:blocks>
                                <mvc:XMLView width="100%" viewName="ch.mindustrie.ZMM_OBJECTS_CLASSES.view.ObjectTable" id="ObjectTable"/>
                            </uxap:blocks>
                        </uxap:ObjectPageSubSection>
                    </uxap:subSections>
                </uxap:ObjectPageSection>
                <!--    <uxap:ObjectPageSection title="Sub classes" id="SecSub" visible="false">
                    <uxap:subSections>
                        <uxap:ObjectPageSubSection >
                            <uxap:blocks>
                                <mvc:XMLView width="100%" viewName="ch.mindustrie.ZMM_OBJECTS_CLASSES.view.ClassTree" id="SubTree"/>
                            </uxap:blocks>
                        </uxap:ObjectPageSubSection>
                    </uxap:subSections>
                </uxap:ObjectPageSection>-->
            </uxap:sections>
        </uxap:ObjectPageLayout>
    </content>
    <footer>
        <Toolbar>
            <ToolbarSpacer/>
            <Button id="FindObject" text="{i18n>charsObject}" press="onPress" type="Transparent"/>
        </Toolbar>
    </footer>
</Page> 

I wanted to scroll to section SecChars programmatically and I have done as following:

_scrollToObjectSection: function () {
    const oObjPage = this.byId("ClassDetail");
    oObjPage.scrollToSection("SecObject", 0, 0);
}  

But it does not work at all. What am I doing wrong?

Upvotes: 1

Views: 1984

Answers (1)

Boghyon Hoffmann
Boghyon Hoffmann

Reputation: 18044

Issues

  1. The API scrollToSection awaits a global ID (the suffix "SecObject" alone is not enough). So it should be:

    oObjPage.scrollToSection(this.byId("SecObject").getId());
    
  2. That API, however, can be only successfully performed when the DOM of the ObjectPageLayout is fully ready. I added "fully" because calling scrollToSection within the onAfterRendering event delegate won't do anything either. There must be an additional timeout of about 450 ms. It's nowhere documented though how many milliseconds are actually required, and there is no public event for this case either.

Alternatives

  • Use setSelectedSection instead, as mentioned in the documentation topic Object Page Scrolling. The ObjectPageLayout will scroll to that section, but currently without any scrolling animation (iDuration = 0). The "selectedSection" is an association, hence, it can be also set within the view definition:

    <uxap:ObjectPageLayout selectedSection="mySection">
      <uxap:ObjectPageSection id="mySection">
    
  • Keep using scrollToSection but leverage the ⚠️ private event "onAfterRenderingDOMReady"(src) which is fired when the DOM is fully ready:

    onInit: function() {
      // ...
      this.scrollTo(this.byId("mySection"), this.byId("myObjectPageLayout"));
    },
    
    scrollTo: function(section, opl) {
      const id = section.getId();
      const ready = !!opl.getScrollingSectionId(); // DOM of opl is fully ready
      const fn = () => opl.scrollToSection(id);
      return ready ? fn() : opl.attachEventOnce("onAfterRenderingDOMReady", fn);
    },
    

    The API getScrollingSectionId() returns a falsy value (currently "") if the DOM is not fully ready.

Upvotes: 3

Related Questions