Page MenuHomeSealhub

simple-input.ts
No OneTemporary

simple-input.ts

import { Context } from "koa";
import { FlatTemplatable, tempstream } from "tempstream";
import { getRequiredClass, inputWrapper } from "../../utils/input-wrapper.js";
import { renderAttributes } from "../../utils/render-attributes.js";
import { FormField } from "../fields/field.js";
import { FormDataValue } from "../form-types.js";
import { FormControlContext } from "./form-control.js";
import { FormFieldControl } from "./form-field-control.js";
export type SimpleInputOptions = {
id?: string;
label?: string;
autocomplete?: boolean;
hide_errors?: boolean;
type?:
| "color"
| "date"
| "email"
| "file"
| "month"
| "number"
| "password"
| "search"
| "tel"
| "text"
| "time"
| "url"
| "week";
value?: string;
placeholder?: string;
readonly?: boolean;
step?: number;
suffix?: string;
};
export class SimpleInput<
ParsedValue,
Options extends SimpleInputOptions = SimpleInputOptions
> extends FormFieldControl {
options: SimpleInputOptions;
constructor(
public field: FormField<boolean, ParsedValue>,
options?: Options
) {
super([field]);
this.options = options || {};
}
async preInput(
_ctx: FormControlContext,
_data: Record<string, FormDataValue>
): Promise<FlatTemplatable> {
return "";
}
getType(): string {
return this.options.type || "text";
}
getLabel(): string {
return this.options.label != undefined
? this.options.label
: this.field.name;
}
getID(): string {
return this.options.id || this.field.name;
}
getPlaceholder(): string {
return this.options.placeholder === ""
? ""
: this.options.placeholder || this.getType();
}
async getInputAttributes(
fctx: FormControlContext
): Promise<Record<string, string | boolean>> {
const readonly = this.options.readonly || false;
const required = this.field.required;
const { parsed, raw, valid } = await this.field.getValue(
fctx.ctx,
fctx.data,
true
);
return Object.fromEntries([
<const>["id", this.getID()],
<const>["type", this.getType()],
<const>["name", `${fctx.field_name_prefix}${this.field.name}`],
<const>[
"value",
!valid && raw
? raw.toString()
: parsed !== undefined && parsed !== null
? (parsed as string)?.toString() || ""
: "",
],
...(fctx.form_id ? [["form", fctx.form_id]] : []),
<const>["placeholder", this.getPlaceholder()],
...(readonly ? [["readonly", true]] : []),
...(required ? [["required", true]] : []),
...(!this.options.autocomplete ? [["autocomplete", "off"]] : []),
...(this.options.step ? [["step", this.options.step]] : []),
]) as Record<string, string>;
}
async postInput(_: Context): Promise<FlatTemplatable> {
return this.options.suffix
? /* HTML */ `<span class="suffix">${this.options.suffix}</span>`
: "";
}
async renderInput(
_ctx: Context,
attributes_str: string,
_data: Record<string, FormDataValue>
): Promise<FlatTemplatable> {
return `<input ${attributes_str} />`;
}
getWrapperModifiers(): string[] {
return [
this.getID(),
this.getType(),
"type__" + this.getType(),
getRequiredClass(this.field.required),
];
}
async render(fctx: FormControlContext): Promise<FlatTemplatable> {
const id = this.getID();
const label = this.getLabel();
const { valid, message } = await this.field.getValue(
fctx.ctx,
fctx.data,
true
);
return inputWrapper(
"simple-input",
this.getWrapperModifiers(),
tempstream/* HTML */ `
${label ? `<label for="${id}">${label}</label>` : ""}
${await this.preInput(fctx, fctx.data)}
${this.renderInput(
fctx.ctx,
renderAttributes(await this.getInputAttributes(fctx)),
fctx.data
)}
${this.postInput(fctx.ctx)}
${~valid && !this.options.hide_errors && fctx.validate
? `<div class="input__error">${message}</div>`
: ""}
`
);
}
}

File Metadata

Mime Type
text/x-java
Expires
Tue, May 27, 23:48 (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
625579
Default Alt Text
simple-input.ts (3 KB)

Event Timeline