Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Links "DE#nnn" prior to version 2.0 point to the Dash Enterprise closed-source D
- [#408](https://github.com/plotly/dash-ag-grid/pull/408) fixed issue where the `columnState` would conflict with `columnDefs` updates
- fixes [#416] (https://github.com/plotly/dash-ag-grid/issues/416)
- fixes [#407](https://github.com/plotly/dash-ag-grid/issues/407)
- [#412](https://github.com/plotly/dash-ag-grid/issues/412) fix "Multi-Column Filter not properly recognized in filterParams"

## [33.3.2rc2] - 2025-09-17

Expand Down
1 change: 1 addition & 0 deletions src/lib/utils/propCategories.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ export const COLUMN_NESTED_OR_OBJ_OF_FUNCTIONS = {
export const COLUMN_ARRAY_NESTED_FUNCTIONS = {
children: 1,
filterOptions: 1,
filters: 1,
};

/**
Expand Down
38 changes: 37 additions & 1 deletion tests/assets/dashAgGridFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,41 @@ dagfuncs.startWith = ([filterValues], cellValue) => {
const name = cellValue ? cellValue.split(" ")[1] : ""
return name && name.toLowerCase().indexOf(filterValues.toLowerCase()) === 0
}

dagfuncs.dateFilterComparator = (filterLocalDateAtMidnight, cellValue) => {
const dateAsString = cellValue;

if (dateAsString == null) {
// Return -1 to show nulls "before" any date
return -1;
}

// The data from this CSV is in dd/mm/yyyy format
const dateParts = dateAsString.split("/");
if (dateParts.length !== 3) {
// Handle invalid format
return 0;
}

const day = Number(dateParts[0]);
const month = Number(dateParts[1]) - 1; // JS months are 0-indexed
const year = Number(dateParts[2]);
const cellDate = new Date(year, month, day);

// Check for invalid date (e.g., from "NaN")
if (isNaN(cellDate.getTime())) {
return 0;
}

// Now that both parameters are Date objects, we can compare
if (cellDate < filterLocalDateAtMidnight) {
return -1;
} else if (cellDate > filterLocalDateAtMidnight) {
return 1;
}
return 0;
};

// END test_custom_filter.py

// FOR test_quick_filter.py
Expand Down Expand Up @@ -502,4 +537,5 @@ dagfuncs.TestEvent = (params, setEventData) => {

dagfuncs.testToyota = (params) => {
return params.data.make == 'Toyota' ? {'color': 'blue'} : {}
}
}

96 changes: 96 additions & 0 deletions tests/test_custom_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,99 @@ def test_fi005_custom_filter(dash_duo):
# Test numberParser and numberFormatter
grid.set_filter(0, "$100,5")
grid.wait_for_cell_text(0, 0, "$200,00")

def test_fi006_custom_filter(dash_duo):
app = Dash(__name__)

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

columnDefs = [
{"field": "athlete",
"filter": "agMultiColumnFilter",
"filterParams": {
"filters": [
{"filter": "agTextColumnFilter"},
{"filter": "agSetColumnFilter"} # Example with Set Filter
]
}},
{"field": "country"},
{
"field": "date",
"filter": "agMultiColumnFilter",
"filterParams": {
"filters": [
{
"filter": "agSetColumnFilter",
'filterParams': {'excelMode': 'windows', 'buttons': ['apply', 'reset'],
}
},
{
"filter": "agDateColumnFilter",
'filterParams': {
'excelMode': 'windows',
'buttons': ['apply', 'reset'],
'comparator': {'function': 'dateFilterComparator'},
}
},
],

},
},
]


app.layout = html.Div(
[
dag.AgGrid(
id="date-filter-example",
enableEnterpriseModules=True,
columnDefs=columnDefs,
rowData=df.to_dict("records"),
defaultColDef={"flex": 1, "minWidth": 150, "floatingFilter": True},
dashGridOptions={"animateRows": False}
),
],
)

dash_duo.start_server(app)

grid = utils.Grid(dash_duo, "date-filter-example")

# Wait for grid to load
grid.wait_for_cell_text(0, 0, "Michael Phelps")

# Test Set Filter - select a date from the checkbox list
dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click()

# Uncheck "Select All"
dash_duo.find_element('.ag-set-filter-list .ag-set-filter-item .ag-checkbox-input').click()

# Select "24/08/2008"
set_filter_items = dash_duo.find_elements('.ag-set-filter-list .ag-virtual-list-item')
for item in set_filter_items:
if "24/08/2008" in item.text:
item.find_element_by_css_selector('.ag-checkbox-input').click()
break

# Apply and verify
dash_duo.find_element('button[ref="applyFilterButton"]').click()
grid.wait_for_cell_text(0, 2, "24/08/2008")

# Reset
dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click()
dash_duo.find_element('button[ref="resetFilterButton"]').click()

# Test Date Filter - type a date in the input field
dash_duo.find_element('.ag-header-cell[aria-colindex="3"] span[data-ref="eFilterButton"]').click()

# Switch to Date Filter tab
dash_duo.find_elements('.ag-tabs-header .ag-tab')[1].click()

# Type date and apply
dash_duo.find_element('.ag-date-filter input[class*="ag-input-field-input"]').send_keys("24/08/2008")
dash_duo.find_element('button[ref="applyFilterButton"]').click()

# Verify
grid.wait_for_cell_text(0, 2, "24/08/2008")
Loading