FORGE KUI / docs

DOM, events and application data

Use the DOM to locate and update elements.

Version 3.61.7

How to use it

Use the DOM to locate and update elements. Events travel through capture, target and bubble phases. Focus, hover, pointer capture and drag-and-drop affect input routing; verify targets and propagation for nested controls.

Integration and limits

Allow normal frame updates to process content changes. Reading geometry can force a synchronous update; avoid alternating style writes and geometry reads inside a loop. Keep business data in the application and manage update timing and object lifetime explicitly.

Read live form state

Read HTMLInputElement::value() and isChecked(). Use setValue() and setChecked() to update controls. The value/checked attributes differ from live state and do not replace all input-state reads.

cpp
    auto* name = dynamic_cast<kui::HTMLInputElement*>(doc->getElementById("display-name"));
    auto* notifications = dynamic_cast<kui::HTMLInputElement*>(doc->getElementById("notifications"));
    auto* save = doc->getElementById("save");
    auto* reset = doc->getElementById("reset");
    auto* status = doc->getElementById("status");
    auto* revision = doc->getElementById("revision");
    if (!name || !notifications || !save || !reset || !status || !revision) return 2;

A native save event

addEventListener returns a listener ID that removeEventListener can remove. Referenced elements belong to the current document. Reloading invalidates old element references, requiring new lookups and bindings.

cpp
    save->addEventListener("click", [&](kui::Event&) {
        // value() 是当前输入;value 属性是初始值,两者不能混用。
        if (!state.save(name->value(), notifications->isChecked())) {
            name->setAttribute("aria-invalid", "true");
            status->setAttribute("data-state", "error");
            status->setTextContent(english ? "Enter a display name (up to 256 UTF-8 bytes)."
                                         : "请输入显示名称(最多 256 个 UTF-8 字节)。");
            return;
        }
        name->removeAttribute("aria-invalid");
        status->setAttribute("data-state", "success");
        status->setTextContent((english ? "Saved in this session: " : "本次会话已保存:") + state.name);
        revision->setTextContent(std::to_string(state.revision));
    });

The full path of a save action

A UI callback should make it clear what was read, saved and preserved on failure.

  1. Look up elements after loading and check both existence and type.
  2. Read current value()/isChecked() inside the handler, not initial attributes.
  3. Validate in the model; preserve old data on failure and commit on success.
  4. Display feedback with setTextContent and set the state attribute.
  5. Test restoring, blank input, long text and repeated clicks.

Avoid duplicate handlers and invalid captures

Repeated initialization can attach a handler twice and save twice per click. Attach handlers when establishing the page and recreate them when replacing it. Captured model objects must outlive the callbacks; avoid references to a scope that has already returned.