Clone on Gitea
Introduction
Explained by ducks
FAQ
Getting Started
Components
Component Basics
Auto Initialization From DOM
Templates
Children and Parents
Roles
Strictness
Fields
What is a Field
Binding Fields to DOM
Reading and Writing Fields
Value Casting
Flags
Events
Overview
Event Handlers
DOM Events
Custom Events
Propagation and Flow
Advanced Event Control
Beyond Components
States
Overview
StateEngine
DisplayStateEngine
Field Matchers
Ordering and priority
Debugging
Advanced usage
Ajax
ComponentUI
VirtualForm
Unit Testing
Helpers
Overview
Cookies
Arrays

Custom Events

Custom events are events that you publish yourself using this.events.publish(...) or the ones received from Qite's standard components. They represent domain-level signals emitted by a component and handled by its parent. Unlike DOM events, custom events do not use the "@" prefix.

Publishing a custom event

Publishing is straightforward:

// Somewhere inside component instance context
this.events.publish("update", {
    data: { customer_id: 42 }
});

The first argument is the event name. The second argument is an optional object containing data— whatever you pass as data becomes the payload received by handlers.

Listening to a custom event

A parent component listens to a child's custom event by specifying the child's role as the source:

class AccountPageComponent extends BaseComponent {
    constructor(tree_node) {
        super(tree_node);

        this.events.add([
            ["update", ">profile_form", (data) => {
            //---^-----------------^----------------------------
            // event name          event source (child component)
                this.refreshSummary(data.customer_id);
            }]
        ]);
    }
}

In this example:

  • The child component with role "profile_form" publishes "update" event.
  • The parent listens using ">profile_form"
  • The handler receives whatever the child passed as data

Designing clean component APIs

A well-designed component hides DOM details internally and exposes only meaningful domain events. For example:

  • A PaymentButton listens to "@click" internally.
  • It publishes "payment_requested" to its parent.
  • The parent does not care about "@click" at all.

This kind of separation keeps components composable and predictable.

Publishing without data

If you only want to signal that something happened, you may omit data

this.events.publish("cancel");

The handler will still run, but it will receive undefined as its argument.

Naming events

Event names are just strings, but they should stay concise and neutral. Since the child's role already provides context, the event name doesn't need to repeat it. If a component with role "profile_form" emits an event, calling it "update" is usually enough:

["update", ">profile_form", handler]

The role tells you what emitted the event. The event name tells you what kind of signal it is.

Prefer short, present-tense names such as:

  • "update"
  • "save"
  • "submit"
  • "cancel"

Keep event names simple and consistent. The combination of role and event name defines the meaning.

Propagation model

When a component publishes a custom event:

  1. It is first delivered to itself (if it listens to "self").
  2. It is then delivered to its parent.
  3. The parent may publish another event upward if needed.

Custom events do not magically travel across the entire component tree. They move through explicit parent-child subscriptions. This makes event flow predictable and easy to reason about.