Published
Edited
Dec 9, 2021
1 fork
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
builder = ({ source } = {}) => {
const ui = view`
${["elements", [], (value) => Inputs.range([0, 1], { value: value })]}
<div style="display: flex;">
${Inputs.button("add", {
reduce: () => ui.value.elements.push(Math.random())
})}
${Inputs.button("remove", {
reduce: () => ui.value.elements.pop()
})}
</div>
`;

if (source) {
ui.value = source.value;
source.addEventListener("input", () => {
source.value.elements.forEach((v, i) => {
// Bug fix for twitchy events, you must not set the target if its the corrent value already
// In the case of the target changing, the is avoid the source setting the target after being changed itself
if (ui.value.elements[i] != v) ui.value.elements[i] = v;
});
ui.value.elements.splice(
// Deal with the case someone deleted an element
source.value.elements.length,
ui.value.elements.length - source.value.elements.length
);
});
ui.addEventListener("input", () => {
ui.value.elements.forEach((v, i) => {
source.value.elements[i] = v; // Straight assignment to source
});
source.value.elements.splice(
// Deal with the case someone deleted an element
ui.value.elements.length,
source.value.elements.length - ui.value.elements.length
);
// Retrigger source when target changes
// Same asymetric operation as Inputs.bind
source.dispatchEvent(new Event("input", { bubbles: true }));
});
}

return ui;
}
Insert cell
viewof target = builder({
source: viewof values
})
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