Ag-Grid Custom Filtering

Hello @robertf,

There isnt currently a way to do this, but I have a PR pending that will fix it so that you can do something like this:

app.py

from dash import Dash, html
import dash_ag_grid as dag
import pandas as pd

app = Dash(__name__)

df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)

rowData = df.to_dict('records')

columnDefs = [
    { 'field': 'age', 'filter': 'agNumberColumnFilter' },
    { 'field': 'country', 'minWidth': 150 },
    { 'field': 'year', 'filter': {'function': 'YearFilter'}},
    {
      'field': 'date',
      'minWidth': 130,
      'filter': 'agDateColumnFilter',
      'filterParams': {
        'comparator': {'function':'dateComparator'},
      },
    },
    { 'field': 'sport' },
    { 'field': 'gold', 'filter': 'agNumberColumnFilter' },
    { 'field': 'silver', 'filter': 'agNumberColumnFilter' },
    { 'field': 'bronze', 'filter': 'agNumberColumnFilter' },
    { 'field': 'total', 'filter': 'agNumberColumnFilter' },
]

defaultColDef = {
    'editable': True,
    'sortable': True,
    'flex': 1,
    'minWidth': 100,
    'filter': True,
    'resizable': True,
}


app.layout = html.Div(
    [
        html.H3("See the custom filter component in the Year column"),
        dag.AgGrid(
            id="grid",
            columnDefs=columnDefs,
            rowData=rowData,
            defaultColDef=defaultColDef
        ),
    ]
)


if __name__ == "__main__":
    app.run(debug=True)

dashAgGridFunctions.js

This example was adapted from React Data Grid: Filter Component
The only differences are:

  • React.createElement instead of JSX
  • setProps, which all Dash components use to report user interactions, nstead of a plain js event handler
var dagfuncs = window.dashAgGridFunctions = window.dashAgGridFunctions || {};

const [useImperativeHandle, useState, useEffect, forwardRef, Component] = [React.useImperativeHandle, React.useState, React.useEffect, React.forwardRef, React.component]

dagfuncs.YearFilter = forwardRef((props, ref) => {
   const [year, setYear] = useState('All');

   useImperativeHandle(ref, () => {
       return {
           doesFilterPass(params) {
               return params.data.year >= 2010;
           },

           isFilterActive() {
               return year === '2010'
           },

           // this example isn't using getModel() and setModel(),
           // so safe to just leave these empty. don't do this in your code!!!
           getModel() {
           },

           setModel() {
           }
       }
   });

   useEffect(() => {
       props.filterChangedCallback()
   }, [year]);

    setProps = (props) => {
        if (props.value) {
            setYear(props.value)
        }
    }

    return React.createElement(
        window.dash_core_components.RadioItems,
        {
            options:[
                {'label': 'All', 'value': 'All'},
                {'label': 'Since 2010', 'value': '2010'},
            ],
            value: year,
            setProps
        }
        )
});

dagfuncs.dateComparator = function (filterLocalDateAtMidnight, cellValue) {

    const dateAsString = cellValue;
    const dateParts = dateAsString.split('/');
    const cellDate = new Date(
        Number(dateParts[2]),
        Number(dateParts[1]) - 1,
        Number(dateParts[0])
    );
    if (filterLocalDateAtMidnight.getTime() === cellDate.getTime()) {
        return 0;
    }
    if (cellDate < filterLocalDateAtMidnight) {
        return -1;
    }
    if (cellDate > filterLocalDateAtMidnight) {
        return 1;
    }

}
1 Like