I am not sure it is a basic or i am missing a point .
We're working with a multi-interface navigation in Appian (6 interfaces navigated via buttons). When a user clicks a button to go to the next interface, the interface loads correctly, but the page does not scroll to the top.
We do not want to use a process model with chaining to reload the form. We also tried using formLayout(focusOnFirstInput: true) but that didn’t help.
How can we make the form automatically scroll to the top on each interface load using only SAIL/interface logic?
Setup :headercontent layout hosts - header, contents {two interfaces}.interface1 have 2 columns , first column hosts navigation and other one hosts subinterfacesinterface 2 have buttons : Go Back , Save & Continue
How it works:On the first page (interface), the user fills out the details and scrolls down to click the "Save & Continue" button. When clicked, the navigation counter increments, and the user is taken to the next page(second interface)—but the view does not scroll back to the top.
Discussion posts and replies are publicly visible
It is not possible to make a form automatically scroll to the top when navigating between interfaces using only interface logic. When you dynamically switch content (whether using conditional logic, choose() functions, or calling different sub-interfaces), Appian's framework intentionally preserves the current scroll position to maintain user context. The only way to achieve automatic scroll-to-top is by using a process model with chaining (which reloads the form) or by navigating to separate Site pages.AFAIK, This is a fundamental limitation of Appian's client-side framework design, not a configuration issue that can be solved through interface logic alone.Workaround(If possible) : Keep form sections short enough to fit on one screen, so users naturally reach navigation buttons without scrolling. Use collapsible sections for optional fields and secondary content - this reduces form height while keeping everything accessible.
Yeah there is no way to control scroll behavior apart from making small or carcading interfaces! Also Generally when a form loads the cursor (and thereby scroll position) moves to the first editable field in the form. Does your second form has editable fields at bottom of page?
I covered this in my latest blog post: https://appian.rocks/2025/06/25/managing-scrolling/
a!localVariables( local!activeStep: 1, local!text, local!checkbox, local!paragraph, local!steps: {"Basic Info", "Additional Info", "Review"}, if( local!activeStep = 1, a!formLayout( formWidth: "MEDIUM", label: "Example: Onboarding Wizard", contents: { a!columnsLayout( columns: { a!columnLayout( contents: { a!milestoneField( label: "Wizzard", steps: { "Step 1", "Step 2" }, active: local!activeStep, color: "ACCENT" ) } ) }, marginBelow: "STANDARD", stackWhen: { "PHONE" }, showDividers: false ), a!sectionLayout( label: if( /* This logic hides the step name at the top of the form on PHONE widths since the step label is already displayed at the top when the screen is narrow */ a!isPageWidth(pageWidths: { "PHONE" }), "", /* This uses local!activeStep as the index of local!steps to display the name of the current step */ local!steps[local!activeStep] ), labelSize: "MEDIUM", labelColor: "STANDARD", contents: { a!textField( label: "Text Box Label", value: local!text, saveInto: local!text ), a!textField( label: "Text Box Label", value: local!text, saveInto: local!text ), a!textField( label: "Text Box Label", value: local!text, saveInto: local!text ), a!textField( label: "Text Box Label", value: local!text, saveInto: local!text ), a!paragraphField(value:local!paragraph,height: "TALL"), a!paragraphField(value:local!paragraph,height: "TALL"), a!paragraphField(value:local!paragraph,height: "TALL"), a!paragraphField(value:local!paragraph,height: "TALL") }, marginAbove: "STANDARD" ) }, buttons: a!buttonLayout( primaryButtons: { a!buttonWidget( label: "Next", value: local!activeStep + 1, saveInto: local!activeStep, style: "SOLID", showWhen: or(local!activeStep = { 1, 2 }), validate: true ), a!buttonWidget( label: "Onboard Employee", submit: true, style: "SOLID", showWhen: local!activeStep = 3 ) }, secondaryButtons: { a!buttonWidget( label: "Back", value: local!activeStep - 1, saveInto: local!activeStep, showWhen: or(local!activeStep = { 2, 3 }) ) } ) ), if( local!activeStep = 2, a!formLayout( formWidth: "MEDIUM", label: "Example: Onboarding Wizard", contents: { a!columnsLayout( columns: { a!columnLayout( contents: { a!milestoneField( label: "Wizzard", steps: { "Step 1", "Step 2" }, active: local!activeStep, color: "ACCENT" ) } ) }, marginBelow: "STANDARD", stackWhen: { "PHONE" } ), a!sectionLayout( label: if( /* This logic hides the step name at the top of the form on PHONE widths since the step label is already displayed at the top when the screen is narrow */ a!isPageWidth(pageWidths: { "PHONE" }), "", /* This uses local!activeStep as the index of local!steps to display the name of the current step */ local!steps[local!activeStep] ), labelSize: "MEDIUM", labelColor: "STANDARD", contents: { a!checkboxField( label: "CheckBox Label", choiceLabels: { "Yes", "No" }, choiceValues: { "Yes", "No" }, value: local!checkbox, saveInto: local!checkbox ), a!checkboxField( label: "CheckBox Label", choiceLabels: { "Yes", "No" }, choiceValues: { "Yes", "No" }, value: local!checkbox, saveInto: local!checkbox ), a!checkboxField( label: "CheckBox Label", choiceLabels: { "Yes", "No" }, choiceValues: { "Yes", "No" }, value: local!checkbox, saveInto: local!checkbox ), a!checkboxField( label: "CheckBox Label", choiceLabels: { "Yes", "No" }, choiceValues: { "Yes", "No" }, value: local!checkbox, saveInto: local!checkbox ), a!paragraphField(value:local!paragraph,height: "TALL"), a!paragraphField(value:local!paragraph,height: "TALL"), a!paragraphField(value:local!paragraph,height: "TALL"), a!paragraphField(value:local!paragraph,height: "TALL"), }, marginAbove: "STANDARD" ) }, buttons: a!buttonLayout( primaryButtons: { a!buttonWidget( label: "Next", value: local!activeStep + 1, saveInto: local!activeStep, style: "SOLID", showWhen: or(local!activeStep = { 1, 2 }), validate: true ), a!buttonWidget( label: "Onboard Employee", submit: true, style: "SOLID", showWhen: local!activeStep = 3 ) }, secondaryButtons: { a!buttonWidget( label: "Back", value: local!activeStep - 1, saveInto: local!activeStep, showWhen: or(local!activeStep = { 2, 3 }) ) } ) ), {} ) ) )
Insightful as always . Not sure why but it does not works (means not scroll to top) when you have more components (i may be doing something wrong) . PFA code.
I'm interested to see if automatic vertical scrolling to the top happens.Keep me posted
What Appian version is this? I did not test it with the all new formLayout.
In our review app, I use a paneLayout. Each section is a separate pane. Below some screenshots of the scrolling behaviour:
Scrolling down
Going to next section with scroll position on top
Thank you for replying, We are on 25.2 .