36
Views
4
Comments
Solved
What are the best practices for handling large forms with multiple tabs or sections ?

What are the best practices for handling large forms with multiple tabs or sections in OutSystems? Is there an efficient way to manage form state and validation across sections without overwhelming the user? 

2020-11-25 10-45-32
Mostafa Othman
Champion
Solution

Hello Pavan,

You can use wizard to build your large form and display controls into steps. This also will help you to validate controls of each wizard step before proceeding to next step.

https://success.outsystems.com/documentation/11/building_apps/user_interface/patterns/using_mobile_and_reactive_patterns/navigation/wizard/

You will need to build your business logic validation and you can use built in validation for controls like required or input data type

https://success.outsystems.com/documentation/11/building_apps/user_interface/forms/validate_the_fields_of_a_form/

You can also find some component in Forge that help you validate format and data of controls link input mask component and more 

https://www.outsystems.com/forge/component-overview/7838/input-mask-react-o11


2019-01-31 08-54-57
André Costa
Champion
Solution

Hi @Pavan Bodapati 

Everything depends on the client's requirements, but purely from a user perspective, implementing an autosave functionality can be a game-changer. 

Option 1:Setting it to trigger after each input is completed ensures that no data is lost, even if the user encounters a timeout, navigates away, or accidentally closes the tab. Given the volume of changes the user needs to make, autosave is an effective way to guarantee data integrity.

Option 2: For a solution with fewer server calls, you can implement a pattern with a save button within each form on each tab. This gives users control over when they save their progress while keeping server interactions to a minimum.

Option 3: My least favorite option is to have a general save button on the page to save all forms at once. Not only does this increase the risk of data loss as mentioned earlier, but it can also overwhelm the user by showing all validation errors at once during save. To help mitigate this, I’d suggest adding a visual element like an icon next to each tab or section name, indicating where and how many errors exist, making it easier for users to identify and correct issues 

AC

2026-02-23 14-14-27
Paolo Cordioli

Hi @André Costa ,

I like option number three, but how can I implement it by best managing the code flow? How can I structure the screen? 

Let me explain better: I would like to have the screen with the save button and the form composed of n blocks, at least one per section. In the screen I retrieve all the form data via an aggregate/data action, and then I pass as input to the blocks a structure only with the data they need. However, I don't know how to pass any block changes to the screen, because for example fields in different sections may depend on input fields entered by the user, and I also don't know how to apply input validations and make a single save.

I have seen that many people recommend using SystemEvent, , but I personally don't like the approach.


Do you happen to have any ideas or another solution? In case you also have an oml example you can share?

2019-01-31 08-54-57
André Costa
Champion

Hi Paolo, il ltry to explain as clear as I can with text:


1. Page Setup

  • Structure for Each Tab: Define a structure (TabN) in the Page Data:

    IsValidated: Boolean (True if validation is completed)
    IsValid: Boolean (True if data is valid)
    - IsSaved: Boolean (True if data is saved successfully)

  • Flags in the Page: Add two local variables to the Page:

    • IsValidating (Boolean): Controls the sequential validation process.
    • IsSaving (Boolean): Controls the sequential saving process.

2. Blocks for Each Tab

Each tab is a reusable block. Blocks encapsulate their validation and save logic.

Block Parameters:

  • Input:
    • IsValidating: Trigger for validation.
    • IsSaving: Trigger for saving.
  • Events:
    • Validation_Event: Outputs IsValid and the Tab Number.
    • Save_Event: Outputs the save result (IsSuccess) and the Tab Number.

Block Client Actions:

  • Validation Logic:
    • On parameter IsValidating change:
      • Check if IsValidating is True.
      • Execute validation logic in a Client Action.
  • Saving Logic:
    • On parameter IsSaving change:
      • Check if IsSaving is True.
      • Execute the save logic in a Client Action.

3. Validation Process (Page Level)

  1. On Save Button Click:

    • Set IsValidating to True to begin the sequential validation process.
    • This triggers the IsValidating parameter change for Tab 1's block.
  2. Catch Validation Events (Handler_Validation):

    • Use a Client Action on the Page to handle the Validation_Event.
    • The event passes:
      • IsValid: Validation result.
      • TabNumber: Which tab triggered the event.
    • Inside the handler:
      • Create a switch to validate TabNumber and direct to the respective tab flow
      • Update the respective tab structure: Tab1.IsValidated = True, Tab1.IsValid = IsValid handler input ).
      • If the current tab is validated (IsValidated = True), trigger the next tab by updating IsValidating.
  3. Validation Complete:

    • When all tabs are validated:
      • Set IsValidating to False.
      • Check if all tabs are valid:

        - If Tab1.IsValid & Tab2.IsValid & ... & TabN.IsValid, then trigger saving process by setting IsSaving = True
        - Else, highlight errors visually (e.g., icons on tab headers).

4. Saving Process (Page Level)

  1. On All Tabs Validated:

    • Set IsSaving to True.
    • This triggers the IsSaving parameter change for Tab 1's block.
  2. Catch Save Events (Handler_Save):

    • Use a Client Action on the Page to handle the Save_Event.
    • The event passes:
      • IsSaved: Save result.
      • TabNumber: Which tab triggered the event.
    • Inside the handler:
      • Create a switch to validate TabNumber and direct to the respective tab flow
      • Update the respective tab structure , Tab1.IsSaved = True
      • This will trigger the next tab's save process
  3. Save Complete:

    • After all tabs are saved:
      • Set IsSaving to False.
      • Display a success message.

5. Visual Error Indicators

Add a UI element (e.g., an icon) next to each tab name to indicate the validation/saving status:

  • Green checkmark: Valid (TabN.IsValidated = True & TabN.IsValid = True)
  • Red cross: Validation failed (TabN.IsValidated = True & TabN.IsValid = False) 


