React-table date range filter

13.7k views Asked by At

I'm trying to implement a date range filter in my React-table. When I'm changing the start or end date, it triggers the filter function, creating the min and max date but when it finishes no dates are being filtered and the input is empty from the chosen date. this is my code:

const ChartData = () => {
const columns = React.useMemo(
() => [
  {
    Header: "Date",
    columns: [
      {
        Header: "Date",
        accessor: "date",
        id: "date",
        Filter: chartFilter.DateRangeColumnFilter,
        filter: "between"
      }
    ]
  }
],
[]
);

const data = React.useMemo(() => dummyData(100000), []);

return (
   <div className={classes.tableWrapper}>
      <Table columns={columns} data={data} />
   </div>
 );
};
export default ChartData;

filter page:

  export function DateRangeColumnFilter({
     column: { filterValue = [], preFilteredRows, setFilter, id }
     }) {
     const [min, max] = React.useMemo(() => {
     let min = preFilteredRows.length ? new Date(preFilteredRows[0].values[id]).getTime() : 0;
     let max = preFilteredRows.length ? new Date(preFilteredRows[0].values[id]).getTime() : 0;

  preFilteredRows.forEach((row) => {
     min = Math.min(new Date(row.values[id]).getTime(), min);
     max = Math.max(new Date(row.values[id]).getTime(), max);
   });
  return [min, max];
 }, [id, preFilteredRows]);

 return (
<div style={{display: "flex"}}>
  <input
    value={filterValue[0] || ""}
    type="date"
    onChange={(e) => {
      const val = e.target.value;
      setFilter((old = []) => [val || undefined, old[1]]);
    }}
    style={{
      width: "70px",
      marginRight: "0.5rem"
    }}
  />
  to
  <input
    value={filterValue[1] || ""}
    type="date"
    onChange={(e) => {
      const val = e.target.value;
      setFilter((old = []) => [old[0], val || undefined]);
    }}
    style={{
      width: "70px",
      marginLeft: "0.5rem"
    }}
  />
 </div>
 );
}

What I'm missing here?

1

There are 1 answers

1
Ahmed Ahmed Sayed On

So i was having the same trouble here is my solution

i have used flatpickr , moment

DateFilter.tsx

export const DateFilter = ({
  column: {
    filterValue,
    setFilter,
    preFilteredRows,
    id,
  },
  rows
}: any) => {
  const dates = preFilteredRows.map((val: any) => moment(val.original[id],dateFormat))
  const minDate = moment.min(dates).subtract(1,'day') // To include the date
  const maxDate = moment.max(dates).add(1, 'day') 
  return (
    <React.Fragment>
      <Flatpickr
        className='form-control'
        onChange={(date) => {
          if (date.length === 2) {
            setFilter([date[0],date[1]])
          }
        }}
        options={{
          enable: [
            {
              from: minDate.toDate(),
              to : maxDate.toDate()
            }
          ],
          mode : 'range'
        }}
      />

  </React.Fragment>

); };

now un your mainTable component file . add a constant called filtertypes . and here is the object

      const filterTypes : any = {
        date: (rows: any[], id: any, filterValue: any) => {
          let start = moment(filterValue[0]).subtract(1, 'day')
          let end = moment(filterValue[1]).add(1, 'day')
          return rows.filter(val => 
           moment(val.original[id],dateFormat).isBetween(start, end);
          )
        }
}

Don't forget to add Filter and filter properties in your column definition