How is your experience with the OutSystems Community?
23
Views
3
Comments
Solved by AI
Global solution to tell if client is waiting for server

Hello all, 

I would like to implement a visual indicator to tell end users that the client is currently waiting for an answer from the server across all my applications.

My applications already uses a common theme and layout for their pages, so the solution I was considering was to add a container to that layout that shows up whenever there is a server action, controlled by a boolean variable. But that would require adding that logic to all of my applications.

I would like to ask if there is a solution that enables adding this behaviour to my applications with the least changes to the applications that are already created.

Thank you in advance for all the help. 

2021-01-01 09-23-30
Michael de Guzman
Champion
Solution

Hi Carlos,

You don’t need to change your server actions for this. I built a small O11 Reactive test app and attached it here.

In Reactive apps, every server call goes to a URL with /screenservices/ in it. A small script watches those calls. While a call is running, it shows a thin bar at the top of the page. It waits 300 ms first, so quick calls don’t make it flash. It also hides the bar if a call fails.

Where to look in the app:

  • BusyIndicatorTest_Th > Interface > Scripts > BusyIndicator is the script.
  • LayoutTopMenu > Required Scripts is where the script is added.
  • LayoutTopMenu > Style Sheet has the CSS for the bar.
  • BusyIndicatorTest is a normal app with no loading logic. The Home screen has a button for each test.

To use it, copy the script and the CSS to your shared layout module. Add the script to your layout’s Required Scripts. Then publish and republish your apps. Put the CSS on the layout, not the theme, so every app that uses the layout gets it.

You can also check these Forge components:

  • XHR Loading Overlay works the same way. You add one block to your layout and it shows a full-screen overlay for every XHR call.
  • XHRLoadingSpecific is based on the first one. It only shows the overlay for buttons with the trigger-loading class.

Mine only watches OutSystems server calls, and the bar doesn’t block the page. Use the one that suits your apps.

I hope this helps.

BusyIndicatorTest.oml
BusyIndicatorTest_Th.oml
2023-12-26 10-35-28
OutSystems Neo
Staff
AI Generated

You’re on the right track thinking at theme/layout level. In OutSystems 11 (Reactive/Traditional) there’s no built‑in “global AJAX wait” for all apps, but you can centralize the behavior enough that existing apps need only minimal changes.

Below are a few approaches, starting from “most global” to “per‑layout”.


1. Shared Library with a Reusable “Global Loader” Block

If all your apps already consume a common UI module (for theme/layout), the cleanest approach is:

  1. Create a UI library module (if you don’t already have one) – for example MyCompany.UI.
  2. Inside it, create a Block GlobalLoader that:
    • Contains the spinner/overlay UI (for example, an If with IsLoading and a container with an icon/spinner).
    • Exposes a public client action SetGlobalLoading(IsLoading: Boolean) that:
      • Sets a client variable (Scoped to App if using Reactive, or Session for Traditional).
      • Triggers a RefreshData or Ajax Refresh of the block so the spinner shows/hides.
  3. Include GlobalLoader in a Layout Block (e.g. LayoutDefault) inside the same module.

Then, for each application:

  1. Reference MyCompany.UI.
  2. Use MyCompany.UI.LayoutDefault as the layout (or use your existing layout extended with GlobalLoader).
  3. Wrap your server calls with the public action:
    Start
      → SetGlobalLoading(True)
      → <Your Server Action>
      → SetGlobalLoading(False)
    End
    
  4. Optionally, extract that pattern to a reusable wrapper client action (e.g. RunWithLoader) in the same library so you only call:
    • RunWithLoader(CallbackAction: YourServerAction).

This way, the visual and state logic is defined once; each screen only needs a couple of calls, not a full custom implementation.


2. Using Data Action / Aggregate IsDataFetch Properties (Reactive)

If most of your server calls are done via Data Actions/Aggregates in Reactive screens:

  1. In your shared layout, add the spinner container with:
    • Visible: some derived boolean like IsAnyDataFetching.
  2. Implement IsAnyDataFetching as the OR of multiple IsDataFetchExecuting flags from Data Actions/Aggregates.