2020-11-25 10-45-32
Mostafa Othman
Champion
Solution

Hello Pavan,

You can use wizard to build your large form and display controls into steps. This also will help you to validate controls of each wizard step before proceeding to next step.

https://success.outsystems.com/documentation/11/building_apps/user_interface/patterns/using_mobile_and_reactive_patterns/navigation/wizard/

You will need to build your business logic validation and you can use built in validation for controls like required or input data type

https://success.outsystems.com/documentation/11/building_apps/user_interface/forms/validate_the_fields_of_a_form/

You can also find some component in Forge that help you validate format and data of controls link input mask component and more 

https://www.outsystems.com/forge/component-overview/7838/input-mask-react-o11


2019-01-31 08-54-57
André Costa
Champion
Solution

Hi @Pavan Bodapati 

Everything depends on the client's requirements, but purely from a user perspective, implementing an autosave functionality can be a game-changer. 

Option 1:Setting it to trigger after each input is completed ensures that no data is lost, even if the user encounters a timeout, navigates away, or accidentally closes the tab. Given the volume of changes the user needs to make, autosave is an effective way to guarantee data integrity.

Option 2: For a solution with fewer server calls, you can implement a pattern with a save button within each form on each tab. This gives users control over when they save their progress while keeping server interactions to a minimum.

Option 3: My least favorite option is to have a general save button on the page to save all forms at once. Not only does this increase the risk of data loss as mentioned earlier, but it can also overwhelm the user by showing all validation errors at once during save. To help mitigate this, I’d suggest adding a visual element like an icon next to each tab or section name, indicating where and how many errors exist, making it easier for users to identify and correct issues 

AC

2026-02-23 14-14-27
Paolo Cordioli

Hi @André Costa ,

I like option number three, but how can I implement it by best managing the code flow? How can I structure the screen? 

Let me explain better: I would like to have the screen with the save button and the form composed of n blocks, at least one per section. In the screen I retrieve all the form data via an aggregate/data action, and then I pass as input to the blocks a structure only with the data they need. However, I don't know how to pass any block changes to the screen, because for example fields in different sections may depend on input fields entered by the user, and I also don't know how to apply input validations and make a single save.

I have seen that many people recommend using SystemEvent, , but I personally don't like the approach.


Do you happen to have any ideas or another solution? In case you also have an oml example you can share?

2019-01-31 08-54-57
André Costa
Champion

Hi Paolo, il ltry to explain as clear as I can with text:


1. Page Setup

  • Structure for Each Tab: Define a structure (TabN) in the Page Data:

    IsValidated: Boolean (True if validation is completed)
    IsValid: Boolean (True if data is valid)
    - IsSaved: Boolean (True if data is saved successfully)

  • Flags in the Page: Add two local variables to the Page:

    • IsValidating (Boolean): Controls the sequential validation process.
    • IsSaving (Boolean): Controls the sequential saving process.

2. Blocks for Each Tab

Each tab is a reusable block. Blocks encapsulate their validation and save logic.

Block Parameters:

  • Input:
    • IsValidating: Trigger for validation.
    • IsSaving: Trigger for saving.
  • Events:
    • Validation_Event: Outputs IsValid and the Tab Number.
    • Save_Event: Outputs the save result (IsSuccess) and the Tab Number.

Block Client Actions:

  • Validation Logic:
    • On parameter IsValidating change:
      • Check if IsValidating is True.
      • Execute validation logic in a Client Action.
  • Saving Logic:
    • On parameter IsSaving change:
      • Check if IsSaving is True.
      • Execute the save logic in a Client Action.

3. Validation Process (Page Level)

  1. On Save Button Click:

    • Set IsValidating to True to begin the sequential validation process.
    • This triggers the IsValidating parameter change for Tab 1's block.
  2. Catch Validation Events (Handler_Validation):

    • Use a Client Action on the Page to handle the Validation_Event.
    • The event passes:
      • IsValid: Validation result.
      • TabNumber: Which tab triggered the event.
    • Inside the handler:
      • Create a switch to validate TabNumber and direct to the respective tab flow
      • Update the respective tab structure: Tab1.IsValidated = True, Tab1.IsValid = IsValid handler input ).
      • If the current tab is validated (IsValidated = True), trigger the next tab by updating IsValidating.
  3. Validation Complete:

    • When all tabs are validated:
      • Set IsValidating to False.
      • Check if all tabs are valid:

        - If Tab1.IsValid & Tab2.IsValid & ... & TabN.IsValid, then trigger saving process by setting IsSaving = True
        - Else, highlight errors visually (e.g., icons on tab headers).

4. Saving Process (Page Level)

  1. On All Tabs Validated:

    • Set IsSaving to True.
    • This triggers the IsSaving parameter change for Tab 1's block.
  2. Catch Save Events (Handler_Save):

    • Use a Client Action on the Page to handle the Save_Event.
    • The event passes:
      • IsSaved: Save result.
      • TabNumber: Which tab triggered the event.
    • Inside the handler:
      • Create a switch to validate TabNumber and direct to the respective tab flow
      • Update the respective tab structure , Tab1.IsSaved = True
      • This will trigger the next tab's save process
  3. Save Complete:

    • After all tabs are saved:
      • Set IsSaving to False.
      • Display a success message.

5. Visual Error Indicators

Add a UI element (e.g., an icon) next to each tab name to indicate the validation/saving status:

  • Green checkmark: Valid (TabN.IsValidated = True & TabN.IsValid = True)
  • Red cross: Validation failed (TabN.IsValidated = True & TabN.IsValid = False) 


Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.