diff options
| author | Shulhan <ms@kilabit.info> | 2024-09-15 14:32:48 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2024-09-15 14:32:48 +0700 |
| commit | d1e96e09438b4a5c7580b86c469e817a61be991f (patch) | |
| tree | 4d81fb2fd62207bbb9162b81083c721ec8fd8e29 /input/checkboxes.js | |
| parent | 1cc9c9dd68a3a59c685505228336430624608852 (diff) | |
| download | pakakeh.ts-d1e96e09438b4a5c7580b86c469e817a61be991f.tar.xz | |
all: commit all generate JavaScript files
This is to simplify development on third party where they can
clone and include the file directly without installing or running
anything to build the files.
Diffstat (limited to 'input/checkboxes.js')
| -rw-r--r-- | input/checkboxes.js | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/input/checkboxes.js b/input/checkboxes.js new file mode 100644 index 0000000..097f19c --- /dev/null +++ b/input/checkboxes.js @@ -0,0 +1,137 @@ +// SPDX-FileCopyrightText: 2021 M. Shulhan <ms@kilabit.info> +// SPDX-License-Identifier: GPL-3.0-or-later +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 { + constructor(opts) { + this.opts = opts; + this.values = []; + 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(); + } + } + generateLabel(wrapper) { + this.elLabel = document.createElement("label"); + this.elLabel.classList.add(WUI_INPUT_CHECKBOXES_CLASS_LABEL); + this.elLabel.innerHTML = `${this.opts.label} `; + wrapper.appendChild(this.elLabel); + } + generateInput(wrapper) { + this.el_fieldset = document.createElement("fieldset"); + this.el_fieldset.classList.add(WUI_INPUT_CHECKBOXES_CLASS_INPUT); + Object.entries(this.opts.options).forEach(([key, option]) => { + const value = option.value; + const wrapper = document.createElement("div"); + const elCb = document.createElement("input"); + elCb.type = "checkbox"; + elCb.name = this.opts.name; + elCb.value = option.value; + if (option.selected) { + elCb.checked = true; + this.values.push(value); + } + elCb.onclick = () => { + this.onClickCheckbox(elCb.value, elCb.checked); + }; + wrapper.appendChild(elCb); + const elLabel = document.createElement("label"); + elLabel.innerHTML = key; + wrapper.appendChild(elLabel); + this.el_fieldset.appendChild(wrapper); + }); + if (this.opts.is_disabled) { + this.el_fieldset.disabled = true; + } + wrapper.appendChild(this.el_fieldset); + } + generateHintToggler(wrapper) { + 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); + } + generateHint() { + this.el_hint = document.createElement("div"); + this.el_hint.classList.add(WUI_INPUT_CHECKBOXES_CLASS_HINT); + this.el_hint.innerHTML = this.opts.hint || ""; + if (this.opts.is_hint_toggled) { + this.el_hint.style.display = "block"; + } + else { + this.el_hint.style.display = "none"; + } + this.el_hint.style.borderRadius = "2px"; + this.el_hint.style.padding = "4px"; + this.el_hint.style.marginTop = "2px"; + this.el.appendChild(this.el_hint); + } + onClickHintToggler() { + if (this.el_hint.style.display === "none") { + this.el_hint.style.display = "block"; + } + else { + this.el_hint.style.display = "none"; + } + } + onClickCheckbox(value, selected) { + 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); + } + } +} |
