FACE - radio button example
by int32_t
HTML
<form action="https://httpbin.org/post" method=post target=_new>
<fieldset>
<label><my-radio name=foo value="r1" tabindex=0></my-radio> Label 1</label>
<label><my-radio name=foo value="r2" tabindex=0></my-radio> Label 2</label>
<label><my-radio name=foo value="r3" tabindex=0 required></my-radio> Label 3</label>
</fieldset>
<input type=submit>
</form>
<pre></pre>
CSS
my-radio:invalid {
background-color: #f88;
}
my-radio:disabled {
background: gray;
}
my-radio {
display: inline-block;
width: 24px;
height: 24px;
}
JavaScript
function log(str) {
document.querySelector('pre').textContent += str + '\n';
}
class MyControl extends HTMLElement {
static get formAssociated() { return true; }
static get observedAttributes() { return ['name', 'required']; }
constructor() {
super();
this.internals_ = this.attachInternals();
this.checked = false;
this.addEventListener('click', this.onClick_.bind(this));
}
get form() { return this.internals_.form; }
get name() { return this.getAttribute('name'); }
get type() { return this.localName; }
get value() { return this.getAttribute('value'); }
checkValidity() {
return this.internals_.checkValidity();
}
// This is called by UA.
// FIXME: Should rename this.
formStateRestoreCallback(state, mode) {
this.checked = state == 'on';
}
get checked() { return this.checked_; }
set checked(flag) {
this.checked_ = flag;
if (flag) {
let value = this.getAttribute('value');
this.internals_.setFormValue(value ? value : 'on', 'on');
} else {
this.internals_.setFormValue(null, 'off');
}
if (this.isConnected)
this.updateView_();
if (flag)
this.uncheckOtherGroupMembers_();
}
attributeChangedCallback(attrName, oldValue, newValue) {
if (attrName == 'required')
this.updateValidityOfGroupMembers_(this.internals_.form, this.name);
else if (attrName == 'name') {
this.updateValidityOfGroupMembers_(this.internals_.form, oldValue);
this.updateValidityOfGroupMembers_(this.internals_.form, newValue);
}
}
connectedCallback() {
this.updateView_();
}
formAssociatedCallback(nullableForm) {
if (this.checked)
this.uncheckOtherGroupMembers_();
this.updateValidityOfGroupMembers_(this.form_, this.name);
this.updateValidityOfGroupMembers_(nullableForm, this.name);
this.form_ = nullableForm;
}
updateView_() {
this.textContent = this.checked ? '\u{1F518}' : '\u26AA';
if...