Skip to content

CodeCoupler UI Blocking

Overview

Each component can be blocked with a message to prevent user activity. Instead of a simple message you can use even a complex DOM structure to e.g. display animation or interactive elements.

Important: Do not use the block functions in the init method of an application. Because at this time the application do not have a panel and this leads to an exception.

The preferred way to create a blocking layer, update the message and unblock is the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { BlockHandle } from "@codecoupler/cc-ui";

//This would be inside a component:

//Block:
let blockHandle = new BlockHandle();
await this.block(blockHandle, "This is a message");

//Update:
await this.block(blockHandle, "This is an updated message");

//Unblock:
await this.unblock(blockHandle);

An alternative way to get an handle would be:

1
2
//Block:
let blockHandle = await this.block("This is a message").then((e) => e.handle);

But here you have to pay attention if parallel processes would try to access the handle. It can happen that the handle has not yet been returned before another process uses it.

Each call to block(..) will return the following object:

1
2
3
4
5
6
{
    container: HTMLELement, //The container in which the message is displayed
    $container: jQuery,     //The jQuery counterpart of "container"
    handle: BlockHandle,    //An handle which can be used to update the message
    isVirtual: Boolean      //true, if the layer is currently in stack
}

Stacking Concept

Each block() call with a specific block handle will produce its own blocking layer. If there is already an existing blocking layer it will be moved into a stack. If you use unblock() the last layer pushed into this stack will be popped out from the stack and reactivated.

This stacking concept is because multiple asynchronous processes can block a component. Each process has to take care of removing its own blocking layer and other not finished processes can still show their own blocking layer.

Sticky Blocking Layer

You can mark a layer as "sticky". This layer will be move any other non-sticky or sticky layer into the stack as before. From now on any non-sticky layer will not push this sticky layer into the stack. The non-sticky layer will be created and pushed into the stack directly. A sticky layer will stay on top until you remove this layer or another sticky layer will be created.

Sticky layers will be pushed into a separate stack. Each time a layer is taken out of the stack the sticky layers are brought back first.

Updating Blocking Layer

Because of this concept calling block without an handle multiple times behind each other would produce more and more blocking layers. You see, this is not a suitable method to update a blocking message.

To block a component and ongoing update the message or other UI elements you have to use use an handle or update the message container directly.

Using the Handle

If you call the block without an handle, a new one will be generated for you which you can read from resolving value of the returned promise. But we recommend to create a handle in advance and use this. We will explain later why.

If you want to reuse the same blocking layer but update just the message, use this handle as argument like in block(handle,text). The message of the blocking layer will be replaced. This works even if the blocking layer is not visible at this time and lives in the stack.

Please note that you can only change the message if calling block with an handle. Modifying settings, type etc. will ot work.

The reason why a handle should be generated in advance concerns processes that access the same blocking layer in parallel. Because the block method is asynchronous the returned handle will not returned directly. In case that a parallel process want to update the message it can happen that the second process does not yet know a handle and thus creates another layer.

Using the Message Container

Another method to update the message is for advanced actions and manipulating the DOM elements of the message directly. The returned container or $container property points to the DOM element that includes the message container of the blocking layer. Therefore you can manipulate the DOM directly without using the block() method again.

Using the second method you have to pay attention to the returned property isVirtual. If this is set to true (use the exact comparsion because the value can be e.g. undefined) the container does not live in the DOM tree. The container and its blocking layer was pushed into the stack and some node properties may not work as expected. In particular the container do not have a perentNode and the sizes may be unpredictable.

However, even when using this method, you should remember the block handle or generate and use it in advance. This is needed to eventually remove the blocking layer.