Having trouble getting my GlobalFilter to update the table when using Regex to search for multiple results in a column.
export const Table = ({ data, columns }) => {
const filterTypes = useMemo(
() => ({
// Override the default text filter to use
// "startWith"
text: (rows, id, filterValue) => {
return rows.filter((row) => {
const rowValue = row.values[id];
const isRegexMatch = () => {
try {
return RegExp(filterValue).test(String(rowValue));
} catch (err) {
return false;
}
};
return rowValue !== undefined
? String(rowValue)
.toLowerCase()
.startsWith(String(filterValue).toLowerCase()) || isRegexMatch()
: true;
});
},
}),
[]
);
const {
getTableProps,
getTableBodyProps,
headerGroups,
prepareRow,
page,
canPreviousPage,
canNextPage,
pageOptions,
pageCount,
gotoPage,
nextPage,
previousPage,
setPageSize,
preGlobalFilteredRows,
setGlobalFilter,
state,
state: { pageIndex, pageSize },
} = useTable(
{
columns,
data,
filterTypes,
},
useFilters,
useGlobalFilter,
useSortBy,
usePagination
);
return (
<div className="col-12">
<div className="table-responsive mb-5">
<GlobalFilter
preGlobalFilteredRows={preGlobalFilteredRows}
globalFilter={state.globalFilter}
setGlobalFilter={setGlobalFilter}
/>
<table {...getTableProps()} className="table">
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
{column.render('Header')}
<span>
{column.isSorted ? (
column.isSortedDesc ? (
<ChevronDown baseLayer="icon" />
) : (
<ChevronUp baseLayer="icon" />
)
) : (
''
)}
</span>
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()} key={i}>
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
);
})}
</tr>
);
})}
</tbody>
</table>
<div className="pagination mt-3">
<button
onClick={() => gotoPage(0)}
disabled={!canPreviousPage}
className="btn btn-sm btn-link"
>
{'<<'}
</button>{' '}
<button
onClick={() => previousPage()}
disabled={!canPreviousPage}
className="btn btn-sm btn-link"
>
{'<'}
</button>{' '}
<button
onClick={() => nextPage()}
disabled={!canNextPage}
className="btn btn-sm btn-link"
>
{'>'}
</button>{' '}
<button
onClick={() => gotoPage(pageCount - 1)}
disabled={!canNextPage}
className="btn btn-sm btn-link"
>
{'>'}
</button>{' '}
<span className="mt-2 text-muted">
<small>
Page {pageIndex + 1} of {pageOptions.length}{' '}
</small>
</span>
<span className="mt-2 ms-1 me-1 text-muted">
<small> | Go to page:</small>
</span>
<span className="me-1">
<input
type="number"
className="form-control"
defaultValue={pageIndex + 1}
onChange={(e) => {
const page = e.target.value ? Number(e.target.value) - 1 : 0;
gotoPage(page);
}}
style={{ width: '80px' }}
/>
</span>
<select
value={pageSize}
style={{ width: '190px' }}
className="form-control"
onChange={(e) => {
setPageSize(Number(e.target.value));
}}
>
{[10, 20, 30, 40, 50].map((pageSize) => (
<option key={pageSize} value={pageSize}>
Show {pageSize} per page
</option>
))}
<option key={data.length} value={data.length}>
Show All
</option>
</select>
</div>
</div>
</div>
);
};
I only had success so far in the console with this function being able to filter the results, but so far no luck with the react-table package.
function regexFilter(rows, ids, filterValue) {
rows = rows.filter((row) => {
return ids.some((id) => {
const rowValue = row.values[id];
const isRegexMatch = () => {
try {
return RegExp(filterValue).test(String(rowValue));
} catch (err) {
return false;
}
};
return (
String(rowValue)
.toLowerCase()
.includes(String(filterValue).toLowerCase()) || isRegexMatch()
);
});
});
return rows;
}
What am I not doing correctly or mis-interpreting from the documentation on filterTypes?