Skip to content

Box

The last base component we will introduce is the Box. The base components Widget and Canvas provide this.element which can be used like an jQuery object. This element can be changed, filled and even completely replaced.

A box component do not provide such an element. Instead, the component offers another element via this.box (or this.$box as jQuery object), but this has certain limitations:

  • You should never replace the box element! The world will definitely end!
  • Never use the start() method to manipulate the content of the box! This will cause incredible pain!
  • Use always and only the method finalize() for this or wait until the component has been initialized! From inside of the component you know that a component is initialized if the boot() method is executed. From outside of the component you know that a component is initialized if the promise initialized or the promise of the load() method was resolved.
  • If you modify the content in the method finalize() you have to call super.finalize() and to do that first thing! Anything else will lead to disaster!

What are we learning here?

  • Use Box component

Thus there are only the following possibilities to change the contents of the box:

Method 1:

Do not forget to call super.finalize(). If you don't forget that, this is the safest way to customize the box content.

export default class extends Box {
  async finalize(){
    super.finalize();
    this.$box.html("Hello World");
  }
}

Method 2:

Modifying the content of a component element or a component box is also possible from the outside. We will see more detailed examples on this topic in the next chapters.

Modifing the content after the promise of the "load()" method resolves, in the "start()" method of the parent component is pretty safe too. The advantage here is also that the parent component is at least still in the initialization phase.

export default class extends Application {
  async start(){
    let component = await this.stage.load(Box);
    component.$box.html("Hello World");
  }
}

// Or more complicated (for whatever reason)
export default class extends Application {
  async start(){
    let component = this.stage.load(Box);
    component.initialized.then(() => component.$box.html("Hello World");)    
  }
}

Method 3:

The boot method will be called after initialization but it can have some sideffects and you never know what other listeners will be executed after initialization.

export default class extends Box {
  async boot(){
    this.$box.html("Hello World");
  }
}

Despite these limitations, this component type is useful. For example, if you just want to implement simple HTML structures In contrast to a canvas component, a box component has the advantage that in many cases it saves one HTML element and this leads to a streamlining of the application.

As you can see now you can also use it to full height and width layout structures.

We will create again a new HTML template, a new widget component and a new application:

src/demo/apps/simple-box/content.html

1
2
3
4
5
<h2 class="flex-grow-0">JS Simple Box</h2>
<div class="p-2 flex-grow-0 border border-success">A small header</div>
<div class="p-2 flex-grow-1 border border-success">
  A bigger section which should take all the rest of the space
</div>

src/demo/apps/simple-box/content.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { Box } from "@codecoupler/cc-ui";
import template from "./content.html";
export default class extends Box {
   async finalize() {
      super.finalize();
      this.$box.addClass("h-100 d-flex flex-column");
      this.$box.css("padding", "20px");
      this.$box.html(template);
   }
}

src/demo/apps/simple-box/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { Application } from "@codecoupler/cc-ui";
import ChildComponent from "./content.js";
export default class extends Application {
  static defaults = {
    "@codecoupler": {
      panel: {
        panelSize: "640 400",
        headerTitle: "Test Box Features"
      }
    }
  };
   async start() {
      await this.stage.load(ChildComponent);
   }
}

We will load the in our system.js file (just replacing again):

src/system.js

1
2
3
4
5
6
7
import { Component } from "@codecoupler/cc-ui";
import TestApp from "./demo/apps/simple-box";
export default class extends Component {
  async boot() {
    await this.stage.load(TestApp);
  }
}

Now you see a amazing flexbox layout based on a box component.