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" }}/>
Angular
Copy
searchText = "";<input [(ngModel)]="searchText" /><simple-table[columns]="columns"[rows]="rows"[quickFilter]="{ text: searchText, mode: 'simple' }"></simple-table>
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>
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" }}/>
Angular
Copy
searchText = "";<input [(ngModel)]="searchText" /><simple-table[columns]="columns"[rows]="rows"[quickFilter]="{ text: searchText, mode: 'smart' }"></simple-table>
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>
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
Angular
Copy
this.tableRef.getAPI()?.setQuickFilter("engineering");this.tableRef.getAPI()?.setQuickFilter(""); // clear
Vue SFC
Copy
tableRef.value?.setQuickFilter("engineering");tableRef.value?.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 theme9}: {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: 20031 }}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: 1344 }}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: 1359 }}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: 1374 }}75 >76 Case Sensitive77 </button>78 </div>79 <SimpleTable80 columns={quickFilterConfig.headers}81 rows={quickFilterConfig.rows}82 height={height}83 theme={theme}84 getRowId={({ row }) => row.id}85 quickFilter={{ text: searchText, mode: filterMode, caseSensitive }}86 />87 </div>88 );89};9091export default QuickFilterDemo;
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, GetRowIdParams, QuickFilterMode, Theme } from "@simple-table/angular";4import { quickFilterConfig } from "./quick-filter.demo-data";5import "@simple-table/angular/styles.css";6import type { QuickFilterEmployee } from "./quick-filter.demo-data";78@Component({9 selector: "quick-filter-demo",10 standalone: true,11 imports: [SimpleTableComponent, FormsModule],12 template: `13 <div>14 <div style="display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; align-items: center">15 <input16 type="text"17 placeholder="Search..."18 [(ngModel)]="searchText"19 style="padding: 6px 12px; border-radius: 6px; border: 1px solid #d1d5db; font-size: 13px; min-width: 200px"20 />21 <button22 (click)="filterMode = 'simple'"23 [style.padding]="'6px 14px'"24 [style.borderRadius]="'6px'"25 [style.border]="filterMode === 'simple' ? '2px solid #3b82f6' : '1px solid #d1d5db'"26 [style.background]="filterMode === 'simple' ? '#eff6ff' : '#fff'"27 [style.color]="filterMode === 'simple' ? '#1d4ed8' : '#374151'"28 [style.fontWeight]="filterMode === 'simple' ? 600 : 400"29 [style.cursor]="'pointer'"30 [style.fontSize]="'13px'"31 >32 Simple33 </button>34 <button35 (click)="filterMode = 'smart'"36 [style.padding]="'6px 14px'"37 [style.borderRadius]="'6px'"38 [style.border]="filterMode === 'smart' ? '2px solid #3b82f6' : '1px solid #d1d5db'"39 [style.background]="filterMode === 'smart' ? '#eff6ff' : '#fff'"40 [style.color]="filterMode === 'smart' ? '#1d4ed8' : '#374151'"41 [style.fontWeight]="filterMode === 'smart' ? 600 : 400"42 [style.cursor]="'pointer'"43 [style.fontSize]="'13px'"44 >45 Smart46 </button>47 <button48 (click)="caseSensitive = !caseSensitive"49 [style.padding]="'6px 14px'"50 [style.borderRadius]="'6px'"51 [style.border]="caseSensitive ? '2px solid #3b82f6' : '1px solid #d1d5db'"52 [style.background]="caseSensitive ? '#eff6ff' : '#fff'"53 [style.color]="caseSensitive ? '#1d4ed8' : '#374151'"54 [style.fontWeight]="caseSensitive ? 600 : 400"55 [style.cursor]="'pointer'"56 [style.fontSize]="'13px'"57 >58 Case Sensitive59 </button>60 </div>61 <simple-table62 [getRowId]="getRowId"63 [rows]="rows"64 [columns]="headers"65 [height]="height"66 [theme]="theme"67 [quickFilter]="{ text: searchText, mode: filterMode, caseSensitive: caseSensitive }"68 ></simple-table>69 </div>70 `,71})72export class QuickFilterDemoComponent {73 @Input() height: string | number = "400px";74 @Input() theme?: Theme;7576 readonly rows: QuickFilterEmployee[] = quickFilterConfig.rows;77 readonly headers: AngularColumnDef<QuickFilterEmployee>[] = quickFilterConfig.headers;78 searchText = "";79 filterMode: QuickFilterMode = "simple";80 caseSensitive = false;8182 getRowId = ({ row }: GetRowIdParams<QuickFilterEmployee>) => row.id;83}848586// quick-filter.demo-data.ts87// Self-contained demo table setup for this example.88import type { AngularColumnDef, ValueFormatterProps } from "@simple-table/angular";8990export interface QuickFilterEmployee {91 id: number;92 name: string;93 age: number;94 department: string;95 salary: number;96 status: string;97 location: string;98}99100export const quickFilterHeaders: AngularColumnDef<QuickFilterEmployee>[] = [101 { accessor: "name", label: "Employee Name", width: 180, type: "string" },102 { accessor: "age", label: "Age", width: 80, type: "number" },103 { accessor: "department", label: "Department", width: 140, type: "string" },104 { accessor: "salary", label: "Salary", width: 120, type: "number", valueFormatter: ({ value }: ValueFormatterProps<QuickFilterEmployee>) => `$${(value || 0).toLocaleString()}`, align: "right" },105 { accessor: "status", label: "Status", width: 100, type: "string" },106 { accessor: "location", label: "Location", width: 140, type: "string" },107];108109export const quickFilterData: QuickFilterEmployee[] = [110 { id: 1, name: "Alice Johnson", age: 28, department: "Engineering", salary: 95000, status: "Active", location: "New York" },111 { id: 2, name: "Bob Smith", age: 35, department: "Sales", salary: 75000, status: "Active", location: "Los Angeles" },112 { id: 3, name: "Charlie Davis", age: 42, department: "Engineering", salary: 110000, status: "Active", location: "San Francisco" },113 { id: 4, name: "Diana Prince", age: 31, department: "Marketing", salary: 82000, status: "Inactive", location: "Chicago" },114 { id: 5, name: "Ethan Hunt", age: 29, department: "Sales", salary: 78000, status: "Active", location: "Boston" },115 { id: 6, name: "Fiona Green", age: 38, department: "Engineering", salary: 105000, status: "Active", location: "Seattle" },116 { id: 7, name: "George Wilson", age: 26, department: "Marketing", salary: 68000, status: "Active", location: "Austin" },117 { id: 8, name: "Hannah Lee", age: 33, department: "Sales", salary: 88000, status: "Inactive", location: "Denver" },118 { id: 9, name: "Isaac Chen", age: 27, department: "Engineering", salary: 92000, status: "Active", location: "San Diego" },119 { id: 10, name: "Julia Brown", age: 30, department: "Marketing", salary: 72000, status: "Inactive", location: "Miami" },120 { id: 11, name: "Kevin Davis", age: 28, department: "Sales", salary: 85000, status: "Active", location: "Phoenix" },121 { id: 12, name: "Laura Garcia", age: 32, department: "Engineering", salary: 102000, status: "Active", location: "San Antonio" },122];123124export const quickFilterConfig = {125 headers: quickFilterHeaders,126 rows: quickFilterData,127};128
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 :get-row-id="getRowId"61 :height="height"62 :theme="theme"63 :quick-filter="{ text: searchText, mode: filterMode, caseSensitive }"64 />65 </div>66</template>6768<script setup lang="ts">69import { ref } from "vue";70import { SimpleTable } from "@simple-table/vue";71import type { Theme, QuickFilterMode, GetRowIdParams } from "@simple-table/vue";72import { quickFilterConfig } from "./quick-filter.demo-data";73import type { QuickFilterEmployee } from "./quick-filter.demo-data";74import "@simple-table/vue/styles.css";7576withDefaults(defineProps<{ height?: string | number; theme?: Theme }>(), {77 height: "400px",78});7980const getRowId = ({ row }: GetRowIdParams<QuickFilterEmployee>) => row.id;8182const searchText = ref("");83const filterMode = ref<QuickFilterMode>("simple");84const caseSensitive = ref(false);85</script>
Svelte
Copy
1<script lang="ts">2 import { SimpleTable } from "@simple-table/svelte";3 import type { Theme, QuickFilterMode, GetRowIdParams } from "@simple-table/svelte";4 import { quickFilterConfig } from "./quick-filter.demo-data";5 import type { QuickFilterEmployee } from "./quick-filter.demo-data";6 import "@simple-table/svelte/styles.css";78 let { height = "400px", theme }: { height?: string | number; theme?: Theme } = $props();9 let searchText = $state("");10 let filterMode: QuickFilterMode = $state("simple");11 let caseSensitive = $state(false);1213 const getRowId = ({ row }: GetRowIdParams<QuickFilterEmployee>) => row.id;14</script>1516<div>17 <div style="display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; align-items: center">18 <input19 type="text"20 placeholder="Search..."21 bind:value={searchText}22 style="padding: 6px 12px; border-radius: 6px; border: 1px solid #d1d5db; font-size: 13px; min-width: 200px"23 />24 <button25 onclick={() => (filterMode = "simple")}26 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}"27 >28 Simple29 </button>30 <button31 onclick={() => (filterMode = "smart")}32 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}"33 >34 Smart35 </button>36 <button37 onclick={() => (caseSensitive = !caseSensitive)}38 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}"39 >40 Case Sensitive41 </button>42 </div>43 <SimpleTable44 columns={quickFilterConfig.headers}45 rows={quickFilterConfig.rows}46 getRowId={getRowId}47 {height}48 {theme}49 quickFilter={{ text: searchText, mode: filterMode, caseSensitive }}50 />51</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 getRowId={({ row }) => row.id}63 rows={quickFilterConfig.rows}64 height={props.height ?? "400px"}65 theme={props.theme}66 quickFilter={{ text: searchText(), mode: filterMode(), caseSensitive: caseSensitive() }}67 />68 </div>69 );70}
TypeScriptQuickFilterDemo.ts
Copy
1import { SimpleTableVanilla } from "simple-table-core";2import type { QuickFilterEmployee } from "./quick-filter.demo-data";3import type { Theme, QuickFilterMode, GetRowIdParams } from "simple-table-core";4import { quickFilterConfig } from "./quick-filter.demo-data";5import "simple-table-core/styles.css";678const getRowId = ({ row }: GetRowIdParams<QuickFilterEmployee>) => row.id;9export function renderQuickFilterDemo(10 container: HTMLElement,11 options?: { height?: string | number; theme?: Theme }12): SimpleTableVanilla<QuickFilterEmployee> {13 let searchText = "";14 let filterMode: QuickFilterMode = "simple";15 let caseSensitive = false;1617 const wrapper = document.createElement("div");1819 const controlsRow = document.createElement("div");20 controlsRow.style.cssText = "display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px;align-items:center";2122 const input = document.createElement("input");23 input.type = "text";24 input.placeholder = "Search...";25 input.style.cssText = "padding:6px 12px;border-radius:6px;border:1px solid #d1d5db;font-size:13px;min-width:200px";26 input.addEventListener("input", () => {27 searchText = input.value;28 table.update({ quickFilter: { text: searchText, mode: filterMode, caseSensitive } });29 });30 controlsRow.appendChild(input);3132 const tableContainer = document.createElement("div");33 wrapper.appendChild(controlsRow);34 wrapper.appendChild(tableContainer);35 container.appendChild(wrapper);3637 const table = new SimpleTableVanilla(tableContainer, {38 getRowId,39 columns: quickFilterConfig.headers,40 rows: quickFilterConfig.rows,41 height: options?.height ?? "400px",42 theme: options?.theme,43 quickFilter: { text: searchText, mode: filterMode, caseSensitive },44 });4546 function applyBtnStyle(btn: HTMLButtonElement, active: boolean) {47 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}`;48 }4950 const simpleBtn = document.createElement("button");51 simpleBtn.textContent = "Simple";52 const smartBtn = document.createElement("button");53 smartBtn.textContent = "Smart";54 const caseBtn = document.createElement("button");55 caseBtn.textContent = "Case Sensitive";5657 function updateButtons() {58 applyBtnStyle(simpleBtn, filterMode === "simple");59 applyBtnStyle(smartBtn, filterMode === "smart");60 applyBtnStyle(caseBtn, caseSensitive);61 }6263 simpleBtn.addEventListener("click", () => {64 filterMode = "simple";65 table.update({ quickFilter: { text: searchText, mode: filterMode, caseSensitive } });66 updateButtons();67 });68 smartBtn.addEventListener("click", () => {69 filterMode = "smart";70 table.update({ quickFilter: { text: searchText, mode: filterMode, caseSensitive } });71 updateButtons();72 });73 caseBtn.addEventListener("click", () => {74 caseSensitive = !caseSensitive;75 table.update({ quickFilter: { text: searchText, mode: filterMode, caseSensitive } });76 updateButtons();77 });7879 controlsRow.appendChild(simpleBtn);80 controlsRow.appendChild(smartBtn);81 controlsRow.appendChild(caseBtn);82 updateButtons();8384 return table;85}868788// quick-filter.demo-data.ts89// Self-contained demo table setup for this example.90import type { ColumnDef } from "simple-table-core";9192export interface QuickFilterEmployee {93 id: number;94 name: string;95 age: number;96 department: string;97 salary: number;98 status: string;99 location: string;100}101102export const quickFilterHeaders: ColumnDef<QuickFilterEmployee>[] = [103 { accessor: "name", label: "Employee Name", width: 180, type: "string" },104 { accessor: "age", label: "Age", width: 80, type: "number" },105 { accessor: "department", label: "Department", width: 140, type: "string" },106 { accessor: "salary", label: "Salary", width: 120, type: "number", valueFormatter: ({ value }) => `$${(value || 0).toLocaleString()}`, align: "right" },107 { accessor: "status", label: "Status", width: 100, type: "string" },108 { accessor: "location", label: "Location", width: 140, type: "string" },109];110111export const quickFilterData: QuickFilterEmployee[] = [112 { id: 1, name: "Alice Johnson", age: 28, department: "Engineering", salary: 95000, status: "Active", location: "New York" },113 { id: 2, name: "Bob Smith", age: 35, department: "Sales", salary: 75000, status: "Active", location: "Los Angeles" },114 { id: 3, name: "Charlie Davis", age: 42, department: "Engineering", salary: 110000, status: "Active", location: "San Francisco" },115 { id: 4, name: "Diana Prince", age: 31, department: "Marketing", salary: 82000, status: "Inactive", location: "Chicago" },116 { id: 5, name: "Ethan Hunt", age: 29, department: "Sales", salary: 78000, status: "Active", location: "Boston" },117 { id: 6, name: "Fiona Green", age: 38, department: "Engineering", salary: 105000, status: "Active", location: "Seattle" },118 { id: 7, name: "George Wilson", age: 26, department: "Marketing", salary: 68000, status: "Active", location: "Austin" },119 { id: 8, name: "Hannah Lee", age: 33, department: "Sales", salary: 88000, status: "Inactive", location: "Denver" },120 { id: 9, name: "Isaac Chen", age: 27, department: "Engineering", salary: 92000, status: "Active", location: "San Diego" },121 { id: 10, name: "Julia Brown", age: 30, department: "Marketing", salary: 72000, status: "Inactive", location: "Miami" },122 { id: 11, name: "Kevin Davis", age: 28, department: "Sales", salary: 85000, status: "Active", location: "Phoenix" },123 { id: 12, name: "Laura Garcia", age: 32, department: "Engineering", salary: 102000, status: "Active", location: "San Antonio" },124];125126export const quickFilterConfig = {127 headers: quickFilterHeaders,128 rows: quickFilterData,129};130
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. |