Skip to content

Loading Components: Error Messages

Now let's look at the layer error. This layer is also a blocking layer like block and have a higher z-index as as block. It's semi-transparent background is redder.

Here is another special feature of blocking layers. All blocking layers hide all underlying blocking layers, of course including all components loaded there. As soon as these are no longer used, they are removed and the highest underlying blocking layer is shown again. So there is always only one blocking layer to see.

What are we learning here?

  • How to block a stage with an error message
  • Using the helper method block(Type, Message)

The code of loading an error message manually in contrast to the code of loading an normal message is almost identical. The only difference would be the option level which value is in the one case block and in the other error.

In order not to further bloat our code we will use now a shortcut which is available for every comopoent this.block(type,text). type can be info or error.

The shortcut will load the component CenteredMessage into the level block or error of the root stage and disable the splash modules like we have done.

Furthermore will the shortcut block the stage in which the component resides if the root stage is not available. This is the case if you try to use the method within the init() method.

Let's add one button into our HTML structure:

src/demo/widgets/loading-components/index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div class="border rounded d-inline-block p-1 mr-2 mt-2">
  Blocking
  <button class="btn btn-xs btn-info" data-role="modal-app">
    <i class="fas fa-check-circle"></i> App
  </button>
  <button class="btn btn-xs btn-info" data-role="modal-multi-app">
    <i class="fas fa-check-circle"></i> MultiApp
  </button>
  <button class="btn btn-xs btn-info" data-role="modal-message">
    <i class="fas fa-check-circle"></i> Message
  </button>
  <button class="btn btn-xs btn-danger" data-role="modal-error">
    <i class="fas fa-check-circle"></i> Error
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 mt-2">
  App
  <button class="btn btn-xs btn-info" data-role="inline-app-noid">
    <i class="fas fa-times-circle"></i>
  </button>
  <button class="btn btn-xs btn-info" data-role="inline-app-id">
    <i class="fas fa-check-circle"></i>
  </button>
</div>

And attach some handlers:

src/demo/widgets/loading-components/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { Box, MockApplication, CenteredMessage } from "@codecoupler/cc-ui";
import template from "./index.html";
export default class extends Box {
  async finalize() {
    super.finalize();
    this.$box.html(template);
    let $this = this.options.target || this.env.parent;
    this.$box.find("[data-role=modal-error]").on("click", async () => {
      let normalMessage = await $this.block("info", "A Normal Message");
      await new Promise((r) => setTimeout(() => r(), 2000));
      let errorMessage = await $this.block("error", "An Error Message");
      await new Promise((r) => setTimeout(() => r(), 2000));
      errorMessage.destroy();
      await new Promise((r) => setTimeout(() => r(), 2000));
      normalMessage.destroy();
    });
    this.$box.find("[data-role=modal-message]").on("click", async () => {
      let message = await $this.getStage("root").load({
        component: CenteredMessage,
        options: { text: "You are blocked!" },
        level: "block"
      });
      for (let x = 0; x <= 100; x += 25) {
        await new Promise((r) => setTimeout(() => r(), 7500));
        message.text = `Please Wait\n${x}% Progress`;
      }
      await new Promise((r) => setTimeout(() => r(), 2000));
      message.destroy();
    });
    this.$box.find("[data-role=modal-multi-app]").on("click", async () => {
      let firstApp = await $this.getStage("root").load({
        component: MockApplication,
        id: "first-app",
        level: "block",
        options: {
          "@codecoupler": {
            application: {
              panel: { position: "left-center left-center 70px" }
            }
          }
        }
      });
      await new Promise((r) => setTimeout(() => r(), 2000));
      let secondApp = await $this.getStage("root").load({
        component: MockApplication,
        id: "second-app",
        level: "block",
        options: {
          "@codecoupler": {
            application: {
              panel: { position: "right-center right-center -70px" }
            }
          }
        }
      });
      await new Promise((r) => setTimeout(() => r(), 2000));
      firstApp.front();
      await new Promise((r) => setTimeout(() => r(), 2000));
      firstApp.destroy();
      await new Promise((r) => setTimeout(() => r(), 2000));
      secondApp.destroy();
    });
    this.$box.find("[data-role=modal-app]").on("click", async () => {
      await $this.getStage("root").load({
        component: MockApplication,
        level: "block"
      });
    });
    this.$box.find("[data-role=inline-app-noid]").on("click", async () => {
      await $this.load(MockApplication);
    });
    this.$box.find("[data-role=inline-app-id]").on("click", async () => {
      await $this.load(MockApplication, "some-id");
    });
  }
}

Now click on the button "Error" to start the show:

  • A normal message will be loaded into the layer block. As a result, the widget will be blocked.
  • After 2 seconds an error message will be loaded into the layer error. As a result, the layer block will be hidden.
  • After 2 seconds the error message component will be destroyed. As a result, the layer block appears again.
  • After 2 seconds the normal message component will be destroyed. As a result, the widget will be unblocked.