Skip to content

Stages & Components: Widget

A widget component extends the Widget class and is one of the components where you can implement user interfaces. Let's start with a simple one.

What are we learning here?

  • How to create a Widget component
  • Use this.element to inject a HTML structure
  • Use template variables in our HTML structure

We put the files for the widget into the same directory as the main application file. Widgets which will be used only by one application should be placed in the application folder. If you plan to develop a reusable component, best practice would be to put all related files of the component into a separate directory with a main file index.js.

We will put the HTML of the widget interface in a separate file and use template variables there. Please note the .ejs.html extension. This is important so that variables can be processed:

src/demo/apps/widget-basics/content.ejs.html

1
<h2><%= locals.myHeader %></h2>

If we import files with the extension .ejs.html, we get a function that we can call with the desired values for the variables. This function then gives us back the final HTML code. Don't be surprised why we have outsourced the template injection to its own function. We will need this structure later in this walkthrough.

src/demo/apps/widget-basics/content.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { Widget } from "@codecoupler/cc-ui";
import template from "./content.ejs.html";
export default class extends Widget {
  myHeader = "JS Widget Basics";
  async start() {
    this.injectTemplate(template({
      myHeader: this.myHeader
    }));
  }
  injectTemplate(tpl) {
    this.element.html(tpl);
  }
}

For now it is only important to know, that you have an async start() method where you can start and an element in this.element. This element is called the "Component Element". Not every component provides a component element like a widget component.

A component element can be filled with any structure. For this you can use this.element, which is like a striped down jQuery Object (only certain jQuery methods will work) with additional functions.

As already described, the application component also has a main stage. The main stage of an application component is the content area between tilte bar and border elements.

Now load the widget into the main stage of our application. We will use again the method async load() of the main stage of the application for this, like we previously loaded our system into the initial stage or the application into the system component.

Important again: Loading a component is always asynchronous. So do not forget to wait for it with await:

src/demo/apps/widget-basics/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 Widget Features"
      }
    }
  };
  async start() {
    await this.stage.load(ChildComponent);
  }
}

Start Definition Object vs Shortcut Signature

We will use here a signature of the load method which expects only one Component. This is just a shortcut signature. The load method normally expects a so called start definition object. This would look like:

load({
  component: ChildComponent
})