Documentation
Quick Filter
Search across columns with one controlled input. Use simple contains matching or smart operators.
Bind a search input
Pass a controlled quickFilter.text. Default mode is simple contains matching across searchable columns.
React TSX
Copy
const [searchText, setSearchText] = useState("");<input value={searchText} onChange={(e) => setSearchText(e.target.value)} /><SimpleTablecolumns={columns}rows={rows}quickFilter={{ text: searchText, mode: "simple" }}/>
Vue SFC
Copy
<script setup>import { ref } from "vue";const searchText = ref("");</script><template><input v-model="searchText" /><SimpleTable:columns="columns":rows="rows":quick-filter="{ text: searchText, mode: 'simple' }"/></template>
Angular
Copy
searchText = "";<input [(ngModel)]="searchText" /><simple-table[columns]="columns"[rows]="rows"[quickFilter]="{ text: searchText, mode: 'simple' }"></simple-table>
Svelte
Copy
<script>let searchText = $state("");</script><input bind:value={searchText} /><SimpleTable{columns}{rows}quickFilter={{ text: searchText, mode: "simple" }}/>
Solid TSX
Copy
const [searchText, setSearchText] = createSignal("");<inputvalue={searchText()}onInput={(e) => setSearchText(e.currentTarget.value)}/><SimpleTablecolumns={columns}rows={rows()}quickFilter={{ text: searchText(), mode: "simple" }}/>
TypeScript
Copy
let searchText = "";const table = new SimpleTableVanilla(container, {columns,rows,quickFilter: { text: searchText, mode: "simple" },});input.addEventListener("input", (e) => {searchText = e.target.value;table.update({ quickFilter: { text: searchText, mode: "simple" } });});
Smart mode
Set mode: "smart" for multi-word AND, quoted phrases, -negation, and column:value.
React TSX
Copy
const [searchText, setSearchText] = useState("");<input value={searchText} onChange={(e) => setSearchText(e.target.value)} /><SimpleTablecolumns={columns}rows={rows}quickFilter={{ text: searchText, mode: "smart" }}/>
Vue SFC
Copy
<script setup>import { ref } from "vue";const searchText = ref("");</script><template><input v-model="searchText" /><SimpleTable:columns="columns":rows="rows":quick-filter="{ text: searchText, mode: 'smart' }"/></template>
Angular
Copy
searchText = "";<input [(ngModel)]="searchText" /><simple-table[columns]="columns"[rows]="rows"[quickFilter]="{ text: searchText, mode: 'smart' }"></simple-table>
Svelte
Copy
<script>let searchText = $state("");</script><input bind:value={searchText} /><SimpleTable{columns}{rows}quickFilter={{ text: searchText, mode: "smart" }}/>
Solid TSX
Copy
const [searchText, setSearchText] = createSignal("");<inputvalue={searchText()}onInput={(e) => setSearchText(e.currentTarget.value)}/><SimpleTablecolumns={columns}rows={rows()}quickFilter={{ text: searchText(), mode: "smart" }}/>
TypeScript
Copy
let searchText = "";const table = new SimpleTableVanilla(container, {columns,rows,quickFilter: { text: searchText, mode: "smart" },});input.addEventListener("input", (e) => {searchText = e.target.value;table.update({ quickFilter: { text: searchText, mode: "smart" } });});
Limit searchable columns
Use quickFilter.columns or set quickFilterable: false on a column.
TypeScript
Copy
// Limit via configquickFilter={{ text: searchText, columns: ["name", "email"] }}// Or exclude a column{ accessor: "id", label: "ID", quickFilterable: false }
TypeScript
Copy
// Limit via configquickFilter={{ text: searchText, columns: ["name", "email"] }}// Or exclude a column{ accessor: "id", label: "ID", quickFilterable: false }
TypeScript
Copy
// Limit via configquickFilter={{ text: searchText, columns: ["name", "email"] }}// Or exclude a column{ accessor: "id", label: "ID", quickFilterable: false }
TypeScript
Copy
// Limit via configquickFilter={{ text: searchText, columns: ["name", "email"] }}// Or exclude a column{ accessor: "id", label: "ID", quickFilterable: false }
TypeScript
Copy
// Limit via configquickFilter={{ text: searchText, columns: ["name", "email"] }}// Or exclude a column{ accessor: "id", label: "ID", quickFilterable: false }
TypeScript
Copy
// Limit via configquickFilter={{ text: searchText, columns: ["name", "email"] }}// Or exclude a column{ accessor: "id", label: "ID", quickFilterable: false }
Custom searchable value
Use quickFilterGetter when the searchable string differs from the cell value.
TypeScript
Copy
{accessor: "user",label: "User",quickFilterGetter: ({ row }) => row.user?.fullName ?? "",}
TypeScript
Copy
{accessor: "user",label: "User",quickFilterGetter: ({ row }) => row.user?.fullName ?? "",}
TypeScript
Copy
{accessor: "user",label: "User",quickFilterGetter: ({ row }) => row.user?.fullName ?? "",}
TypeScript
Copy
{accessor: "user",label: "User",quickFilterGetter: ({ row }) => row.user?.fullName ?? "",}
TypeScript
Copy
{accessor: "user",label: "User",quickFilterGetter: ({ row }) => row.user?.fullName ?? "",}
TypeScript
Copy
{accessor: "user",label: "User",quickFilterGetter: ({ row }) => row.user?.fullName ?? "",}
Programmatic filter
Call setQuickFilter on the table API. See Programmatic Control.
React TSX
Copy
tableRef.current?.setQuickFilter("engineering");tableRef.current?.setQuickFilter(""); // clear
Vue SFC
Copy
tableRef.value?.setQuickFilter("engineering");tableRef.value?.setQuickFilter(""); // clear
Angular
Copy
this.tableRef.getAPI()?.setQuickFilter("engineering");this.tableRef.getAPI()?.setQuickFilter(""); // clear
Svelte
Copy
tableRef.getAPI()?.setQuickFilter("engineering");tableRef.getAPI()?.setQuickFilter(""); // clear
Solid TSX
Copy
tableRef.setQuickFilter("engineering");tableRef.setQuickFilter(""); // clear
TypeScript
Copy
table.setQuickFilter("engineering");table.setQuickFilter(""); // clear
Example
Try simple vs smart mode below. In smart mode, try engineering -inactive.
React TSX
Copy
1import { useState } from "react";2import {SimpleTable} from "@simple-table/react";import type { Theme, QuickFilterMode } from "@simple-table/react";3import { quickFilterConfig } from "./quick-filter.demo-data";4import "@simple-table/react/styles.css";56const QuickFilterDemo = ({7 height = "400px",8 theme,9}: {10 height?: string | number;11 theme?: Theme;12}) => {13 const [searchText, setSearchText] = useState("");14 const [filterMode, setFilterMode] = useState<QuickFilterMode>("simple");15 const [caseSensitive, setCaseSensitive] = useState(false);1617 return (18 <div>19 <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 12, alignItems: "center" }}>20 <input21 type="text"22 placeholder="Search..."23 value={searchText}24 onChange={(e) => setSearchText(e.target.value)}25 style={{26 padding: "6px 12px",27 borderRadius: 6,28 border: "1px solid #d1d5db",29 fontSize: 13,30 minWidth: 200,31 }}32 />33 <button34 onClick={() => setFilterMode("simple")}35 style={{36 padding: "6px 14px",37 borderRadius: 6,38 border: filterMode === "simple" ? "2px solid #3b82f6" : "1px solid #d1d5db",39 background: filterMode === "simple" ? "#eff6ff" : "#fff",40 color: filterMode === "simple" ? "#1d4ed8" : "#374151",41 fontWeight: filterMode === "simple" ? 600 : 400,42 cursor: "pointer",43 fontSize: 13,44 }}45 >46 Simple47 </button>48 <button49 onClick={() => setFilterMode("smart")}50 style={{51 padding: "6px 14px",52 borderRadius: 6,53 border: filterMode === "smart" ? "2px solid #3b82f6" : "1px solid #d1d5db",54 background: filterMode === "smart" ? "#eff6ff" : "#fff",55 color: filterMode === "smart" ? "#1d4ed8" : "#374151",56 fontWeight: filterMode === "smart" ? 600 : 400,57 cursor: "pointer",58 fontSize: 13,59 }}60 >61 Smart62 </button>63 <button64 onClick={() => setCaseSensitive((prev) => !prev)}65 style={{66 padding: "6px 14px",67 borderRadius: 6,68 border: caseSensitive ? "2px solid #3b82f6" : "1px solid #d1d5db",69 background: caseSensitive ? "#eff6ff" : "#fff",70 color: caseSensitive ? "#1d4ed8" : "#374151",71 fontWeight: caseSensitive ? 600 : 400,72 cursor: "pointer",73 fontSize: 13,74 }}75 >76 Case Sensitive77 </button>78 </div>79 <SimpleTable80 columns={quickFilterConfig.headers}81 rows={quickFilterConfig.rows}82 height={height}83 theme={theme}84 quickFilter={{ text: searchText, mode: filterMode, caseSensitive }}85 />86 </div>87 );88};8990export default QuickFilterDemo;
Vue SFC
Copy
1<template>2 <div>3 <div style="display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; align-items: center">4 <input5 type="text"6 placeholder="Search..."7 :value="searchText"8 @input="searchText = ($event.target as HTMLInputElement).value"9 style="padding: 6px 12px; border-radius: 6px; border: 1px solid #d1d5db; font-size: 13px; min-width: 200px"10 />11 <button12 @click="filterMode = 'simple'"13 :style="{14 padding: '6px 14px',15 borderRadius: '6px',16 border: filterMode === 'simple' ? '2px solid #3b82f6' : '1px solid #d1d5db',17 background: filterMode === 'simple' ? '#eff6ff' : '#fff',18 color: filterMode === 'simple' ? '#1d4ed8' : '#374151',19 fontWeight: filterMode === 'simple' ? 600 : 400,20 cursor: 'pointer',21 fontSize: '13px',22 }"23 >24 Simple25 </button>26 <button27 @click="filterMode = 'smart'"28 :style="{29 padding: '6px 14px',30 borderRadius: '6px',31 border: filterMode === 'smart' ? '2px solid #3b82f6' : '1px solid #d1d5db',32 background: filterMode === 'smart' ? '#eff6ff' : '#fff',33 color: filterMode === 'smart' ? '#1d4ed8' : '#374151',34 fontWeight: filterMode === 'smart' ? 600 : 400,35 cursor: 'pointer',36 fontSize: '13px',37 }"38 >39 Smart40 </button>41 <button42 @click="caseSensitive = !caseSensitive"43 :style="{44 padding: '6px 14px',45 borderRadius: '6px',46 border: caseSensitive ? '2px solid #3b82f6' : '1px solid #d1d5db',47 background: caseSensitive ? '#eff6ff' : '#fff',48 color: caseSensitive ? '#1d4ed8' : '#374151',49 fontWeight: caseSensitive ? 600 : 400,50 cursor: 'pointer',51 fontSize: '13px',52 }"53 >54 Case Sensitive55 </button>56 </div>57 <SimpleTable58 :columns="quickFilterConfig.headers"59 :rows="quickFilterConfig.rows"60 :height="height"61 :theme="theme"62 :quick-filter="{ text: searchText, mode: filterMode, caseSensitive }"63 />64 </div>65</template>6667<script setup lang="ts">68import { ref } from "vue";69import {SimpleTable} from "@simple-table/vue";import type { Theme, QuickFilterMode } from "@simple-table/vue";70import { quickFilterConfig } from "./quick-filter.demo-data";71import "@simple-table/vue/styles.css";7273withDefaults(defineProps<{ height?: string | number; theme?: Theme }>(), {74 height: "400px",75});7677const searchText = ref("");78const filterMode = ref<QuickFilterMode>("simple");79const caseSensitive = ref(false);80</script>
Angularquick-filter-demo.component.ts
Copy
1import { Component, Input } from "@angular/core";2import { FormsModule } from "@angular/forms";3import {SimpleTableComponent} from "@simple-table/angular";import type { AngularColumnDef, QuickFilterMode, Row, Theme } from "@simple-table/angular";4import { quickFilterConfig } from "./quick-filter.demo-data";5import "@simple-table/angular/styles.css";67@Component({8 selector: "quick-filter-demo",9 standalone: true,10 imports: [SimpleTableComponent, FormsModule],11 template: `12 <div>13 <div style="display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; align-items: center">14 <input15 type="text"16 placeholder="Search..."17 [(ngModel)]="searchText"18 style="padding: 6px 12px; border-radius: 6px; border: 1px solid #d1d5db; font-size: 13px; min-width: 200px"19 />20 <button21 (click)="filterMode = 'simple'"22 [style.padding]="'6px 14px'"23 [style.borderRadius]="'6px'"24 [style.border]="filterMode === 'simple' ? '2px solid #3b82f6' : '1px solid #d1d5db'"25 [style.background]="filterMode === 'simple' ? '#eff6ff' : '#fff'"26 [style.color]="filterMode === 'simple' ? '#1d4ed8' : '#374151'"27 [style.fontWeight]="filterMode === 'simple' ? 600 : 400"28 [style.cursor]="'pointer'"29 [style.fontSize]="'13px'"30 >31 Simple32 </button>33 <button34 (click)="filterMode = 'smart'"35 [style.padding]="'6px 14px'"36 [style.borderRadius]="'6px'"37 [style.border]="filterMode === 'smart' ? '2px solid #3b82f6' : '1px solid #d1d5db'"38 [style.background]="filterMode === 'smart' ? '#eff6ff' : '#fff'"39 [style.color]="filterMode === 'smart' ? '#1d4ed8' : '#374151'"40 [style.fontWeight]="filterMode === 'smart' ? 600 : 400"41 [style.cursor]="'pointer'"42 [style.fontSize]="'13px'"43 >44 Smart45 </button>46 <button47 (click)="caseSensitive = !caseSensitive"48 [style.padding]="'6px 14px'"49 [style.borderRadius]="'6px'"50 [style.border]="caseSensitive ? '2px solid #3b82f6' : '1px solid #d1d5db'"51 [style.background]="caseSensitive ? '#eff6ff' : '#fff'"52 [style.color]="caseSensitive ? '#1d4ed8' : '#374151'"53 [style.fontWeight]="caseSensitive ? 600 : 400"54 [style.cursor]="'pointer'"55 [style.fontSize]="'13px'"56 >57 Case Sensitive58 </button>59 </div>60 <simple-table61 [rows]="rows"62 [columns]="headers"63 [height]="height"64 [theme]="theme"65 [quickFilter]="{ text: searchText, mode: filterMode, caseSensitive: caseSensitive }"66 ></simple-table>67 </div>68 `,69})70export class QuickFilterDemoComponent {71 @Input() height: string | number = "400px";72 @Input() theme?: Theme;7374 readonly rows: Row[] = quickFilterConfig.rows;75 readonly headers: AngularColumnDef[] = quickFilterConfig.headers;76 searchText = "";77 filterMode: QuickFilterMode = "simple";78 caseSensitive = false;79}808182// quick-filter.demo-data.ts83// Self-contained demo table setup for this example.84import type { AngularColumnDef } from "@simple-table/angular";858687export const quickFilterHeaders: AngularColumnDef[] = [88 { accessor: "name", label: "Employee Name", width: 180, type: "string" },89 { accessor: "age", label: "Age", width: 80, type: "number" },90 { accessor: "department", label: "Department", width: 140, type: "string" },91 { accessor: "salary", label: "Salary", width: 120, type: "number", valueFormatter: ({ value }) => `$${(value || 0).toLocaleString()}`, align: "right" },92 { accessor: "status", label: "Status", width: 100, type: "string" },93 { accessor: "location", label: "Location", width: 140, type: "string" },94];9596export const quickFilterData = [97 { id: 1, name: "Alice Johnson", age: 28, department: "Engineering", salary: 95000, status: "Active", location: "New York" },98 { id: 2, name: "Bob Smith", age: 35, department: "Sales", salary: 75000, status: "Active", location: "Los Angeles" },99 { id: 3, name: "Charlie Davis", age: 42, department: "Engineering", salary: 110000, status: "Active", location: "San Francisco" },100 { id: 4, name: "Diana Prince", age: 31, department: "Marketing", salary: 82000, status: "Inactive", location: "Chicago" },101 { id: 5, name: "Ethan Hunt", age: 29, department: "Sales", salary: 78000, status: "Active", location: "Boston" },102 { id: 6, name: "Fiona Green", age: 38, department: "Engineering", salary: 105000, status: "Active", location: "Seattle" },103 { id: 7, name: "George Wilson", age: 26, department: "Marketing", salary: 68000, status: "Active", location: "Austin" },104 { id: 8, name: "Hannah Lee", age: 33, department: "Sales", salary: 88000, status: "Inactive", location: "Denver" },105 { id: 9, name: "Isaac Chen", age: 27, department: "Engineering", salary: 92000, status: "Active", location: "San Diego" },106 { id: 10, name: "Julia Brown", age: 30, department: "Marketing", salary: 72000, status: "Inactive", location: "Miami" },107 { id: 11, name: "Kevin Davis", age: 28, department: "Sales", salary: 85000, status: "Active", location: "Phoenix" },108 { id: 12, name: "Laura Garcia", age: 32, department: "Engineering", salary: 102000, status: "Active", location: "San Antonio" },109];110111export const quickFilterConfig = {112 headers: quickFilterHeaders,113 rows: quickFilterData,114 tableProps: { quickFilter: { text: "", mode: "simple" as const, caseSensitive: false } },115} as const;116
Svelte
Copy
1<script lang="ts">2 import {SimpleTable} from "@simple-table/svelte"; import type { Theme, QuickFilterMode } from "@simple-table/svelte";3 import { quickFilterConfig } from "./quick-filter.demo-data";4 import "@simple-table/svelte/styles.css";56 let { height = "400px", theme }: { height?: string | number; theme?: Theme } = $props();7 let searchText = $state("");8 let filterMode: QuickFilterMode = $state("simple");9 let caseSensitive = $state(false);10</script>1112<div>13 <div style="display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; align-items: center">14 <input15 type="text"16 placeholder="Search..."17 bind:value={searchText}18 style="padding: 6px 12px; border-radius: 6px; border: 1px solid #d1d5db; font-size: 13px; min-width: 200px"19 />20 <button21 onclick={() => (filterMode = "simple")}22 style="padding: 6px 14px; border-radius: 6px; cursor: pointer; font-size: 13px; border: {filterMode === 'simple' ? '2px solid #3b82f6' : '1px solid #d1d5db'}; background: {filterMode === 'simple' ? '#eff6ff' : '#fff'}; color: {filterMode === 'simple' ? '#1d4ed8' : '#374151'}; font-weight: {filterMode === 'simple' ? 600 : 400}"23 >24 Simple25 </button>26 <button27 onclick={() => (filterMode = "smart")}28 style="padding: 6px 14px; border-radius: 6px; cursor: pointer; font-size: 13px; border: {filterMode === 'smart' ? '2px solid #3b82f6' : '1px solid #d1d5db'}; background: {filterMode === 'smart' ? '#eff6ff' : '#fff'}; color: {filterMode === 'smart' ? '#1d4ed8' : '#374151'}; font-weight: {filterMode === 'smart' ? 600 : 400}"29 >30 Smart31 </button>32 <button33 onclick={() => (caseSensitive = !caseSensitive)}34 style="padding: 6px 14px; border-radius: 6px; cursor: pointer; font-size: 13px; border: {caseSensitive ? '2px solid #3b82f6' : '1px solid #d1d5db'}; background: {caseSensitive ? '#eff6ff' : '#fff'}; color: {caseSensitive ? '#1d4ed8' : '#374151'}; font-weight: {caseSensitive ? 600 : 400}"35 >36 Case Sensitive37 </button>38 </div>39 <SimpleTable40 columns={quickFilterConfig.headers}41 rows={quickFilterConfig.rows}42 {height}43 {theme}44 quickFilter={{ text: searchText, mode: filterMode, caseSensitive }}45 />46</div>
Solid TSX
Copy
1import { createSignal } from "solid-js";2import {SimpleTable} from "@simple-table/solid";import type { Theme, QuickFilterMode } from "@simple-table/solid";3import { quickFilterConfig } from "./quick-filter.demo-data";4import "@simple-table/solid/styles.css";56export default function QuickFilterDemo(props: { height?: string | number; theme?: Theme }) {7 const [searchText, setSearchText] = createSignal("");8 const [filterMode, setFilterMode] = createSignal<QuickFilterMode>("simple");9 const [caseSensitive, setCaseSensitive] = createSignal(false);1011 const modeBtn = (mode: QuickFilterMode, label: string) => ({12 padding: "6px 14px",13 "border-radius": "6px",14 border: filterMode() === mode ? "2px solid #3b82f6" : "1px solid #d1d5db",15 background: filterMode() === mode ? "#eff6ff" : "#fff",16 color: filterMode() === mode ? "#1d4ed8" : "#374151",17 "font-weight": filterMode() === mode ? 600 : 400,18 cursor: "pointer",19 "font-size": "13px",20 });2122 return (23 <div>24 <div style={{ display: "flex", "flex-wrap": "wrap", gap: "8px", "margin-bottom": "12px", "align-items": "center" }}>25 <input26 type="text"27 placeholder="Search..."28 value={searchText()}29 onInput={(e) => setSearchText(e.currentTarget.value)}30 style={{31 padding: "6px 12px",32 "border-radius": "6px",33 border: "1px solid #d1d5db",34 "font-size": "13px",35 "min-width": "200px",36 }}37 />38 <button onClick={() => setFilterMode("simple")} style={modeBtn("simple", "Simple")}>39 Simple40 </button>41 <button onClick={() => setFilterMode("smart")} style={modeBtn("smart", "Smart")}>42 Smart43 </button>44 <button45 onClick={() => setCaseSensitive((prev) => !prev)}46 style={{47 padding: "6px 14px",48 "border-radius": "6px",49 border: caseSensitive() ? "2px solid #3b82f6" : "1px solid #d1d5db",50 background: caseSensitive() ? "#eff6ff" : "#fff",51 color: caseSensitive() ? "#1d4ed8" : "#374151",52 "font-weight": caseSensitive() ? 600 : 400,53 cursor: "pointer",54 "font-size": "13px",55 }}56 >57 Case Sensitive58 </button>59 </div>60 <SimpleTable61 columns={quickFilterConfig.headers}62 rows={quickFilterConfig.rows}63 height={props.height ?? "400px"}64 theme={props.theme}65 quickFilter={{ text: searchText(), mode: filterMode(), caseSensitive: caseSensitive() }}66 />67 </div>68 );69}
TypeScriptQuickFilterDemo.ts
Copy
1import { SimpleTableVanilla } from "simple-table-core";2import type { Theme, QuickFilterMode } from "simple-table-core";3import { quickFilterConfig } from "./quick-filter.demo-data";4import "simple-table-core/styles.css";56export function renderQuickFilterDemo(7 container: HTMLElement,8 options?: { height?: string | number; theme?: Theme }9): SimpleTableVanilla {10 let searchText = "";11 let filterMode: QuickFilterMode = "simple";12 let caseSensitive = false;1314 const wrapper = document.createElement("div");1516 const controlsRow = document.createElement("div");17 controlsRow.style.cssText = "display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px;align-items:center";1819 const input = document.createElement("input");20 input.type = "text";21 input.placeholder = "Search...";22 input.style.cssText = "padding:6px 12px;border-radius:6px;border:1px solid #d1d5db;font-size:13px;min-width:200px";23 input.addEventListener("input", () => {24 searchText = input.value;25 table.update({ quickFilter: { text: searchText, mode: filterMode, caseSensitive } });26 });27 controlsRow.appendChild(input);2829 const tableContainer = document.createElement("div");30 wrapper.appendChild(controlsRow);31 wrapper.appendChild(tableContainer);32 container.appendChild(wrapper);3334 const table = new SimpleTableVanilla(tableContainer, {35 columns: quickFilterConfig.headers,36 rows: quickFilterConfig.rows,37 height: options?.height ?? "400px",38 theme: options?.theme,39 quickFilter: { text: searchText, mode: filterMode, caseSensitive },40 });4142 function applyBtnStyle(btn: HTMLButtonElement, active: boolean) {43 btn.style.cssText = `padding:6px 14px;border-radius:6px;cursor:pointer;font-size:13px;border:${active ? "2px solid #3b82f6" : "1px solid #d1d5db"};background:${active ? "#eff6ff" : "#fff"};color:${active ? "#1d4ed8" : "#374151"};font-weight:${active ? 600 : 400}`;44 }4546 const simpleBtn = document.createElement("button");47 simpleBtn.textContent = "Simple";48 const smartBtn = document.createElement("button");49 smartBtn.textContent = "Smart";50 const caseBtn = document.createElement("button");51 caseBtn.textContent = "Case Sensitive";5253 function updateButtons() {54 applyBtnStyle(simpleBtn, filterMode === "simple");55 applyBtnStyle(smartBtn, filterMode === "smart");56 applyBtnStyle(caseBtn, caseSensitive);57 }5859 simpleBtn.addEventListener("click", () => {60 filterMode = "simple";61 table.update({ quickFilter: { text: searchText, mode: filterMode, caseSensitive } });62 updateButtons();63 });64 smartBtn.addEventListener("click", () => {65 filterMode = "smart";66 table.update({ quickFilter: { text: searchText, mode: filterMode, caseSensitive } });67 updateButtons();68 });69 caseBtn.addEventListener("click", () => {70 caseSensitive = !caseSensitive;71 table.update({ quickFilter: { text: searchText, mode: filterMode, caseSensitive } });72 updateButtons();73 });7475 controlsRow.appendChild(simpleBtn);76 controlsRow.appendChild(smartBtn);77 controlsRow.appendChild(caseBtn);78 updateButtons();7980 return table;81}828384// quick-filter.demo-data.ts85// Self-contained demo table setup for this example.86import type { ColumnDef } from "simple-table-core";878889export const quickFilterHeaders: ColumnDef[] = [90 { accessor: "name", label: "Employee Name", width: 180, type: "string" },91 { accessor: "age", label: "Age", width: 80, type: "number" },92 { accessor: "department", label: "Department", width: 140, type: "string" },93 { accessor: "salary", label: "Salary", width: 120, type: "number", valueFormatter: ({ value }) => `$${(value || 0).toLocaleString()}`, align: "right" },94 { accessor: "status", label: "Status", width: 100, type: "string" },95 { accessor: "location", label: "Location", width: 140, type: "string" },96];9798export const quickFilterData = [99 { id: 1, name: "Alice Johnson", age: 28, department: "Engineering", salary: 95000, status: "Active", location: "New York" },100 { id: 2, name: "Bob Smith", age: 35, department: "Sales", salary: 75000, status: "Active", location: "Los Angeles" },101 { id: 3, name: "Charlie Davis", age: 42, department: "Engineering", salary: 110000, status: "Active", location: "San Francisco" },102 { id: 4, name: "Diana Prince", age: 31, department: "Marketing", salary: 82000, status: "Inactive", location: "Chicago" },103 { id: 5, name: "Ethan Hunt", age: 29, department: "Sales", salary: 78000, status: "Active", location: "Boston" },104 { id: 6, name: "Fiona Green", age: 38, department: "Engineering", salary: 105000, status: "Active", location: "Seattle" },105 { id: 7, name: "George Wilson", age: 26, department: "Marketing", salary: 68000, status: "Active", location: "Austin" },106 { id: 8, name: "Hannah Lee", age: 33, department: "Sales", salary: 88000, status: "Inactive", location: "Denver" },107 { id: 9, name: "Isaac Chen", age: 27, department: "Engineering", salary: 92000, status: "Active", location: "San Diego" },108 { id: 10, name: "Julia Brown", age: 30, department: "Marketing", salary: 72000, status: "Inactive", location: "Miami" },109 { id: 11, name: "Kevin Davis", age: 28, department: "Sales", salary: 85000, status: "Active", location: "Phoenix" },110 { id: 12, name: "Laura Garcia", age: 32, department: "Engineering", salary: 102000, status: "Active", location: "San Antonio" },111];112113export const quickFilterConfig = {114 headers: quickFilterHeaders,115 rows: quickFilterData,116 tableProps: { quickFilter: { text: "", mode: "simple" as const, caseSensitive: false } },117} as const;118
Props
Quick Filter Configuration
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
quickFilter | Optional | Global search across columns. Controlled via QuickFilterConfig (text is required). | |
ColumnDef.quickFilterableboolean | Optional | When false, the column is skipped by quick filter. Defaults to true. | |
ColumnDef.quickFilterGetterQuickFilterGetter | Optional | Custom string extracted from the row for quick filter matching. |
QuickFilterConfig
QuickFilterConfig
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
textstring | Required | The search text to filter by. All columns will be searched for this text unless specific columns are configured. | |
mode"simple" | "smart" | Optional | Search mode: 'simple' for basic contains matching, or 'smart' for advanced search with multi-word AND logic, phrase search (quotes), negation (minus), and column-specific search. Defaults to 'simple'. | |
caseSensitiveboolean | Optional | Whether the search should be case-sensitive. Defaults to false. | |
columnsAccessor[] | Optional | Array of column accessors to search. If not provided, all columns are searched (unless a column has quickFilterable: false). | |
useFormattedValueboolean | Optional | Whether to search the formatted value (from valueFormatter) instead of the raw value. Defaults to true. | |
onChange(text: string) => void | Optional | Callback function triggered when the quick filter text changes. Useful for tracking search analytics or syncing with external state. |
QuickFilterGetterProps
QuickFilterGetterProps
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
rowRow | Required | The row data object. | |
accessorAccessor | Required | The column accessor. |