RootComponent

This component is created automatically upon Webface.js app initialization and is assigned <body> as its associated dom element.

Currently the only important functionality it has is to catch click events and notify ALL of the child components of this event.

The use case for this would, for example, be a situation when a user first clicks a select box, which opens with a list of options. Naturally, clicking on any other place on the page should close this selectbox. But for it to know it has to close it needs to be notified of such event happening outside of its dom_element. For that, a externalClickCallback() is used - if this method is defined on a component it gets invoked every time someone clicks anywhere on the page, except when the click's target is the said component.

Let's look at an example of how we can use this. Firstly, let's write our html:

We laid out the structure in which we have our own MyComponent, which we'll define below, and its child, a ButtonComponent from Webface.js standard components. We don't see it mention anywhere in the javascript code, but that's because Webface.js looks at the corresponding html and determines that ButtonComponent needs to be loaded.

export class MyComponent extends extend_as("MyComponent").mix(Component).with() {
  constructor() {
    super();

    this.event_handlers.add({ event: "click", role: "disable_button", handler: (self, child) => {
      child.externalClickCallback = function() {
        child.behave("unlock");
      }
    }});

  }
}
window.webface.component_classes["MyComponent"] = MyComponent;

And that's what it'll look like in the browser:

Now let's go over this code. Since some of the concepts introduced here you're not familiar with yet it'd be a good idea to explain.

On line 5 we create an event hander with this.event_handlers.add - Component.event_handlers is an object that tracks events and allows you to add or remove them (read up on Events to understand how it works).

Now, apart from the event handler we added for the button, ButtonComponent itself has a built in click handler which locks the button (ButtonComponent.behave("lock") is called) whenever it's clicked. This is to prevent user from clicking that button again and accidentally submitting the form twice (this can be changed, of course). So that's why in the video below you see button becomes gray and a spinner appears as soon as it's clicked. We didn't have to program that and we could've gotten away without lines 5-9 for that.

However, what we actually want to do is to unlock the button as soon as user clicks in any other place except for the button itself. To do that, we employ a special callback method that you can define on any Webface.js component - externalClickCallback(). This method will be called by the RootComponent automatically when a click event is detected on any dom element except for our button.

As you can see in this example, we defined this method on an object, not the class ButtonComponent. This means it only applies to this particular button and not all buttons. However, if you design your own component, you may add externalClickCallback() to it and then all instances of your component will get to run the code inside it when a click is detected outside of the dom element of that component.