Im using React Table to display data I receive from an API call. Currently I save the state locally and the table displays the data. I have added filtering of column values for two columns. My filtering logic is as follows:
<ReactTable
data={tableData}
noDataText="Loading.."
filterable
defaultFilterMethod={(filter, row) =>
String(row[filter.id]) === filter.value}
};
}}
columns={[
{
columns: [
{
Header: 'Name',
accessor: 'Name',
id: 'Name',
Cell: ({ value }) => (value === 'group1' ?
'group1' : 'group2'),
filterMethod: (filter, row) => {
if (filter.value === 'all') {
return true;
}
if (filter.value === 'group1') {
return row[filter.id] === 'group1';
}
if (filter.value === 'group2') {
return row[filter.id] === 'group2';
}
},
Filter: ({ filter, onChange }) =>
<select
onChange={event => onChange(event.target.value)}
style={{ width: '100%' }}
value={filter ? filter.value : 'all'}
>
<option value="all">All</option>
<option value="group1">Group1</option>
<option value="group2">Group2</option>
</select>,
},
}
As of now, the filtering rule is hard coded between two values. How to implement the filter logic so that the filtering is dynamic?(If there are 3 or 7 different values in a particular column, the dropdown should display all 7 values and filter should work based on any of the value selected). Since Im using React Table(https://react-table.js.org).
I assume you wanted to make options out of list of options. If so, here is a way you can do it:
const exampleList = ['option1','option2','option3','option4',...,'option n']
In your column:
filterMethod: (filter, row) => customOptionsFilterMethod(filter, row),
Filter: () => ({filter, onChange}) => customOptionsFilter({filter, onChange})
Inside render() implement customOptionsFilter and customOptionsFilterMethod as:
const customOptionsFilter = ({filter, onChange}) => {
return(
<select
onChange={e => onChange(e.target.value)}
style={{ width: '100%' }}
value={filter ? filter.value : 'all'}
>
<option value='all'>Show All</option>
{
exampleList.map( k => {
return <option key={k.toString()} value={k}>{k}</option>
})
}
</select>
)
}
const customOptionsFilterMethod = (filter, row) => {
if(filter.value === '') { return true }
if(exampleList.includes(filter.value)){
return row[filter.id] === filter.value
} else { return true }
}
Haven't used the library, but it kind of sounds like something like this would work
if (filter.value === 'all') {
return true;
} else {
// what ever the value is, we will only
// show rows that have a column value
// that matches it
// If value is 'group1' just show the ones where the column
// value is 'group1', etc etc.
return row[filter.id] == filter.value;
}
Note that this will show nothing untill you get an exact match. So even if you have column values like "group1" the search term "grou" will not match it. If that's not the behaviour you want then you'd want to switch out
return row[filter.id] == filter.value;
to something like
return row[filter.id].indexOf(filter.value) >= 0;
As an alternative, if you need it to be more restricted than that, you could build your options from an array
const options = [ { value: "all" , label: "All" }, { value: "group1" , label: "Group1" }];
And use it like
<select
onChange={event => onChange(event.target.value)}
style={{ width: '100%' }}
value={filter ? filter.value : 'all'}
>
{ options.map(({value,label}) => <option value={value}>{label}</option>)}
</select>,
And in your filter logic you could check if the filter.value
value is in the 'options` array.
// check if there is some (any) value that matches the criteria
// of opt.value == filter.value
return options.some(opt => opt.value == filter.value);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With