Add: make setupLivePrefs work with radio

This commit is contained in:
eight 2019-06-26 09:15:47 +08:00
parent 0fc73b5f8c
commit c5ba22ffed

View File

@ -407,29 +407,35 @@ function setupLivePrefs(
.filter(id => $('#' + id)) .filter(id => $('#' + id))
) { ) {
for (const id of IDs) { for (const id of IDs) {
const element = $('#' + id); const elements = [$('#' + id), ...$$(`[name=${id}]`)];
updateElement({id, element, force: true}); for (const element of elements) {
element.addEventListener('change', onChange); updateElement({id, elements: [element], force: true});
element.addEventListener('change', onChange);
}
} }
prefs.subscribe(IDs, (id, value) => updateElement({id, value})); prefs.subscribe(IDs, (id, value) => updateElement({id, value}));
function onChange() { function onChange() {
const key = this.id || this.name;
const value = getInputValue(this); const value = getInputValue(this);
if (prefs.get(this.id) !== value) { if (value !== undefined && prefs.get(key) !== value) {
prefs.set(this.id, value); prefs.set(key, value);
} }
} }
function updateElement({ function updateElement({
id, id,
value = prefs.get(id), value = prefs.get(id),
element = $('#' + id), elements = [$('#' + id), ...$$(`[name=${id}]`)],
force, force,
}) { }) {
if (!element) { // FIXME: this has no effect. `updateElement` is not a listener
prefs.unsubscribe(IDs, updateElement); // if (!element) {
return; // prefs.unsubscribe(IDs, updateElement);
// return;
// }
for (const element of elements) {
setInputValue(element, value, force);
} }
setInputValue(element, value, force);
} }
function getInputValue(input) { function getInputValue(input) {
if (input.type === 'checkbox') { if (input.type === 'checkbox') {
@ -438,15 +444,24 @@ function setupLivePrefs(
if (input.type === 'number') { if (input.type === 'number') {
return Number(input.value); return Number(input.value);
} }
if (input.type === 'radio' && !input.checked) {
return undefined;
}
return input.value; return input.value;
} }
function setInputValue(input, value, force = false) { function setInputValue(input, value, force = false) {
if (force || getInputValue(input) !== value) { let oldValue, newValue;
if (input.type === 'checkbox') { if (input.type === 'radio') {
input.checked = value; oldValue = input.checked;
} else { newValue = input.checked = value === input.value;
input.value = value; } else if (input.type === 'checkbox') {
} oldValue = input.checked;
newValue = input.checked = value;
} else {
oldValue = input.value;
newValue = input.value = value;
}
if (force || oldValue !== newValue) {
input.dispatchEvent(new Event('change', {bubbles: true, cancelable: true})); input.dispatchEvent(new Event('change', {bubbles: true, cancelable: true}));
} }
} }