aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2021-09-05 19:52:15 +0700
committerShulhan <ms@kilabit.info>2021-09-05 19:57:35 +0700
commit897d8bbdd89034d8a9bdc781de07c5492b340f1f (patch)
treef44d0001ac1b1e53e55cc9174a2791c39545027f
parentb18cd3529299e03f5c14d9bf702f28c3f7acb4d0 (diff)
downloadpakakeh.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.ts32
-rw-r--r--input/checkboxes.ts172
-rw-r--r--input/example.ts66
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 = " &#x2139;"
+
+ 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()