gregnb / mui-datatables

Datatables for React using Material-UI
MIT License
2.71k stars 934 forks source link

Help wanted: Custom filter component changes not propagating to onFilterChange #1997

Closed patt1s0n closed 1 year ago

patt1s0n commented 1 year ago

I have a custom filter component which I am using to debounce the typing in a text field. With this component I call updateFilter I call it like so: updateFilter(value, columnIndex, 'custom', column); Where the columnIndex and column values come from the display callback (filterList: any, updateFilter: any, index: any, column: any). When updateFilter is called I can then see that onFilterChange is called, however the columnName is always undefined. I would expect that the changeColumn would be based on the data passed to updateFilter. What am I misunderstanding or doing wrong?

My custom component:

interface IProps {
    filterList: any;
    columnIndex: number;
    updateFilter: (value: any, columnIndex: number, filterType: string, columnName: any) => void;
    column: any;
    onChange: (val: string) => void;
    label: string;
}

export const DebouncedFilter = ({filterList, columnIndex, updateFilter, label, column, onChange}: IProps) => {
    const [filterText, setFilterText] = useState(filterList[columnIndex][0] || '');

    const debouncedUpdateFilter = useCallback(
        debounce((value, columnIndex) => {
            updateFilter(value, columnIndex, 'custom', column);
            // onChange(value)
        }, 300),
        [updateFilter]
    );

    useEffect(() => {
        return () => {
            debouncedUpdateFilter.clear(); // Clean up debounced function on component unmount
        };
    }, [debouncedUpdateFilter]);

    const handleChange = (event: { target: { value: any; }; }) => {
        const value = event.target.value;
        setFilterText(value);
        debouncedUpdateFilter(value, columnIndex);
    };

    return (
        <TextField
            label={label}
            value={filterText}
            onChange={handleChange}
            autoFocus
            fullWidth
        />
    );
};

The column options:

options: {
    filter: true,
    filterType: "custom" as FilterType,
    customFilterListOptions: {
        render: (v: any) => `Destination: ${v}`,
    },
    filterOptions: {
        names: [],
        display: (filterList: any, updateFilter: any, index: any, column: any) => {
            return (
                <DebouncedFilter
                    filterList={filterList}
                    columnIndex={index}
                    updateFilter={updateFilter}
                    column={column}
                    label="Destination"
                    onChange={(v: string) => setDestinationContains(v)}
                />
            );
        },
    },
},
patt1s0n commented 1 year ago

I got this working as I had the wrong values being passed to the updateFilter function.