191 lines
5.3 KiB
JavaScript
191 lines
5.3 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
// On/off toggle checkbox
|
||
|
Toolkit.CheckBox = class CheckBox extends Toolkit.Panel {
|
||
|
|
||
|
// Object constructor
|
||
|
constructor(application, options) {
|
||
|
super(application, options);
|
||
|
options = options || {};
|
||
|
|
||
|
// Configure instance fields
|
||
|
this.changeListeners = [];
|
||
|
this.checked = false;
|
||
|
this.enabled = "enabled" in options ? !!options.enabled : true;
|
||
|
this.text = options.text || "";
|
||
|
|
||
|
// Configure element
|
||
|
this.setLayout("grid", {
|
||
|
columns : "max-content max-content"
|
||
|
});
|
||
|
this.setDisplay("inline-grid");
|
||
|
this.setHollow(false);
|
||
|
this.setOverflow("visible", "visible");
|
||
|
this.element.setAttribute("tabindex", "0");
|
||
|
this.element.setAttribute("role", "checkbox");
|
||
|
this.element.setAttribute("aria-checked", "false");
|
||
|
this.element.style.alignItems = "center";
|
||
|
this.element.addEventListener("keydown" , e=>this.onkeydown (e));
|
||
|
this.element.addEventListener("pointerdown", e=>this.onpointerdown(e));
|
||
|
this.element.addEventListener("pointermove", e=>this.onpointermove(e));
|
||
|
this.element.addEventListener("pointerup" , e=>this.onpointerup (e));
|
||
|
|
||
|
// Configure check box
|
||
|
this.check = this.add(this.newLabel());
|
||
|
this.check.element.setAttribute("name", "check");
|
||
|
this.check.element.setAttribute("aria-hidden", "true");
|
||
|
|
||
|
// Configure label
|
||
|
this.label = this.add(this.newLabel({ localized: true }));
|
||
|
this.label.element.setAttribute("name", "label");
|
||
|
this.element.setAttribute("aria-labelledby", this.label.id);
|
||
|
|
||
|
// Configure properties
|
||
|
this.setChecked(options.checked);
|
||
|
this.setEnabled(this.enabled);
|
||
|
this.setText (this.text );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////// Public Methods //////////////////////////////
|
||
|
|
||
|
// Add a callback for change events
|
||
|
addChangeListener(listener) {
|
||
|
if (this.changeListeners.indexOf(listener) == -1)
|
||
|
this.changeListeners.push(listener);
|
||
|
}
|
||
|
|
||
|
// Request focus on the appropriate element
|
||
|
focus() {
|
||
|
this.element.focus();
|
||
|
}
|
||
|
|
||
|
// Determine whether the component is checked
|
||
|
isChecked() {
|
||
|
return this.checked;
|
||
|
}
|
||
|
|
||
|
// Determine whether the component is enabled
|
||
|
isEnabled() {
|
||
|
return this.enabled;
|
||
|
}
|
||
|
|
||
|
// Specify whether the component is checked
|
||
|
setChecked(checked, e) {
|
||
|
checked = !!checked;
|
||
|
if (checked == this.checked)
|
||
|
return;
|
||
|
this.checked = checked;
|
||
|
this.element.setAttribute("aria-checked", checked);
|
||
|
if (e === undefined)
|
||
|
return;
|
||
|
for (let listener of this.changeListeners)
|
||
|
listener(e);
|
||
|
}
|
||
|
|
||
|
// Specify whether the component is enabled
|
||
|
setEnabled(enabled) {
|
||
|
this.enabled = enabled = !!enabled;
|
||
|
this.element.setAttribute("aria-disabled", !enabled);
|
||
|
if (enabled)
|
||
|
this.element.setAttribute("tabindex", "0");
|
||
|
else this.element.removeAttribute("tabindex");
|
||
|
}
|
||
|
|
||
|
// Specify the component's display text
|
||
|
setText(text) {
|
||
|
this.text = text = text || "";
|
||
|
this.label.setText(text);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////// Private Methods /////////////////////////////
|
||
|
|
||
|
// Key down event handler
|
||
|
onkeydown(e) {
|
||
|
|
||
|
// Error checking
|
||
|
if (!this.enabled)
|
||
|
return;
|
||
|
|
||
|
// Ignore the key
|
||
|
if (e.key != " ")
|
||
|
return;
|
||
|
|
||
|
// Configure event
|
||
|
e.preventDefault();
|
||
|
e.stopPropagation();
|
||
|
|
||
|
// Toggle the checked state
|
||
|
this.setChecked(!this.checked, e);
|
||
|
}
|
||
|
|
||
|
// Pointer down event handler
|
||
|
onpointerdown(e) {
|
||
|
|
||
|
// Configure event
|
||
|
//e.preventDefault();
|
||
|
e.stopPropagation();
|
||
|
|
||
|
// Configure focus
|
||
|
if (this.enabled)
|
||
|
this.focus();
|
||
|
else return;
|
||
|
|
||
|
// Error checking
|
||
|
if (e.button != 0 || this.element.hasPointerCapture(e.captureId))
|
||
|
return;
|
||
|
|
||
|
// Configure element
|
||
|
this.element.setPointerCapture(e.pointerId);
|
||
|
this.element.setAttribute("active", "");
|
||
|
}
|
||
|
|
||
|
// Pointer move event handler
|
||
|
onpointermove(e) {
|
||
|
|
||
|
// Error checking
|
||
|
if (!this.element.hasPointerCapture(e))
|
||
|
return;
|
||
|
|
||
|
// Configure event
|
||
|
e.preventDefault();
|
||
|
e.stopPropagation();
|
||
|
|
||
|
// Working variables
|
||
|
let bounds = this.getBounds();
|
||
|
let active =
|
||
|
e.x >= bounds.x && e.x < bounds.x + bounds.width &&
|
||
|
e.y >= bounds.y && e.y < bounds.y + bounds.height
|
||
|
;
|
||
|
|
||
|
// Configure element
|
||
|
if (active)
|
||
|
this.element.setAttribute("active", "");
|
||
|
else this.element.removeAttribute("active");
|
||
|
}
|
||
|
|
||
|
// Pointer up event handler
|
||
|
onpointerup(e) {
|
||
|
|
||
|
// Configure event
|
||
|
e.stopPropagation();
|
||
|
|
||
|
// Error checking
|
||
|
if (!this.element.hasPointerCapture(e.pointerId))
|
||
|
return;
|
||
|
|
||
|
// Configure element
|
||
|
this.element.releasePointerCapture(e.pointerId);
|
||
|
|
||
|
// Activate the component if it is active
|
||
|
if (!this.element.hasAttribute("active"))
|
||
|
return;
|
||
|
this.element.removeAttribute("active");
|
||
|
this.setChecked(!this.checked, e);
|
||
|
}
|
||
|
|
||
|
};
|