Published unlisted
Edited
Aug 28, 2020
Insert cell
Insert cell
Insert cell
viewof p = autoSelect({
value:"",
title:"first",
options: firstopt
})
Insert cell
firstopt = ["one", "two"]
Insert cell
viewof q = autoSelect({
value:"",
title:"second",
options: secondopt
})
Insert cell
secondopt = ["three", "four"]
Insert cell
viewof r = autoSelect({
value:"",
title:"third (inline)",
options: ["five", "six"]
})
Insert cell
function autoSelect_alt(config = {}) {
const {
value,
title,
description,
disabled,
autocomplete = "off",
placeholder,
size,
options,
list = "options"
} = Array.isArray(config) ? { options: config } : config;

const optionsSet = new Set(options);

const form = input({
type: "text",
title,
description,
attributes: { disabled },
action: fm => {
fm.value = fm.input.value = value || "";
fm.onsubmit = e => e.preventDefault();
fm.input.oninput = function(e) {
e.stopPropagation();
fm.value = fm.input.value;
if (!fm.value || optionsSet.has(fm.value))
fm.dispatchEvent(new CustomEvent("input"));
};
},
form: html`
<form>
<input name="input" type="text" autocomplete="off"
placeholder="${placeholder ||
""}" style="font-size: 1em;" list=${list}>
<datalist id="${list}">
${options.map(d =>
Object.assign(html`<option>`, {
value: d
})
)}
</datalist>
</form>
`
});

form.output.remove();
return form;
}
Insert cell
function input(config) {
let {
form,
type = "text",
attributes = {},
action,
getValue,
title,
description,
format,
display,
submit,
options
} = config;
const wrapper = html`<div></div>`;
if (!form)
form = html`<form>
<input name=input type=${type} />
</form>`;
Object.keys(attributes).forEach(key => {
const val = attributes[key];
if (val != null) form.input.setAttribute(key, val);
});
if (submit)
form.append(
html`<input name=submit type=submit style="margin: 0 0.75em" value="${
typeof submit == "string" ? submit : "Submit"
}" />`
);
form.append(
html`<output name=output style="font: 14px Menlo, Consolas, monospace; margin-left: 0.5em;"></output>`
);
if (title)
form.prepend(
html`<div style="font: 700 0.9rem sans-serif; margin-bottom: 3px;">${title}</div>`
);
if (description)
form.append(
html`<div style="font-size: 0.85rem; font-style: italic; margin-top: 3px;">${description}</div>`
);
if (format)
format = typeof format === "function" ? format : d3format.format(format);
if (action) {
action(form);
} else {
const verb = submit
? "onsubmit"
: type == "button"
? "onclick"
: type == "checkbox" || type == "radio"
? "onchange"
: "oninput";
form[verb] = e => {
e && e.preventDefault();
const value = getValue ? getValue(form.input) : form.input.value;
if (form.output) {
const out = display ? display(value) : format ? format(value) : value;
if (out instanceof window.Element) {
while (form.output.hasChildNodes()) {
form.output.removeChild(form.output.lastChild);
}
form.output.append(out);
} else {
form.output.value = out;
}
}
form.value = value;
if (verb !== "oninput")
form.dispatchEvent(new CustomEvent("input", { bubbles: true }));
};
if (verb !== "oninput")
wrapper.oninput = e => e && e.stopPropagation() && e.preventDefault();
if (verb !== "onsubmit") form.onsubmit = e => e && e.preventDefault();
form[verb]();
}
while (form.childNodes.length) {
wrapper.appendChild(form.childNodes[0]);
}
form.append(wrapper);
return form;
}
Insert cell
d3format = require("d3-format@1")
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