diff options
| author | Shulhan <ms@kilabit.info> | 2021-09-05 16:09:55 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2021-09-05 18:36:42 +0700 |
| commit | 2df99a87e652db2c82383b59307b6016ae2ba4f4 (patch) | |
| tree | ddca74b85f61962dae505e404706b5f2336ed901 | |
| parent | 437cee56693f69b2a58f37f8a5ff5b931ea803a2 (diff) | |
| download | pakakeh.ts-2df99a87e652db2c82383b59307b6016ae2ba4f4.tar.xz | |
input: implement class WuiInputString
The WuiInputString create an HTML input for string with predefined
options.
The required options are "label" and "value".
| -rw-r--r-- | input/example.ts | 46 | ||||
| -rw-r--r-- | input/string.d.ts | 23 | ||||
| -rw-r--r-- | input/string.ts | 135 |
3 files changed, 204 insertions, 0 deletions
diff --git a/input/example.ts b/input/example.ts index 3e68451..aa26d2d 100644 --- a/input/example.ts +++ b/input/example.ts @@ -1,5 +1,50 @@ +import { WuiInputString, WuiInputStringOpts } from "./string.js" import { WuiInputNumber, WuiInputNumberOpts } from "./number.js" +function exampleInputString() { + let el_example = document.createElement("div") + + let el_title = document.createElement("h3") + el_title.innerText = "Input string" + el_example.appendChild(el_title) + + let opts: WuiInputStringOpts = { + id: "my_input_string", + label: "Input string with ID", + value: "Hello, input string", + hint: "The input ID is 'my_input_string'", + onChangeHandler: (new_value: string) => { + console.log("input string new value: ", new_value) + } + } + let el_input_string = new WuiInputString(opts) + el_example.appendChild(el_input_string.el) + + opts = { + label: "Input string disabled", + value: "Hello, disabled input string", + is_disabled: true, + hint: "The input string is disabled", + onChangeHandler: (new_value: string) => { + console.log("input string new value: ", new_value) + } + } + el_input_string = new WuiInputString(opts) + el_example.appendChild(el_input_string.el) + + opts = { + label: "Input string without hint", + value: "Hello, input string without hint", + onChangeHandler: (new_value: string) => { + console.log("input string without hint: new value: ", new_value) + } + } + el_input_string = new WuiInputString(opts) + el_example.appendChild(el_input_string.el) + + document.body.appendChild(el_example) +} + function exampleInputNumber() { let el_example = document.createElement("div") @@ -66,4 +111,5 @@ function exampleInputNumber() { document.body.appendChild(el_example) } +exampleInputString() exampleInputNumber() diff --git a/input/string.d.ts b/input/string.d.ts new file mode 100644 index 0000000..f0a36fe --- /dev/null +++ b/input/string.d.ts @@ -0,0 +1,23 @@ +export interface WuiInputStringOpts { + label: string; + value: string; + id?: string; + hint?: string; + is_disabled?: boolean; + onChangeHandler?: (new_value: string) => void; +} +export declare class WuiInputString { + opts: WuiInputStringOpts; + el: HTMLElement; + private el_label; + private el_input; + private el_hint; + private el_hint_toggler; + private value; + constructor(opts: WuiInputStringOpts); + private generateLabel; + private generateInput; + private generateHintToggler; + private generateHint; + private onClickHintToggler; +} diff --git a/input/string.ts b/input/string.ts new file mode 100644 index 0000000..d8faf36 --- /dev/null +++ b/input/string.ts @@ -0,0 +1,135 @@ +export interface WuiInputStringOpts { + label: string + value: string + id?: string + hint?: string + is_disabled?: boolean + onChangeHandler?: (new_value: string) => void +} + +const WUI_INPUT_STRING_CLASS = "wui_input_string" +const WUI_INPUT_STRING_CLASS_HINT = "wui_input_string_hint" +const WUI_INPUT_STRING_CLASS_HINT_TOGGLER = "wui_input_string_hint_toggler" +const WUI_INPUT_STRING_CLASS_INPUT = "wui_input_string_input" +const WUI_INPUT_STRING_CLASS_LABEL = "wui_input_string_label" + +// +// WuiInputString create an HTML input for string with predefined options. +// The required options are "label" and "value". +// +// Format of generated HTML output, +// +// <div [id=${id}] class="${WUI_INPUT_STRING_CLASS}"> +// <div> +// <label class="${WUI_INPUT_STRING_CLASS_LABEL}">${label}</label> +// <input +// class="${WUI_INPUT_STRING_CLASS_INPUT}" +// [disabled=${is_disabled}] +// value=${value} +// > +// [<span class="${WUI_INPUT_STRING_CLASS_HINT_TOGGLER}">i </span>] +// </div> +// [<div class="${WUI_INPUT_STRING_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. +// +// User can set onChangeHandler to receive new value when the input value +// changes. +// +export class WuiInputString { + el: HTMLElement + private el_label!: HTMLElement + private el_input!: HTMLInputElement + private el_hint!: HTMLElement + private el_hint_toggler!: HTMLElement + private value: string = "" + + constructor(public opts: WuiInputStringOpts) { + this.value = opts.value + + this.el = document.createElement("div") + if (opts.id) { + this.el.id = opts.id + } + this.el.classList.add(WUI_INPUT_STRING_CLASS) + this.el.style.padding = "2px" + + let wrapper = document.createElement("div") + this.generateLabel(wrapper) + this.generateInput(wrapper) + if (opts.hint) { + this.generateHintToggler(wrapper) + } + this.el.appendChild(wrapper) + + if (opts.hint) { + this.generateHint() + } + } + + private generateLabel(wrapper: HTMLElement) { + this.el_label = document.createElement("label") + this.el_label.classList.add(WUI_INPUT_STRING_CLASS_LABEL) + this.el_label.innerHTML = `${this.opts.label} ` + wrapper.appendChild(this.el_label) + } + + private generateInput(wrapper: HTMLElement) { + this.el_input = document.createElement("input") as HTMLInputElement + this.el_input.classList.add(WUI_INPUT_STRING_CLASS_INPUT) + this.el_input.value = "" + this.opts.value + + if (this.opts.is_disabled) { + this.el_input.disabled = true + } + + if (this.opts.onChangeHandler) { + console.log("register onchange") + this.el_input.onkeyup = (ev: Event) => { + if (this.opts.onChangeHandler) { + if (this.value !== this.el_input.value) { + this.opts.onChangeHandler(this.el_input.value) + this.value = this.el_input.value + } + } + } + } + + wrapper.appendChild(this.el_input) + } + + private generateHintToggler(wrapper: HTMLElement) { + this.el_hint_toggler = document.createElement("span") + this.el_hint_toggler.classList.add(WUI_INPUT_STRING_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_STRING_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" + } + } +} |
