Filter binding and placement
Bind, read, and display filters in a view or zone.
A filter declaration has no URL namespace until you bind it to a view or zone.
A view filter uses f[name]. A zone filter uses f[zone][name].
Use the same binding for two operations:
- Pass its owner to
ctx.parseto read typed values. - Pass it to
section.setFiltersorpanel.setFiltersto display controls.
View binding
Pass a filter bar through the view options. The resolver receives the binding
as view.state.filters.
import {
defineFilters,
defineResource,
filters,
section,
} from '@backlit/sdk'
const orders = defineResource('orders', [])
const orderFilters = defineFilters([
filters.text('search').setLabel('Search orders'),
])
orders.view(
'list',
{ filters: orderFilters },
(_ctx, view) =>
section('Orders').setFilters(view.state.filters)
)
export default orders{
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "orders",
"name": "list",
"slots": {
"content": [
{
"kind": "section",
"title": "Orders",
"slots": {
"content": [],
"filters": {
"kind": "filters",
"resource": "orders",
"view": "list",
"keyword": "f",
"definesResult": true,
"dependsOnResult": false,
"filters": [
{
"kind": "text",
"name": "search",
"label": "Search orders"
}
]
}
}
}
]
}
}
}Read view filters
Call ctx.parse(view).filters. The result has one typed property for
each declared filter. A missing or invalid value is undefined.
import {
callout,
defineFilters,
defineResource,
filters,
section,
} from '@backlit/sdk'
const orders = defineResource('orders', [])
const orderFilters = defineFilters([
filters.text('search').setLabel('Search orders'),
filters.toggle('paid').setLabel('Paid'),
])
orders.view(
'list',
{ filters: orderFilters },
(ctx, view) => {
const { search, paid } = ctx.parse(view).filters
return section('Orders')
.setFilters(view.state.filters)
.setContent([
callout(
`Search: ${search ?? 'all'}; paid: ${paid ?? 'all'}`
),
])
}
)
export default orders{
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "orders",
"name": "list",
"slots": {
"content": [
{
"kind": "section",
"title": "Orders",
"slots": {
"content": [
{
"kind": "callout",
"text": "Search: all; paid: all"
}
],
"filters": {
"kind": "filters",
"resource": "orders",
"view": "list",
"keyword": "f",
"definesResult": true,
"dependsOnResult": false,
"filters": [
{
"kind": "text",
"name": "search",
"label": "Search orders"
},
{
"kind": "toggle",
"name": "paid",
"label": "Paid"
}
]
}
}
}
]
}
}
}Zone binding
Pass a filter bar through the zone options. Place zone.state.filters inside the
zone. A control change then requests only that zone.
import {
defineFilters,
defineResource,
filters,
section,
table,
zone,
} from '@backlit/sdk'
const orders = defineResource('orders', [])
const activityFilters = defineFilters([
filters.text('search').setLabel('Search activity'),
])
orders.view('detail', () =>
zone(
'activity',
{ filters: activityFilters },
(_ctx, currentZone) =>
section('Activity')
.setFilters(currentZone.state.filters)
.setContent([table([]).setFields([])])
)
)
export default orders{
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "orders",
"name": "detail",
"slots": {
"content": [
{
"kind": "zone",
"name": "activity",
"resource": "orders",
"view": "detail",
"slots": {
"content": [
{
"kind": "section",
"title": "Activity",
"slots": {
"content": [
{
"kind": "table",
"fields": [],
"data": []
}
],
"filters": {
"kind": "filters",
"resource": "orders",
"view": "detail",
"zone": "activity",
"keyword": "f",
"definesResult": true,
"dependsOnResult": false,
"filters": [
{
"kind": "text",
"name": "search",
"label": "Search activity"
}
]
}
}
}
]
}
}
]
}
}
}Read zone filters
Call ctx.parse(zone).filters. Backlit reads values from that zone scope.
import {
callout,
defineFilters,
defineResource,
filters,
section,
zone,
} from '@backlit/sdk'
const orders = defineResource('orders', [])
const activityFilters = defineFilters([
filters.text('search').setLabel('Search activity'),
])
orders.view('detail', () =>
zone(
'activity',
{ filters: activityFilters },
(ctx, currentZone) => {
const { search } = ctx.parse(currentZone).filters
return section('Activity')
.setFilters(currentZone.state.filters)
.setContent([
callout(`Search: ${search ?? 'all activity'}`),
])
}
)
)
export default orders{
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "orders",
"name": "detail",
"slots": {
"content": [
{
"kind": "zone",
"name": "activity",
"resource": "orders",
"view": "detail",
"slots": {
"content": [
{
"kind": "section",
"title": "Activity",
"slots": {
"content": [
{
"kind": "callout",
"text": "Search: all activity"
}
],
"filters": {
"kind": "filters",
"resource": "orders",
"view": "detail",
"zone": "activity",
"keyword": "f",
"definesResult": true,
"dependsOnResult": false,
"filters": [
{
"kind": "text",
"name": "search",
"label": "Search activity"
}
]
}
}
}
]
}
}
]
}
}
}Place filters in a section
A filter bar is not a content block. A section has a separate slot for it.
import {
defineFilters,
defineResource,
filters,
section,
} from '@backlit/sdk'
const orders = defineResource('orders', [])
const orderFilters = defineFilters([
filters.text('search').setLabel('Search orders'),
])
orders.view(
'list',
{ filters: orderFilters },
(_ctx, view) =>
section('Orders')
.setFilters(view.state.filters)
)
export default orders{
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "orders",
"name": "list",
"slots": {
"content": [
{
"kind": "section",
"title": "Orders",
"slots": {
"content": [],
"filters": {
"kind": "filters",
"resource": "orders",
"view": "list",
"keyword": "f",
"definesResult": true,
"dependsOnResult": false,
"filters": [
{
"kind": "text",
"name": "search",
"label": "Search orders"
}
]
}
}
}
]
}
}
}Place filters in a panel
A panel has the same separate filter slot.
import {
defineFilters,
defineResource,
filters,
panel,
} from '@backlit/sdk'
const orders = defineResource('orders', [])
const orderFilters = defineFilters([
filters.text('search').setLabel('Search orders'),
])
orders.view(
'list',
{ filters: orderFilters },
(_ctx, view) =>
panel([])
.setTitle('Orders')
.setFilters(view.state.filters)
)
export default orders{
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "orders",
"name": "list",
"slots": {
"content": [
{
"kind": "panel",
"title": "Orders",
"slots": {
"content": [],
"filters": {
"kind": "filters",
"resource": "orders",
"view": "list",
"keyword": "f",
"definesResult": true,
"dependsOnResult": false,
"filters": [
{
"kind": "text",
"name": "search",
"label": "Search orders"
}
]
}
}
}
]
}
}
}