diff options
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); + } + } +} |
