4

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).

2
  • @SeaWarrior404..What does this " return row[filter.id] === 'group2'; " returns, ideally it should return true or false..I have doubt weather it returns boolean or any value....please clarify Commented Sep 13, 2017 at 6:01
  • Is this question still open? Unsolved? You seem to have moved on to other questions, but no response here.. Why? If my suggested answer doesn't work maybe you have the answer yourself by now, and you can answer your own question and accept it: stackoverflow.com/help/self-answer Commented Sep 20, 2017 at 7:48

2 Answers 2

7

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 }

    }
Sign up to request clarification or add additional context in comments.

1 Comment

I was very confused with what is Filter and filterMethod individually for, but if I am not wrong, Filter is to get the filter type on the view and filterMethod is to implement the filter itself. Please correct me if I am wrong.
1

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);

4 Comments

This approach works under certain conditions. However the answer I needed is not this. I left this open because there maybe another potential answer which may solve this problem. I have been busy with other parts of the app, so when I find a solution for this issue I will update accordingly.
Ok, thanks for the feedback. Maybe you could add more info to the question that highlights the kind of situations that my two suggested solutions doesn't solve?
Btw. Sorry for "nagging" and the blaming tone of my comment. It just looks bad when there is no response from OP on a question for a long time, even though the person is active on other questions. Some people just ask questions and then never come back to accept answers or give thanks, which goes against the idea of Stackoverflow. But I can also see how there might be other reasons for not responding at once, so sorry if I was being unfair.
Thats allright! As I mentioned above. I do value your answer, it surely did help me solve the issue upto some extent. So when I figure out a solution I will provide the solution myself. Appreciate your insight. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.