mirror of
https://github.com/gosticks/react-table.git
synced 2025-10-16 11:55:36 +00:00
Add disableGlobalFilter prop to allow for columns (and instance) to ignore global filter (#1963)
* size-snapshot created? * Added `disableGlobalFilter` prop and associated tests * Updated documentation * improvement(useglobalfilter): add `disableGlobalFilter` prop Adding `disableGlobalFilter` prop to both table and column to allow columns to be excluded from Global Filter * test(usefilters.test.js): added base test for disableGlobalFilter Needed a test to make sure that disableGlobalFilter didn't break anything when applied * Delete .size-snapshot.json * Update README.md Co-authored-by: Jason Clark <jason.clark@tcnbroadcasting.com> Co-authored-by: Tanner Linsley <tannerlinsley@gmail.com>
This commit is contained in:
parent
63754a58dd
commit
512f615988
@ -23,6 +23,8 @@ The following options are supported via the main options object passed to `useTa
|
|||||||
- `manualGlobalFilter: Bool`
|
- `manualGlobalFilter: Bool`
|
||||||
- Enables filter detection functionality, but does not automatically perform row filtering.
|
- Enables filter detection functionality, but does not automatically perform row filtering.
|
||||||
- Turn this on if you wish to implement your own row filter outside of the table (eg. server-side or manual row grouping/nesting)
|
- Turn this on if you wish to implement your own row filter outside of the table (eg. server-side or manual row grouping/nesting)
|
||||||
|
- `disableGlobalFilter: Bool`
|
||||||
|
- Disables global filtering for every column in the entire table.
|
||||||
- `filterTypes: Object<filterKey: filterType>`
|
- `filterTypes: Object<filterKey: filterType>`
|
||||||
- Must be **memoized**
|
- Must be **memoized**
|
||||||
- Allows overriding or adding additional filter types for the table to use. If the globalFilter type isn't found on this object, it will default to using the built-in filter types.
|
- Allows overriding or adding additional filter types for the table to use. If the globalFilter type isn't found on this object, it will default to using the built-in filter types.
|
||||||
@ -34,6 +36,14 @@ The following options are supported via the main options object passed to `useTa
|
|||||||
- To disable, set to `false`
|
- To disable, set to `false`
|
||||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](./faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](./faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||||
|
|
||||||
|
### Column Options
|
||||||
|
|
||||||
|
The following options are supported on any `Column` object passed to the `columns` option in `useTable()`
|
||||||
|
|
||||||
|
- `disableGlobalFilter: Bool`
|
||||||
|
- Optional
|
||||||
|
- If set to `true`, will disable global filtering for this column
|
||||||
|
|
||||||
### Instance Properties
|
### Instance Properties
|
||||||
|
|
||||||
The following values are provided to the table `instance`:
|
The following values are provided to the table `instance`:
|
||||||
|
|||||||
@ -52,10 +52,14 @@ const defaultColumn = {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
function App() {
|
function App(props) {
|
||||||
const [data, setData] = React.useState(makeData)
|
const [data, setData] = React.useState(makeData)
|
||||||
const columns = React.useMemo(
|
|
||||||
() => [
|
const columns = React.useMemo(() => {
|
||||||
|
if (props.columns) {
|
||||||
|
return props.columns
|
||||||
|
}
|
||||||
|
return [
|
||||||
{
|
{
|
||||||
Header: 'Name',
|
Header: 'Name',
|
||||||
columns: [
|
columns: [
|
||||||
@ -90,9 +94,8 @@ function App() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
]
|
||||||
[]
|
}, [props.columns])
|
||||||
)
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getTableProps,
|
getTableProps,
|
||||||
@ -177,6 +180,8 @@ test('renders a filterable table', async () => {
|
|||||||
const globalFilterInput = rendered.getByPlaceholderText('Global search...')
|
const globalFilterInput = rendered.getByPlaceholderText('Global search...')
|
||||||
const filterInputs = rendered.getAllByPlaceholderText('Search...')
|
const filterInputs = rendered.getAllByPlaceholderText('Search...')
|
||||||
|
|
||||||
|
expect(filterInputs).toHaveLength(6)
|
||||||
|
|
||||||
fireEvent.change(filterInputs[1], { target: { value: 'l' } })
|
fireEvent.change(filterInputs[1], { target: { value: 'l' } })
|
||||||
expect(
|
expect(
|
||||||
rendered
|
rendered
|
||||||
@ -243,3 +248,146 @@ test('renders a filterable table', async () => {
|
|||||||
'firstName: jaylen',
|
'firstName: jaylen',
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('does not filter columns marked as disableFilters', () => {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
Header: 'Name',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
Header: 'First Name',
|
||||||
|
accessor: 'firstName',
|
||||||
|
disableFilters: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Last Name',
|
||||||
|
accessor: 'lastName',
|
||||||
|
disableFilters: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Info',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
Header: 'Age',
|
||||||
|
accessor: 'age',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Visits',
|
||||||
|
accessor: 'visits',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Status',
|
||||||
|
accessor: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Profile Progress',
|
||||||
|
accessor: 'progress',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const rendered = render(<App columns={columns} />)
|
||||||
|
|
||||||
|
const filterInputs = rendered.getAllByPlaceholderText('Search...')
|
||||||
|
|
||||||
|
expect(filterInputs).toHaveLength(4)
|
||||||
|
|
||||||
|
// should be Age column
|
||||||
|
fireEvent.change(filterInputs[0], { target: { value: '45' } })
|
||||||
|
expect(
|
||||||
|
rendered
|
||||||
|
.queryAllByRole('row')
|
||||||
|
.slice(3)
|
||||||
|
.map(row => Array.from(row.children)[0].textContent)
|
||||||
|
).toEqual(['firstName: joe'])
|
||||||
|
|
||||||
|
fireEvent.change(filterInputs[0], { target: { value: '' } })
|
||||||
|
expect(
|
||||||
|
rendered
|
||||||
|
.queryAllByRole('row')
|
||||||
|
.slice(3)
|
||||||
|
.map(row => Array.from(row.children)[0].textContent)
|
||||||
|
).toEqual([
|
||||||
|
'firstName: tanner',
|
||||||
|
'firstName: derek',
|
||||||
|
'firstName: joe',
|
||||||
|
'firstName: jaylen',
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('does not filter columns with GlobalFilter if marked disableGlobalFilter', () => {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
Header: 'Name',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
Header: 'First Name',
|
||||||
|
accessor: 'firstName',
|
||||||
|
disableGlobalFilter: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Last Name',
|
||||||
|
accessor: 'lastName',
|
||||||
|
disableGlobalFilter: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Info',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
Header: 'Age',
|
||||||
|
accessor: 'age',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Visits',
|
||||||
|
accessor: 'visits',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Status',
|
||||||
|
accessor: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Profile Progress',
|
||||||
|
accessor: 'progress',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const rendered = render(<App columns={columns} />)
|
||||||
|
|
||||||
|
const globalFilterInput = rendered.getByPlaceholderText('Global search...')
|
||||||
|
|
||||||
|
fireEvent.change(globalFilterInput, { target: { value: '' } })
|
||||||
|
expect(
|
||||||
|
rendered
|
||||||
|
.queryAllByRole('row')
|
||||||
|
.slice(3)
|
||||||
|
.map(row => Array.from(row.children)[0].textContent)
|
||||||
|
).toEqual([
|
||||||
|
'firstName: tanner',
|
||||||
|
'firstName: derek',
|
||||||
|
'firstName: joe',
|
||||||
|
'firstName: jaylen',
|
||||||
|
])
|
||||||
|
|
||||||
|
// global filter shouldn't apply to firstName or lastName
|
||||||
|
fireEvent.change(globalFilterInput, { target: { value: 'li' } })
|
||||||
|
expect(
|
||||||
|
rendered
|
||||||
|
.queryAllByRole('row')
|
||||||
|
.slice(3)
|
||||||
|
.map(row => Array.from(row.children)[0].textContent)
|
||||||
|
).toEqual(['firstName: joe'])
|
||||||
|
|
||||||
|
// double check global filter ignore (should ignore joe bergevin)
|
||||||
|
fireEvent.change(globalFilterInput, { target: { value: 'in' } })
|
||||||
|
expect(
|
||||||
|
rendered
|
||||||
|
.queryAllByRole('row')
|
||||||
|
.slice(3)
|
||||||
|
.map(row => Array.from(row.children)[0].textContent)
|
||||||
|
).toEqual(['firstName: tanner', 'firstName: derek', 'firstName: jaylen'])
|
||||||
|
})
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import { getFilterMethod, shouldAutoRemoveFilter } from '../utils'
|
import {
|
||||||
|
getFilterMethod,
|
||||||
|
shouldAutoRemoveFilter,
|
||||||
|
getFirstDefined,
|
||||||
|
} from '../utils'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
actions,
|
actions,
|
||||||
@ -68,6 +72,7 @@ function useInstance(instance) {
|
|||||||
state: { globalFilter: globalFilterValue },
|
state: { globalFilter: globalFilterValue },
|
||||||
dispatch,
|
dispatch,
|
||||||
autoResetGlobalFilter = true,
|
autoResetGlobalFilter = true,
|
||||||
|
disableGlobalFilter,
|
||||||
} = instance
|
} = instance
|
||||||
|
|
||||||
const setGlobalFilter = React.useCallback(
|
const setGlobalFilter = React.useCallback(
|
||||||
@ -105,11 +110,23 @@ function useInstance(instance) {
|
|||||||
return rows
|
return rows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allColumns.forEach(column => {
|
||||||
|
const { disableGlobalFilter: columnDisableGlobalFilter } = column
|
||||||
|
|
||||||
|
column.canFilter = getFirstDefined(
|
||||||
|
columnDisableGlobalFilter === true ? false : undefined,
|
||||||
|
disableGlobalFilter === true ? false : undefined,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const filterableColumns = allColumns.filter(c => c.canFilter === true)
|
||||||
|
|
||||||
// Filters top level and nested rows
|
// Filters top level and nested rows
|
||||||
const filterRows = filteredRows => {
|
const filterRows = filteredRows => {
|
||||||
filteredRows = filterMethod(
|
filteredRows = filterMethod(
|
||||||
filteredRows,
|
filteredRows,
|
||||||
allColumns.map(d => d.id),
|
filterableColumns.map(d => d.id),
|
||||||
globalFilterValue
|
globalFilterValue
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -132,10 +149,11 @@ function useInstance(instance) {
|
|||||||
globalFilterValue,
|
globalFilterValue,
|
||||||
globalFilter,
|
globalFilter,
|
||||||
userFilterTypes,
|
userFilterTypes,
|
||||||
|
allColumns,
|
||||||
rows,
|
rows,
|
||||||
flatRows,
|
flatRows,
|
||||||
rowsById,
|
rowsById,
|
||||||
allColumns,
|
disableGlobalFilter,
|
||||||
])
|
])
|
||||||
|
|
||||||
const getAutoResetGlobalFilter = useGetLatest(autoResetGlobalFilter)
|
const getAutoResetGlobalFilter = useGetLatest(autoResetGlobalFilter)
|
||||||
@ -157,5 +175,6 @@ function useInstance(instance) {
|
|||||||
flatRows: globalFilteredFlatRows,
|
flatRows: globalFilteredFlatRows,
|
||||||
rowsById: globalFilteredRowsById,
|
rowsById: globalFilteredRowsById,
|
||||||
setGlobalFilter,
|
setGlobalFilter,
|
||||||
|
disableGlobalFilter,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user