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

Flags

A flag is a named on/off toggle that belongs to a component instance. Unlike fields, flags are not mirrored into the DOM. They exist to drive behavior and logic inside components.

Here is a minimal example that toggles a flag from a button click:

export default class PanelComponent extends BaseComponent {
    constructor(tree_node) {
        super(tree_node);

        this.flags.add(["open", false]);
        //------------------------^----
        //                default value

        this.events.add([
            [ "click", "toggle",
              () => this.flags.set("open", !this.flags.get("open"))
            ],
        ]);
    }
}

Flags are for simple, boolean-like state that affects behavior or visibility — things like "disabled", "open", "loading", "active", "selected".

Unlike fields, flags are not about structured data. They are about intent and control flow. Because flags integrate directly with the state engine and emit "flag_change" events, they are ideal for driving declarative UI transitions without manually toggling classes or touching the DOM.

Creating flags

Flags must be declared before you can use them. You do that with this.flags.add(...). This method accepts a variable number of arguments (it's variadic), where each argument is an array of at least two elements representing a flag: each flag has a name, an initial value, and two optional callbacks.

this.flags.add(
    ["locked", true],
    ["debug",  false],
    ...
);

If you try to access a flag that was never added, Qite will throw a MissingFlag error:

this.flags.get("non-existent"); // => MissingFlag is thrown

Finally, a flag may be dynamically removed with remove(flag_name), although you're unlikely to ever need it:

this.flags.remove("debug");
this.flags.get("debug"); // => MissingFlag is thrown

Reading and writing flags

There are a number of ways to set flags. All the different kinds of versions are demonstrated below:

this.flags.set("debug", true);
this.flags.set("debug", "!locked"); // batch set: debug set to true, locked to false
this.flags.unset("debug");          // debug set to false
this.flags.toggle("locked");        // toggles the flag, so may set to true or false

Just like with fields, you can check if a flag exists by calling the has() method:

this.flags.has("debug");

Callbacks and flag_change

When a flag value actually changes, Flags calls its change callbacks. In Qite, BaseComponent also hooks this up to publish a flag_change event for the component, so parents can react to changes without polling.

If you want per-flag callbacks when you declare the flag, use the two optional array elements (3rd and 4th) when adding a flag:

this.flags.add(
    ["open", false,
        // These callbacks run only when the value flips
        () => { ... }, // when open becomes true
        () => { ... }  // when open becomes false
    ],
);