Published
Edited
Aug 17, 2022
Importers
Insert cell
Insert cell
function toInput(node, options) {
if (!hasValueProperty(node)) {
const { get, set } = Array.isArray(options)
? namedFields(...options)
: options || arrayFields();
let value = [];
Object.defineProperty(node, "value", {
get: () => get(getElementsWithValues(node)),
set: (value) => set(getElementsWithValues(node), value)
});
}
return node;
}
Insert cell
function namedFields(...fields) {
return {
get: (inputs) => {
return fields.reduce(
(result, field, idx) => (
(result[field] = (inputs[idx] || {}).value), result
),
{}
);
},
set: (inputs, values = {}) => {
fields.forEach(
(field, idx) => inputs[idx] && (inputs[idx].value = values[field])
);
}
};
}
Insert cell
function arrayFields() {
return {
get: (inputs) => {
const values = inputs.map((n) => n.value);
return values.length === 1 ? values[0] : values;
},
set: (inputs, values) => {
values = toArray(values);
for (let i = 0; i < Math.min(inputs.length, values.length); i++) {
inputs[i].value = values[i];
}
}
};
}
Insert cell
function getElementsWithValues(node) {
const list = [];
visitNodes(node, (n) => {
if (!hasValueProperty(n) || n === node) return true;
list.push(n);
return false;
});
return list;
}
Insert cell
function hasValueProperty(n) {
if (Object.hasOwn(n, "value")) return true;
return (
typeof n === "object" && Object.hasOwn(n.constructor.prototype, "value")
);
}
Insert cell
function visitNodes(node, callback) {
const r = callback(node);
if (r !== undefined && !r) return false;
for (let n = node.firstChild; n; n = n.nextSibling) {
visitNodes(n, callback);
}
return true;
}
Insert cell
function toArray(value) {
if (Array.isArray(value)) return [...value];
if (value === undefined) return [];
return [value];
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more