- Before you start
- A running settings page and main.cpp
- What you will build
- Read current values, validate, save and restore
Current values and initial attributes
HTMLInputElement::value() returns the current edited value. The value attribute represents the default and may differ. Read a checkbox’s current state with isChecked(). The project checks element types and exits if the document structure is missing required nodes.
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;
The application data model
SettingsState stores the name, notification preference and successful-save count. Validation rejects names containing only ASCII spaces, tabs or newlines, and names over 256 UTF-8 bytes. Failure preserves existing state. The page’s maxlength=64 limits editing, while native code validates independently.
#pragma once
#include <string>
#include <utility>
// 练习项目只保存在内存中,退出后恢复默认值。
struct SettingsState {
std::string name = "Studio";
bool notifications = true;
unsigned revision = 0;
bool save(std::string nextName, bool nextNotifications) {
const auto begin = nextName.find_first_not_of(" \t\r\n");
if (begin == std::string::npos) return false;
const auto end = nextName.find_last_not_of(" \t\r\n");
nextName = nextName.substr(begin, end - begin + 1);
if (nextName.size() > 256) return false;
name = std::move(nextName);
notifications = nextNotifications;
++revision;
return true;
}
};
The save callback
The click handler reads current control values. Validation failure displays an error; success updates status and the count. setTextContent displays user input as text instead of interpolating it into HTML. The handler runs on the UI thread, so avoid blocking network work here.
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));
});
Restore unsaved edits
The restore button updates controls from the last successful save. setValue and setChecked set current state; restoring does not increment the count. Edit the name without saving, then restore it.
reset->addEventListener("click", [&](kui::Event&) {
name->setValue(state.name);
notifications->setChecked(state.notifications);
name->removeAttribute("aria-invalid");
status->setAttribute("data-state", "idle");
status->setTextContent(english ? "Restored the last saved values." : "已恢复上次保存的内容。");
});
Interaction checks
Check the actual window with the actions below. CTest runs data-model regressions, complementing input and keyboard checks in the window.
- Save Workbench: status displays the name and the count increases.
- Save whitespace: an error appears and the count stays unchanged.
- Save <h1>Test</h1>: status displays the literal text.
- Restore unsaved edits: both controls return to the last saved values.
Current SDK keyboard limitation
In the Windows x64 SDK 3.61.7 lesson, Tab focuses the button, but Enter injected through DevTools does not trigger its save click. Mouse activation works. This does not establish behavior for every native keyboard path or full keyboard acceptance.
Practice and acceptance
Use these actions to check completion; there is no need to copy the same code into another project.
- A valid save increases the count; blank input preserves state and count.
- <h1>Test</h1> remains literal text in the feedback.
- Restore unsaved edits to the last successful values.
- Restarting resets state: this lesson does not persist data to disk.
Something unclear?
Report an issue on this page →