-
-
Notifications
You must be signed in to change notification settings - Fork 151
Cancelable text input
Karsten Schmidt edited this page Jul 3, 2018
·
3 revisions
(See general info in cookbook intro)
This higher-order textfield component sources its value from a
preconfigured app state view and triggers an event to store value
changes. Each time the input element is being focused we record the
current value, which is then being restored if the user types Esc
and
thereby cancels any edits made. Pressing Enter
triggers
element.blur()
.
export function cancelableInput(ctx: AppContext, view: IView<string | number>, eventID: string) {
let prev: string;
const attribs = {
...ctx.ui.input,
type: "text",
onfocus: (e) => (prev = view.deref()),
oninput: (e) => ctx.bus.dispatch([eventID, e.target.value]),
onkeydown: (e: KeyboardEvent) => {
switch (e.key) {
case "Escape":
ctx.bus.dispatch([eventID, prev]);
(<HTMLElement>e.target).blur();
break;
case "Enter":
ctx.bus.dispatch([eventID, (<HTMLInputElement>e.target).value]);
(<HTMLInputElement>e.target).blur();
break;
default:
}
}
};
return () => ["input", {...attribs, value: view.deref()}];
}
function labeledInput(ctx: AppContext, view: IView<string | number>, label: string) {
const name = cancelableInput(ctx, ctx.views.name, "set-name");
return () => ["div", ["label", ctx.ui.label, label], name];
}
function demoForm(ctx: AppContext) {
const firstName = labeledInput(ctx, ctx.views.firstName, "First name");
const surname = labeledInput(ctx, ctx.views.surname, "Surname");
return () => ["div", firstName, surname];
}