For new screens, if you standardize names or patterns of Data Actions, you can:

  • Create a shared layout pattern that includes a placeholder region (e.g. a block placeholder).
  • Ask developers to drop their Data Actions in a way that the layout can access those flags through input parameters or a shared client variable.

This still requires some wiring per screen, but avoids duplicating UI for the spinner.


3. Common Theme + Custom JavaScript Hook (Traditional)

For Traditional Web apps (or if you are using some custom JS already):

  1. In your Theme (or Global Scripts), add JavaScript that hooks into AJAX events and toggles a CSS class on body:
    • On AJAX start → add .is-loading
    • On AJAX end → remove .is-loading
  2. In the same Theme, add CSS for that class (e.g. a full-screen overlay spinner).

This is closest to the legacy Feedback_AjaxWait pattern: any AJAX request from any screen using that Theme will automatically show the loader, with zero per‑screen changes.

Note: native hooks differ between Traditional and Reactive – for Reactive you’d rely on your own client actions, not the old AJAX events.


4. What You Can’t Avoid Entirely

There’s no single switch in O11 that automatically tracks all server calls across modules without any change:

  • For Reactive apps, server calls are usually explicit Client Actions/Data Actions; you still need a way to toggle IsLoading around them.
  • For Traditional apps you can get very close with JS hooks in the Theme, but that only catches AJAX calls initiated via platform patterns.

So the typical “minimal changes” strategy is:

  1. Centralize loader UI and state handling in a shared UI module (layout/block + public actions).
  2. Standardize a small pattern (e.g., always call RunWithLoader for long server actions).
  3. Gradually refactor existing apps to use this pattern when you touch them, instead of rewriting everything at once.

If you tell me whether your apps are mostly Reactive or Traditional, I can outline a concrete layout/block structure and a small example of the client actions needed for that specific stack.

This answer was AI-generated. Please read it carefully and use the forums for clarifications
2024-10-12 12-11-20
Kerollos Adel
Champion

Hallo @Carlos João Lopes Mendes

It's definitely a great idea to centralize this behavior in one place. However, from the application side, not all controls can be made common, and trying to do so may save time and effort in some cases, but it can also become complex.

A good middle-ground solution would be:

  1. Create a common Loading control.

  2. Add it to the main layout.

  3. Add a Boolean input parameter to the layout, for example, IsLoading.

  4. Set IsLoading to True when a Server Action starts.

  5. Set IsLoading back to False when the action finishes, whether it succeeds or fail

2021-01-01 09-23-30
Michael de Guzman
Champion
Solution

Hi Carlos,

You don’t need to change your server actions for this. I built a small O11 Reactive test app and attached it here.

In Reactive apps, every server call goes to a URL with /screenservices/ in it. A small script watches those calls. While a call is running, it shows a thin bar at the top of the page. It waits 300 ms first, so quick calls don’t make it flash. It also hides the bar if a call fails.

Where to look in the app:

  • BusyIndicatorTest_Th > Interface > Scripts > BusyIndicator is the script.
  • LayoutTopMenu > Required Scripts is where the script is added.
  • LayoutTopMenu > Style Sheet has the CSS for the bar.
  • BusyIndicatorTest is a normal app with no loading logic. The Home screen has a button for each test.

To use it, copy the script and the CSS to your shared layout module. Add the script to your layout’s Required Scripts. Then publish and republish your apps. Put the CSS on the layout, not the theme, so every app that uses the layout gets it.

You can also check these Forge components:

  • XHR Loading Overlay works the same way. You add one block to your layout and it shows a full-screen overlay for every XHR call.
  • XHRLoadingSpecific is based on the first one. It only shows the overlay for buttons with the trigger-loading class.

Mine only watches OutSystems server calls, and the bar doesn’t block the page. Use the one that suits your apps.

I hope this helps.

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