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

DOM Events

DOM events are native browser events such as "click", "input", "keydown", "change" and so on. In Qite, they are written with an "@" prefix, for example "@click" or "@input". They are declared using the same events.add(...) API as custom events. The only difference is the "@" prefix.

You typically attach DOM events to parts or field elements inside your component template.

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

        this.events.add([
            // User clicks "Apply"
            ["@click", "#apply", () => {
                this.events.publish("coupon_apply", {
                    data: { code: this.fields.get("code") }
                });
            }],

            // User presses Enter inside the input field
            ["@keydown", ".code", (e) => {
                if (e.key === "Enter") {
                    this.events.publish("coupon_apply", {
                        data: { code: this.fields.get("code") }
                    });
                }
            }]
        ]);
    }
}

In this example, the component listens for user interaction on both a "#apply" part and a ".code" field element, and then converts that interaction into a domain-level "coupon_apply" event. Notice that the handler does not read values directly from the DOM beyond what is needed to detect the key press — instead it retrieves the current value from its own fields, keeping DOM details local to the component.

When "@" is NOT required

For "#part" and ".field" sources, DOM events are automatically treated as native events. You may write:

["click", "#remove", handler]

and it will behave as "@click". However, when listening to DOM events coming from a child component role, you must use "@" explicitly:

["@click", ">button", handler]

Without "@", Qite assumes you are listening to a custom event named "click" published by that child component.

Click handling nuance

When you declare "@click", Qite internally listens to both "pointerup" and "click" events and prevents duplicate handling if they fire in quick succession. This avoids common double-trigger issues on touch devices and also makes them more responsive (since "click" events usually have a noticeable delay on such devices).

In other words: use "@click" everywhere with Qite and don't worry about it.

Attaching and reattaching

DOM listeners are attached to elements at registration time. If a "#part" or ".field" element exists when events.add(...) runs, the listener is attached immediately. If it does not exist, no listener is attached.

If your component modifies its internal DOM dynamically (for example, after re-rendering or injecting new parts), you may need to call:

this.events.reAttachDOMEventListeners()

This re-scans the template and attaches listeners again. For most components though, you'll never need this.