Observable Framework 1.0.0 GitHub

JavaScript: Inputs

Inputs are graphical user interface elements such as dropdowns, radios, sliders, and text boxes that accept data from a user and enable interaction via reactivity. They can also be custom elements that you design, such as charts that support interactive selection via pointing or brushing.

Inputs might prompt a viewer to:

Inputs are typically displayed using the built-in view function, which displays the given element and returns a value generator. The generator can then be declared as a top-level variable to expose the input’s value to the page. For example, the radio input below prompts the user to select their favorite team:

const team = view(Inputs.radio(["Metropolis Meteors", "Rockford Peaches", "Bears"], {label: "Favorite team:", value: "Metropolis Meteors"}));

The team variable here will reactively update when the user interacts with the radio input, triggering re-evaluation of referencing code blocks. Select different teams in the radio input above to update the text.

My favorite baseball team is the !

My favorite baseball team is the ${team}!

You can implement custom inputs using arbitrary HTML. For example, here is a range input that lets you choose an integer between 1 and 15 (inclusive):

const n = view(html`<input type=range step=1 min=1 max=15>`);
n // Try dragging the slider above
To be compatible with view, custom inputs must emit input events and expose their current value as element.value. See Generators.input for more.

More often, you’ll use a helper library such as Observable Inputs or Observable Plot to declare inputs. For example, here is Inputs.range:

const m = view(Inputs.range([1, 15], {label: "Favorite number", step: 1}));
m // Try dragging the slider above

To use a chart as an input, you can use Plot’s pointer interaction, say by setting the tip option on a mark. In the scatterplot below, the penguin closest to the pointer is exposed as the reactive variable penguin.

const penguin = view(Plot.dot(penguins, {x: "culmen_length_mm", y: "flipper_length_mm", tip: true}).plot());
penguin

In the future, Plot will support more interaction methods, including brushing. Please upvote #5 if you are interested in this feature.

view(element)

The view function used above does two things:

  1. it displays the given DOM element, and then
  2. returns its corresponding value generator.

The view function uses Generators.input under the hood. You can also call Generators.input directly, say to declare the input as a top-level variable without immediately displaying it:

const nameInput = html`<input type="text" placeholder="anonymous">`;
const name = Generators.input(nameInput);

As a top-level variable, you can then display the input anywhere you like, such as within a card using an inline expression. And you can reference the input’s value reactively anywhere, too.

Enter your name:
Hi !
<div class="card" style="display: grid; gap: 0.5rem;">
  <div>Enter your name: ${nameInput}</div>
  <div>Hi <b>${name || "anonymous"}</b>!</div>
</div>