diff options
| author | Shulhan <ms@kilabit.info> | 2021-09-05 19:52:15 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2021-09-05 19:57:35 +0700 |
| commit | 897d8bbdd89034d8a9bdc781de07c5492b340f1f (patch) | |
| tree | f44d0001ac1b1e53e55cc9174a2791c39545027f | |
| parent | b18cd3529299e03f5c14d9bf702f28c3f7acb4d0 (diff) | |
| download | pakakeh.ts-897d8bbdd89034d8a9bdc781de07c5492b340f1f.tar.xz | |
input: implement input for checkboxes
The WuiInputCheckboxes class can create an HTML input for selecting one
or more item using checkbox.
The class require the following options: label, name, and options; and
optionally id, hint, is_disabled, and onChangeHandler.
The onChangeHandler receive all checked values.
| -rw-r--r-- | input/checkboxes.d.ts | 32 | ||||
| -rw-r--r-- | input/checkboxes.ts | 172 | ||||
| -rw-r--r-- | input/example.ts | 66 |
3 files changed, 270 insertions, 0 deletions
diff --git a/input/checkboxes.d.ts b/input/checkboxes.d.ts new file mode 100644 index 0000000..89a35d3 --- /dev/null +++ b/input/checkboxes.d.ts @@ -0,0 +1,32 @@ +import { WuiInputOption } from "./option.js"; +export interface WuiKeyValue { + [key: string]: string; +} +export interface WuiKeySelectOption { + [key: string]: WuiInputOption; +} +export interface WuiInputCheckboxesOpts { + label: string; + name: string; + options: WuiKeySelectOption; + id?: string; + hint?: string; + is_disabled?: boolean; + onChangeHandler?: (values: string[]) => void; +} +export declare class WuiInputCheckboxes { + opts: WuiInputCheckboxesOpts; + el: HTMLElement; + private el_label; + private el_fieldset; + private el_hint; + private el_hint_toggler; + private values; + constructor(opts: WuiInputCheckboxesOpts); + private generateLabel; + private generateInput; + private generateHintToggler; + private generateHint; + private onClickHintToggler; + private onClickCheckbox; +} diff --git a/input/checkboxes.ts b/input/checkboxes.ts new file mode 100644 index 0000000..3da7335 --- /dev/null +++ b/input/checkboxes.ts @@ -0,0 +1,172 @@ +import { WuiInputOption } from "./option.js" + +export interface WuiKeyValue { + [key: string]: string +} + +export interface WuiKeySelectOption { + [key: string]: WuiInputOption +} + +export interface WuiInputCheckboxesOpts { + label: string + name: string + options: WuiKeySelectOption + id?: string + hint?: string + is_disabled?: boolean + onChangeHandler?: (values: string[]) => void +} + +const WUI_INPUT_CHECKBOXES_CLASS = "wui_input_checkboxes" +const WUI_INPUT_CHECKBOXES_CLASS_HINT = "wui_input_checkboxes_hint" +const WUI_INPUT_CHECKBOXES_CLASS_HINT_TOGGLER = "wui_input_checkboxes_hint_toggler" +const WUI_INPUT_CHECKBOXES_CLASS_INPUT = "wui_input_checkboxes_input" +const WUI_INPUT_CHECKBOXES_CLASS_LABEL = "wui_input_checkboxes_label" + +// +// WuiInputCheckboxes create an HTML input for selecting one or more item +// using checkbox. +// +// Format of generated HTML output, +// +// <div [id=${id}] class="${WUI_INPUT_CHECKBOXES_CLASS}"> +// <label class="${WUI_INPUT_CHECKBOXES_CLASS_LABEL}">${label}</label> +// [<span class="${WUI_INPUT_CHECKBOXES_CLASS_HINT_TOGGLER}">i </span>] +// <fieldset +// class="${WUI_INPUT_CHECKBOXES_CLASS_INPUT}" +// [disabled=${is_disabled}] +// > +// ${ for key in options } +// <div> +// <input name=${name} value="${options[key].value}"> +// <label>${key}</label> +// </div> +// ${ endfor } +// </fieldset> +// [<div class="${WUI_INPUT_CHECKBOXES_CLASS_HINT}">${hint}</div>] +// </div> +// +// The "hint" option is optional, if it set the input will have a hint toggler +// to display or hide the input information. +// +// The onChangeHandler receive all checked values. +// +export class WuiInputCheckboxes { + el: HTMLElement + private el_label!: HTMLElement + private el_fieldset!: HTMLFieldSetElement + private el_hint!: HTMLElement + private el_hint_toggler!: HTMLElement + private values: string[] = [] + + constructor(public opts: WuiInputCheckboxesOpts) { + this.el = document.createElement("div") + if (opts.id) { + this.el.id = opts.id + } + this.el.classList.add(WUI_INPUT_CHECKBOXES_CLASS) + this.el.style.padding = "2px" + + this.generateLabel(this.el) + if (opts.hint) { + this.generateHintToggler(this.el) + } + this.generateInput(this.el) + + if (opts.hint) { + this.generateHint() + } + } + + private generateLabel(wrapper: HTMLElement) { + this.el_label = document.createElement("label") + this.el_label.classList.add(WUI_INPUT_CHECKBOXES_CLASS_LABEL) + this.el_label.innerHTML = `${this.opts.label} ` + wrapper.appendChild(this.el_label) + } + + private generateInput(wrapper: HTMLElement) { + this.el_fieldset = document.createElement("fieldset") + this.el_fieldset.classList.add(WUI_INPUT_CHECKBOXES_CLASS_INPUT) + + for (let key in this.opts.options) { + let option = this.opts.options[key] + let value = option.value + + let wrapper = document.createElement("div") + + let el_cb = document.createElement("input") + el_cb.type = "checkbox" + el_cb.name = this.opts.name + el_cb.value = option.value + if (option.selected) { + el_cb.checked = true + this.values.push(value) + } + el_cb.onclick = () => { + this.onClickCheckbox(el_cb.value, el_cb.checked) + } + wrapper.appendChild(el_cb) + + let el_label = document.createElement("label") + el_label.innerHTML = key + wrapper.appendChild(el_label) + + this.el_fieldset.appendChild(wrapper) + } + + if (this.opts.is_disabled) { + this.el_fieldset.disabled = true + } + + wrapper.appendChild(this.el_fieldset) + } + + private generateHintToggler(wrapper: HTMLElement) { + this.el_hint_toggler = document.createElement("span") + this.el_hint_toggler.classList.add(WUI_INPUT_CHECKBOXES_CLASS_HINT_TOGGLER) + this.el_hint_toggler.innerHTML = " ℹ" + + this.el_hint_toggler.onmouseover = () => { + this.el_hint_toggler.style.cursor = "pointer" + } + this.el_hint_toggler.onclick = () => { + this.onClickHintToggler() + } + wrapper.appendChild(this.el_hint_toggler) + } + + private generateHint() { + this.el_hint = document.createElement("div") + this.el_hint.classList.add(WUI_INPUT_CHECKBOXES_CLASS_HINT) + this.el_hint.innerHTML = this.opts.hint || "" + this.el_hint.style.display = "none" + this.el_hint.style.backgroundColor = "gainsboro" + this.el_hint.style.borderRadius = "2px" + this.el_hint.style.padding = "4px" + this.el.appendChild(this.el_hint) + } + + private onClickHintToggler() { + if (this.el_hint.style.display === "none") { + this.el_hint.style.display = "block" + } else { + this.el_hint.style.display = "none" + } + } + + private onClickCheckbox(value: string, selected: boolean) { + for (let x = 0; x < this.values.length; x++) { + if (this.values[x] === value) { + this.values.splice(x, 1) + } + } + if (selected) { + this.values.push(value) + } + if (this.opts.onChangeHandler) { + this.opts.onChangeHandler(this.values) + } + } +} diff --git a/input/example.ts b/input/example.ts index f6a0647..1ca5736 100644 --- a/input/example.ts +++ b/input/example.ts @@ -1,6 +1,7 @@ import { WuiInputString, WuiInputStringOpts } from "./string.js" import { WuiInputNumber, WuiInputNumberOpts } from "./number.js" import { WuiInputSelect, WuiInputSelectOpts } from "./select.js" +import { WuiInputCheckboxes, WuiInputCheckboxesOpts } from "./checkboxes.js" function exampleInputString() { let el_example = document.createElement("div") @@ -149,6 +150,71 @@ function exampleInputSelect() { el_example.appendChild(el_log) } +function exampleInputCheckboxes() { + let el_example = document.createElement("div") + document.body.appendChild(el_example) + + let el_title = document.createElement("h3") + el_title.innerText = "Input checkboxes" + el_example.appendChild(el_title) + + let el_log = document.createElement("div") + + let opts: WuiInputCheckboxesOpts = { + name: "my_fruits", + label: "Input checkboxes", + options: { + mango: { + value: "1000", + selected: false, + }, + papaya: { + value: "200", + selected: false, + }, + rambutan: { + value: "100", + selected: true, + }, + }, + hint: "Select fruits.", + onChangeHandler: (values: string[]) => { + el_log.innerText = `You are selecting ${values}` + }, + } + let input = new WuiInputCheckboxes(opts) + el_example.appendChild(input.el) + + opts = { + name: "my_fruits", + label: "Input checkboxes", + options: { + mango: { + value: "1000", + selected: false, + }, + papaya: { + value: "200", + selected: false, + }, + rambutan: { + value: "100", + selected: true, + }, + }, + hint: "Select fruits.", + is_disabled: true, + onChangeHandler: (values: string[]) => { + el_log.innerText = `You are selecting ${values}` + }, + } + input = new WuiInputCheckboxes(opts) + el_example.appendChild(input.el) + + el_example.appendChild(el_log) +} + exampleInputString() exampleInputNumber() exampleInputSelect() +exampleInputCheckboxes() |
