Public
Edited
Nov 1, 2023
Importers
Insert cell
Insert cell
Insert cell
viewof state = Inputs.input(getHashState())
Insert cell
Insert cell
state
Insert cell
Insert cell
bindToState(Inputs.range([0, 100], { step: 1 }), viewof state, "slider")
Insert cell
bindToState(Inputs.range([0, 100], { step: 1 }), viewof state, "slider")
Insert cell
bindToState(Inputs.range([0, 100], { step: 1 }), viewof state, "slider2")
Insert cell
Generators.input(viewof state)
Insert cell
bindToState(
Inputs.button("X", {
reduce: () => false
}),
viewof state,
"showFilters"
)
Insert cell
bindToState(
Inputs.button(`${state.showFilters ? "Hide" : "Show"} Filters`, {
reduce: (value) => !value
}),
viewof state,
"showFilters"
)
Insert cell
bindToState(Inputs.text(), viewof state, "name")
Insert cell
{
let div = htl.html`<div id="myDiv"></div>`;
let range1 = bindToState(
Inputs.range([0, 100], { step: 1 }),
viewof state,
"slider"
);
let range2 = bindToState(
Inputs.range([0, 100], { step: 1 }),
viewof state,
"slider2"
);
div.append(range1);
div.append(range2);
return div;
}
Insert cell
Insert cell
hash = Generators.observe((notify) => {
const hashchange = () => notify(location.hash);
hashchange();
addEventListener("hashchange", hashchange);
return () => removeEventListener("hashchange", hashchange);
})
Insert cell
{
hash;
const date = new Date();
return md`[Bookmark to State](#${serialize(state)})`;
}
Insert cell
### URL Hash helper functions
Insert cell
serialize = function (obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
Insert cell
function paramsToObject(entries) {
const result = {};
for (const [key, value] of entries) {
// each 'entry' is a [key, value] tupple
result[key] = value;
}
return result;
}
Insert cell
getHashState = () => {
const urlParams = new URLSearchParams(hash.slice(1));
const entries = urlParams.entries();
return paramsToObject(entries);
}
Insert cell
bindToState = function (target, source, property) {
const sourceEvent = "input";
const onsource = () => (target.value = source.value[property]);
const ontarget = () => {
source.value[property] = target.value;
source.dispatchEvent(new Event("input", { bubbles: true }));
};
onsource();
target.addEventListener("input", ontarget);
source.addEventListener("input", onsource);
invalidation.then(() => source.removeEventListener("input", onsource));
return target;
}
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