Page MenuHomeSealhub

checkboxed-list-input.ts
No OneTemporary

checkboxed-list-input.ts

import { tempstream } from "tempstream";
import { getRequiredClass, inputWrapper } from "../../utils/input-wrapper.js";
import {
CheckboxedListField,
CheckboxedListItem,
} from "../fields/checkboxed-list.js";
import { FormControlContext } from "./form-control.js";
import { FormFieldControl } from "./form-field-control.js";
export class CheckboxedListInput extends FormFieldControl {
constructor(
public field: CheckboxedListField<boolean>,
public options: { label: string } = { label: field.name }
) {
super([field]);
}
generateCountBasedClasses(n: number) {
return [
"options-count--" + n.toString(),
...(n >= 5 ? ["options-count--5-or-more"] : []),
...(n >= 10 ? ["options-count--10-or-more"] : []),
...(n >= 15 ? ["options-count--15-or-more"] : []),
...(n >= 20 ? ["options-count--20-or-more"] : []),
];
}
async render(fctx: FormControlContext) {
const {
valid,
message,
parsed: currentValue,
} = await this.field.getValue(fctx.ctx, fctx.data, true);
const pickedValues = Object.entries(currentValue || {})
.filter(([, is_on]) => is_on)
.map(([key]) => key);
const [options, isVisible] = await Promise.all([
this.field.generateOptions(fctx.ctx),
this.field.isVisible(fctx.ctx),
]);
const ungroupped = [];
const groups: Record<string, CheckboxedListItem[] | undefined> = {};
for (const option of options) {
if (!option.group) {
ungroupped.push(option);
} else {
if (!groups[option.group]) {
groups[option.group] = [];
}
groups[option.group]!.push(option);
}
}
const { name, required } = this.field;
return inputWrapper(
"checkboxed-list",
[
name,
getRequiredClass(required),
...this.generateCountBasedClasses(options.length),
],
tempstream/* HTML */ `<label
>${this.options.label || this.field.name}</label
>
${~valid && fctx.validate
? `<div class="input__error">${message}</div>`
: ""}
<ul>
${isVisible
? Object.entries(groups).map(
([group_label, options]) =>
tempstream/* HTML */ ` <h3>
${group_label}
</h3>
${options!.map(({ value, label }) =>
this.renderOption({
name,
value,
label,
form_id: fctx.form_id,
checked:
pickedValues.includes(
value
),
})
)}`
)
: ""}
${isVisible
? ungroupped.map(({ value, label }) =>
this.renderOption({
name,
value,
label,
form_id: fctx.form_id,
checked: pickedValues.includes(value),
})
)
: ""}
</ul>`
);
}
renderOption({
name,
value,
form_id,
label,
checked,
}: {
name: string;
form_id: string;
value: string;
label?: string;
checked: boolean;
}) {
return tempstream/* HTML */ `<li>
${inputWrapper(
"checkbox",
[name],
/* HTML */ `
<input
type="checkbox"
id="${name}.${value}"
name="${name}.${value}"
${checked ? "checked" : ""}
form=${form_id}
/>
<label for="${name}.${value}">${label || value}</label>
`
)}
</li>`;
}
}

File Metadata

Mime Type
text/x-java
Expires
Wed, May 7, 19:49 (22 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
625211
Default Alt Text
checkboxed-list-input.ts (3 KB)

Event Timeline