Skip to content

Search & Filter

Build a faceted search interface with multiple filter widgets that update a listing in real time.

Database Table

Assume a properties table (real estate listings):

ColumnType
idint
titlevarchar
descriptiontext
pricedecimal
bedroomsint
property_typevarchar
cityvarchar
image_urlvarchar

UI Layout

Container (flex, row, gap: 24px)
  ├── Container (width: 280px)          ← Sidebar
  │   ├── Heading ("Filters")
  │   ├── Search Filter (target: "listing", field: "title")
  │   ├── Dropdown Filter (target: "listing", field: "property_type",
  │   │     options: ["House", "Apartment", "Condo", "Townhouse"])
  │   ├── Checkbox Filter (target: "listing", field: "city",
  │   │     options: ["New York", "Los Angeles", "Chicago", "Houston"])
  │   └── Range Filter (target: "listing", field: "price",
  │         min: 0, max: 1000000, step: 10000)
  └── Container (flex: 1)              ← Main Content
      ├── Heading ("Properties")
      └── Listing Grid (id: "listing", dataSource: properties pipeline)
          └── Card
              ├── Image (src: "`{ {row.image_url}}`")
              ├── Heading ("`{ {row.title}}`")
              ├── Text ("`{ {row.property_type}}` | `{ {row.bedrooms}}` bed")
              ├── Text ("`{ {row.city}}`")
              └── Text ("$`{ {number_format(row.price, 0)}}`")

How Filter Widgets Work

Filter widgets are linked to a Listing Grid (or Repeater) by a target ID. When a user interacts with a filter, it sends the filter parameters to the listing's data source pipeline, which re-executes with the new filters applied.

Search Filter (Text)

Performs a text search on the specified field:

target: "listing"
field: "title"
placeholder: "Search properties..."

The search value is passed to the pipeline as a whereField/whereValue parameter.

Filters by a single selected value:

target: "listing"
field: "property_type"
options: ["House", "Apartment", "Condo", "Townhouse"]

Checkbox Filter

Filters by one or more selected values:

target: "listing"
field: "city"
options: ["New York", "Los Angeles", "Chicago", "Houston"]

When multiple checkboxes are selected, rows matching any selected value are included.

Range Filter

Filters by a numeric range:

target: "listing"
field: "price"
min: 0
max: 1000000
step: 10000
label: "Price Range"

Data Source Pipeline

Table Query (properties, orderBy: "created_at", order: "DESC")
  → Result

The filter widgets modify the query parameters dynamically. When a user selects a filter, the pipeline re-executes with the additional WHERE clauses.

Responsive Layout

PropertyDesktopMobile
Sidebar width280px100%
Container flexDirectionrowcolumn

On mobile, the sidebar stacks above the listing.

Variations

Add sorting

Add a Dropdown Filter configured as a sort selector:

target: "listing"
sortField: true
options: ["Price: Low to High", "Price: High to Low", "Newest"]

Add bedroom filter

Add a Dropdown Filter:

target: "listing"
field: "bedrooms"
options: ["1", "2", "3", "4", "5+"]

Combine with an Address Input widget and the Distance Filter pipeline node:

Table Query → Distance Filter (center from address input) → Result

Show result count

Display the number of matching results:

`{ {count(row)}}` properties found

No results message

Add a Text widget with visibility rule:

count(row) == 0

Text: "No properties match your filters. Try adjusting your search criteria."

TIP

Filter widgets work best with the Listing Grid widget, which handles pagination and loading states automatically. You can also use them with a plain Repeater, but you will need to handle pagination manually.