Skip to content

Commit dc0b294

Browse files
authored
bug(data frame filter): When the filter is reset, be sure to use a "" value for the input (#1557)
1 parent 76cee50 commit dc0b294

File tree

6 files changed

+100
-7
lines changed

6 files changed

+100
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
### Other changes
1313

14+
### Bug fixes
15+
16+
* Fixed bug where calling `.update_filter(None)` on a data frame renderer did not visually reset non-numeric column filters. (It did reset the column's filtering, just not the label). Now it resets filter's label. (#1557)
17+
1418
* Require shinyswatch >= 0.7.0 and updated examples accordingly. (#1558)
1519

1620
### Bug fixes

js/data-frame/filter.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,10 @@ export const Filter: FC<FilterProps> = ({ header, className, ...props }) => {
9494
return (
9595
<input
9696
{...props}
97-
value={header.column.getFilterValue() as string}
97+
// If there was a value and now there isn't,
98+
// set the filter value to `""` and not `undefined`.
99+
// `undefined` will not clear the displayed value.
100+
value={(header.column.getFilterValue() as string) || ""}
98101
className={`form-control form-control-sm ${className}`}
99102
type="text"
100103
onChange={(e) => header.column.setFilterValue(e.target.value)}

shiny/www/py-shiny/data-frame/data-frame.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

shiny/www/py-shiny/data-frame/data-frame.js.map

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from typing import cast
2+
3+
import pandas as pd
4+
from palmerpenguins import load_penguins # pyright: ignore[reportMissingTypeStubs]
5+
6+
from shiny import reactive
7+
from shiny.express import input, render, ui
8+
9+
penguins = cast(pd.DataFrame, load_penguins())
10+
11+
ui.input_action_button("update_filters", "Update filters")
12+
ui.input_action_button("reset_filters", "Reset filters")
13+
14+
ui.h5("Current filters: ", {"class": "pt-2"})
15+
16+
17+
@render.code
18+
def penguins_code():
19+
return str(penguins_df.filter())
20+
21+
22+
@render.data_frame
23+
def penguins_df():
24+
return render.DataGrid(penguins, filters=True)
25+
26+
27+
@reactive.effect
28+
@reactive.event(input.update_filters)
29+
async def _():
30+
await penguins_df.update_filter(
31+
[
32+
{"col": 0, "value": "Gentoo"},
33+
{"col": 2, "value": (50, None)},
34+
{"col": 3, "value": (None, 17)},
35+
{"col": 4, "value": (220, 225)},
36+
],
37+
)
38+
39+
40+
@reactive.effect
41+
@reactive.event(input.reset_filters)
42+
async def _():
43+
await penguins_df.update_filter(None) # <<
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from playwright.sync_api import Page, expect
2+
3+
from shiny.playwright import controller
4+
from shiny.run import ShinyAppProc
5+
6+
7+
def test_filters_are_reset(page: Page, local_app: ShinyAppProc) -> None:
8+
page.goto(local_app.url)
9+
10+
penguin_df = controller.OutputDataFrame(page, "penguins_df")
11+
penguin_code = controller.OutputCode(page, "penguins_code")
12+
update_filters = controller.InputActionButton(page, "update_filters")
13+
reset_filters = controller.InputActionButton(page, "reset_filters")
14+
15+
filter_inputs = penguin_df.loc_column_filter.locator("input")
16+
17+
expect(filter_inputs).to_have_count(8 + 5) # 8 columns including 5 numeric columns
18+
19+
penguin_code.expect_value("()")
20+
for element in filter_inputs.element_handles():
21+
assert element.input_value() == ""
22+
23+
update_filters.click()
24+
25+
penguin_code.expect_value(
26+
"("
27+
"{'col': 0, 'value': 'Gentoo'}, "
28+
"{'col': 2, 'value': (50, None)}, "
29+
"{'col': 3, 'value': (None, 17)}, "
30+
"{'col': 4, 'value': (220, 225)}"
31+
")"
32+
)
33+
for value, element in zip(
34+
["Gentoo", "", "50", "", "", "17", "220", "225", "", "", "", "", ""],
35+
filter_inputs.element_handles(),
36+
):
37+
assert element.input_value() == value
38+
39+
reset_filters.click()
40+
41+
penguin_code.expect_value("()")
42+
for element in filter_inputs.element_handles():
43+
assert element.input_value() == ""

0 commit comments

Comments
 (0)