Skip to content

Filtering

Pantanal Grid provides powerful filtering capabilities with multiple operators and filter modes.

Filter Row

Filter inputs appear directly in the header row. The grid automatically uses appropriate input types based on column data type.

ID
Product Name
Unit Price
Units In Stock
Category
1
Chai
$ 18.00
39
Beverages
2
Chang
$ 17.00
40
Beverages
3
Aniseed Syrup
$ 10.00
13
Condiments
4
Chef Anton's Cajun Seasoning
$ 22.00
53
Condiments
5
Chef Anton's Gumbo Mix
$ 21.35
0
Condiments
6
Grandma's Boysenberry Spread
$ 25.00
120
Confections

Advanced Filter (Different Types)

Filter row with support for different input types: text, number, date, and boolean.

Order ID
Customer
Order Date
Freight
Shipped
1
John Doe
1/15/2024
$ 32.38
Yes
2
Jane Smith
1/20/2024
$ 11.61
No
3
Bob Johnson
2/1/2024
$ 65.83
Yes
4
Alice Brown
2/10/2024
$ 41.34
Yes

Custom Filter Options

Use custom filter options with dropdown selects. Boolean filters are automatically translated.

ID
Name
Status
Category
1
Product A
active
electronics
2
Product B
inactive
electronics
3
Product C
active
clothing
4
Product D
pending
food

Filter Row Mode

Use the filter inputs in the header row to filter data. Try filtering by name, price, or category.

ID
Product Name
Price
Category
Stock
1
Product A
29.99
Electronics
150
2
Product B
49.99
Clothing
75
3
Product C
19.99
Accessories
200
4
Product D
39.99
Electronics
50
5
Product E
59.99
Clothing
100
6
Product F
24.99
Accessories
300
7
Product G
69.99
Electronics
25
8
Product H
34.99
Clothing
120

Display filter inputs directly in the header row:

vue
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef, type FilterDescriptor } from '@pantanal/grid'

const rows = ref([/* ... */])
const columns: ColumnDef[] = [
  { 
    field: 'name', 
    title: 'Name', 
    filterable: true,
    filterableMode: 'row'
  },
  { 
    field: 'price', 
    title: 'Price', 
    filterable: true,
    filterableMode: 'row'
  }
]

const filter = ref<FilterDescriptor[]>([])
</script>

<template>
  <PantanalGrid
    :rows="rows"
    :columns="columns"
    key-field="id"
    v-model:filter="filter"
  />
</template>

Filter Menu Mode

Use a dropdown menu for filtering:

vue
<script setup lang="ts">
const columns: ColumnDef[] = [
  { 
    field: 'name', 
    title: 'Name', 
    filterable: true,
    filterableMode: 'menu'
  }
]
</script>

Filter Operators

Available operators:

  • contains - Contains text (default for strings)
  • eq - Equals
  • neq - Not equals
  • gt - Greater than
  • gte - Greater than or equal
  • lt - Less than
  • lte - Less than or equal
  • startswith - Starts with
  • endswith - Ends with
  • isnull - Is null
  • isnotnull - Is not null
  • isempty - Is empty
  • isnotempty - Is not empty

Custom Filter UI

Provide a custom filter UI:

vue
<script setup lang="ts">
const columns: ColumnDef[] = [
  {
    field: 'category',
    title: 'Category',
    filterable: true,
    filterableUI: 'dropdown',
    filterableOptions: [
      { value: 'Electronics', label: 'Electronics' },
      { value: 'Clothing', label: 'Clothing' },
      { value: 'Accessories', label: 'Accessories' }
    ]
  }
]
</script>

Multiple Filters

Enable multiple filter criteria:

vue
<script setup lang="ts">
const columns: ColumnDef[] = [
  {
    field: 'price',
    title: 'Price',
    filterable: true,
    filterableMulti: true,
    filterableExtra: true
  }
]
</script>

Filter Events

Listen to filter changes:

vue
<template>
  <PantanalGrid
    :rows="rows"
    :columns="columns"
    key-field="id"
    @update:filter="handleFilterChange"
    @filter="handleFilter"
  />
</template>

<script setup lang="ts">
function handleFilterChange(newFilter: FilterDescriptor[]) {
  console.log('Filter changed:', newFilter)
}

function handleFilter(event: { filter: FilterDescriptor[] }) {
  console.log('Filter event:', event.filter)
}
</script>

Filter Descriptor

The filter descriptor has the following structure:

typescript
interface FilterDescriptor {
  field: string           // Column field name
  operator: string        // Filter operator (contains, eq, gt, etc.)
  value: any              // Filter value
}

Filter Operators

Available filter operators:

  • String operators: contains, eq, neq, startswith, endswith, isnull, isnotnull, isempty, isnotempty
  • Number operators: eq, neq, gt, gte, lt, lte
  • Date operators: eq, neq, gt, gte, lt, lte
  • Boolean operators: eq, neq

Default Filter Operator

Set a default operator for a column:

vue
const columns: ColumnDef[] = [
  { 
    field: 'price', 
    title: 'Price', 
    filterable: true,
    filterableDefaultOperator: 'gte'  // Greater than or equal
  }
]

Filter UI Types

Text Input (Default)

vue
const columns: ColumnDef[] = [
  { field: 'name', title: 'Name', filterable: true }
]
vue
const columns: ColumnDef[] = [
  { 
    field: 'status', 
    title: 'Status', 
    filterable: true,
    filterableUI: 'dropdown',
    filterableOptions: [
      { value: 'active', label: 'Active' },
      { value: 'inactive', label: 'Inactive' }
    ]
  }
]

Date Picker

vue
const columns: ColumnDef[] = [
  { 
    field: 'date', 
    title: 'Date', 
    filterable: true,
    type: 'date'
  }
]

Server-Side Filtering

For server-side filtering, send filter descriptors to your API:

vue
<script setup lang="ts">
watchEffect(async () => {
  const params = new URLSearchParams({
    page: String(page.value),
    pageSize: String(pageSize.value)
  })
  
  if (filter.value.length > 0) {
    filter.value.forEach(f => {
      params.append(`filter[${f.field}][${f.operator}]`, String(f.value))
    })
  }
  
  const response = await fetch(`/api/data?${params}`)
  // ...
})
</script>

See Also