aboutsummaryrefslogtreecommitdiff
path: root/input/checkboxes.js
diff options
context:
space:
mode:
Diffstat (limited to 'input/checkboxes.js')
-rw-r--r--input/checkboxes.js137
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 = " &#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);
+ }
+ 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);
+ }
+ }
+}