observablehq / inputs

Better input elements
https://observablehq.com/framework/lib/inputs
ISC License
125 stars 34 forks source link

Is it possible to have multiple filters linked together #233

Closed novotny1akub closed 2 years ago

novotny1akub commented 2 years ago

Is it possible to update the options in a filter based on the selection made in another filter? In the example picture below, there is the name filter filtering based on a car name. Once the "car2" has been selected, the options in the filter filtering number of cylinders has been updated showing the option "2" greyed out because of the selection in the other filter. Is something like that possible with observablehq inputs?

image

enjalot commented 2 years ago

yes, you can use the disabled property to set disabled values, here is an example with the cars dataset: https://observablehq.com/d/97e99dde46096bf5

see the Select API reference too: https://github.com/observablehq/inputs/blob/main/README.md#select

novotny1akub commented 2 years ago

I am not sure how I can update the disabled property based on a selection made in another filter. Below is an example code. How can I update the cyl_filter based on a selection made in the name_filter? Perhaps it is obvious, but when I tried to do it, it gave me "circular reference" error.

d3 = require("d3@6")

// dummy data
cars = d3.csvParse(`name,cyl,mpg
car1,2,21.4
car2,4,18
car2,6,54
car3,2,18.6
`)

// filter for the car name
viewof name_filter = Inputs.select(
  cars.map(d => d.name),
  {value: [...new Set(cars.map(d => d.name))],
  label: "Car Name", multiple: true, sort: true, unique: true}
  )

// filter for the number of cylinders
viewof cyl_filter = Inputs.select(
  cars.map(d => d.cyl),
  {value: [...new Set(cars.map(d => d.cyl))],
  label: "Number of Cylinders", multiple: true, sort: true, unique: true}
  )

// applying the filters above
cars_filtered = cars.filter(d => name_filter.indexOf(d.name) >= 0 && cyl_filter.indexOf(d.cyl) >= 0)

Inputs.table(cars_filtered)