Skip to content

General Features

We will now add the same application a second time so we can examine the behaviour of two applications started in parallel.

We override the icon of the second entry to be able to distinguish them and parameterize these two application entries with the property options:

apps.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
import TestingButtonsApp from "./apps/testing-buttons.js";
export default function() {
  return [
    {
      ui: {
        iconHtml: '<i class="far fa-smile fa-fw"></i>',
        name: "Just an Alert"
      },
      app: () => {
        alert("Hello World");
      }
    },
    {
      app: TestingButtonsApp,
      options: {
        text: "My First Application"
      }
    },
    {
      ui: {
        iconHtml: '<i class="fas fa-tree fa-fw"></i>'
      },
      app: TestingButtonsApp,
      options: {
        text: "My Second Application"
      }
    }
  ];
}

We modify now our application to respond to these parameters:

apps/testing-buttons.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
import { Application, Layout } from "@codecoupler/cc-ui";
import buttons from "./custom-buttons";
import MyFirstWidget from "../widgets/my-first-widget.js";
export default class extends Application {
  static ui = {
    name: "Testing Buttons",
    iconHtml: '<i class="fas fa-seedling fa-fw"></i>'
  };
  async init(env, options) {
    let layout = {
      header: {
        show: true
      },
      root: {
        /* .... left out for the sake of simplicity .... */
      }
    };
    await super.init({
      panel: {
        panelSize: "820 600",
        headerTitle: "My First Title",
        footerToolbar:
          '<i class="far fa-hand-point-right mx-1"></i> [blocks][hints][alerts][close]',
        content: `
          <div class="d-flex flex-column h-100">
          <div class="bg-info text-center text-white py-3">+++ ${options.text} +++</div>
          <div class="flex-grow-1 position-relative" data-role="widget"></div>
          </div>
        `
      },
      buttons: buttons,
      widget: {
        widget: Layout,
        options: layout
      }
    });
  }
}

Now start "both" application twice to examine the following features.

Arguments

As you see the two application instances have now a different banner text. The object you defined in options can be read by the argument options of the init method.

Focus Trap

Click on each application window and press the Tab-Button. You will see, the focus will stay always inside the top-most application.

Browser Navigation

Now that you have clicked multple times alternately in each application so that it comes to the front the browser has remembered these actions.

Now click the back button or the forward button multiple times. You will see that the user can navigate back to the last application that he have fronted or forward to the previous fronted application.

ID's

You can even save this history beyond a reload. For this you have to add id's to the application entries and also start the system with an id:

apps.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
import TestingButtonsApp from "./apps/testing-buttons.js";
export default function() {
  return [
    {
      ui: {
        iconHtml: '<i class="far fa-smile fa-fw"></i>',
        name: "Just an Alert"
      },
      app: () => {
        alert("Hello World");
      }
    },
    {
      app: TestingButtonsApp,
      id: "TestApp1",
      options: {
        text: "My First Application"
      }
    },
    {
      ui: {
        iconHtml: '<i class="fas fa-tree fa-fw"></i>'
      },
      app: TestingButtonsApp,
      id: "TestApp2",
      options: {
        text: "My Second Application"
      }
    }
  ];
}

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
import { System, Sidebar } from "@codecoupler/cc-ui";
import HeaderStage from "./stages/header.js";
import apps from "./apps.js";
import "./style.css";
import "./sidebar.css";
let system = new System({
  id: "codecoupler-walkthrough",
  apps: apps,
  stages: [
    {
      stage: Sidebar
    },
    {
      stage: HeaderStage,
      options: { header: "Test" }
    }
  ]
});
system.initialized
  .then((system) => {
    console.info("System is Ready!", system.id);
  })
  .catch((e) => {
    console.error(e);
    if (!e.systemBlocked)
      document.body.innerHTML = "Oops, Something went wrong!";
  });

Now repeat the steps starting the applications and bring them randomly to the front. Then press the reload button.

You will see that the last fronted application will be automatically started. If you click on the back button, the last fronted application will be automatically started and fronted.

Now restart your browser and navigate again to your site. You will see that the browser storage have saved the last active application and it will be started automatically. The history is of course lost.

This behaviour is very important for website look alike sites that we will discuss later. Basically you should always use id's. Otherwise for the system and applications will get randomly generated id's which can under certain circumstances mess up the url.

Setting id's also ensures that you cannot start another system with the same id.