Skip to content

Commit

Permalink
Tabulator: document how to set a *multiselect* header filter (#5825)
Browse files Browse the repository at this point in the history
* add multiselect test

* document multiselect
  • Loading branch information
maximlt authored Nov 6, 2023
1 parent a51f573 commit 0169933
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
22 changes: 8 additions & 14 deletions examples/reference/widgets/Tabulator.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@
"from bokeh.sampledata.movies_data import movie_path\n",
"\n",
"con = sqlite3.Connection(movie_path)\n",
"movies_df = pd.read_sql('SELECT Title, Year, Genre, Director, Writer, imdbRating from omdb', con)\n",
"movies_df = pd.read_sql('SELECT Title, Year, Genre, Director, Writer, Rating, imdbRating from omdb', con)\n",
"movies_df = movies_df[~movies_df.Director.isna()]\n",
"\n",
"movies_table = pn.widgets.Tabulator(movies_df, pagination='remote', page_size=4)"
Expand Down Expand Up @@ -997,7 +997,7 @@
"tabulator_editors = {\n",
" 'float': {'type': 'number', 'max': 10, 'step': 0.1},\n",
" 'bool': {'type': 'tickCross', 'tristate': True, 'indeterminateValue': None},\n",
" 'str': {'type': 'list', 'valuesLookup': True}\n",
" 'str': {'type': 'list', 'valuesLookup': True},\n",
"}\n",
"\n",
"header_filter_table = pn.widgets.Tabulator(\n",
Expand All @@ -1020,15 +1020,6 @@
"Try applying a filter and then inspect the `filters` parameter:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"header_filter_table.filters"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -1041,7 +1032,9 @@
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"movie_filters = {\n",
Expand All @@ -1050,11 +1043,12 @@
" 'Genre': {'type': 'input', 'func': 'like', 'placeholder': 'Enter genre'},\n",
" 'Director': {'type': 'input', 'func': 'like', 'placeholder': 'Enter director'},\n",
" 'Writer': {'type': 'input', 'func': 'like', 'placeholder': 'Enter writer'},\n",
" 'imdbRating': {'type': 'number', 'func': '>=', 'placeholder': 'Enter minimum rating'}\n",
" 'Rating': {'type': 'list', 'func': 'in', 'valuesLookup': True, 'sort': 'asc', 'multiselect': True},\n",
" 'imdbRating': {'type': 'number', 'func': '>=', 'placeholder': 'Enter minimum rating'},\n",
"}\n",
"\n",
"filter_table = pn.widgets.Tabulator(\n",
" movies_df, pagination='remote', layout='fit_columns', page_size=4, sizing_mode='stretch_width',\n",
" movies_df.iloc[:200], pagination='local', layout='fit_columns', page_size=4, sizing_mode='stretch_width',\n",
" header_filters=movie_filters\n",
")\n",
"filter_table"
Expand Down
33 changes: 33 additions & 0 deletions panel/tests/ui/widgets/test_tabulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1935,6 +1935,39 @@ def test_tabulator_header_filters_set_from_client(page, df_mixed):
wait_until(lambda: widget.current_view.equals(expected_filter_df), page)


def test_tabulator_header_filters_multiselect(page, df_mixed):
header_filters = {
'str': {
'type': 'list',
'func': 'in',
'valuesLookup': True,
'autocomplete': False,
'multiselect': True
},
}
widget = Tabulator(df_mixed, header_filters=header_filters, widths=dict(str=200))

serve_component(page, widget)

str_header = page.locator('input[type="search"]')
str_header.click()
cmp, col = 'in', 'str'
val = ['A', 'D']
for v in val:
item = page.locator(f'.tabulator-edit-list-item:has-text("{v}")')
item.click()
# Validating the filters doesn't have a very nice behavior, you need to lose
# focus on the multiselect by clicking somewhere else.
# Delay required before clicking for the focus to be lost and the filters accounted for.
page.wait_for_timeout(200)
page.locator('text="idx0"').click()
expected_filter_df = df_mixed.query(f'{col} {cmp} {val}')
expected_filter = {'field': col, 'type': cmp, 'value': val}
expect(page.locator('.tabulator-row')).to_have_count(len(expected_filter_df))
wait_until(lambda: widget.filters == [expected_filter], page)
wait_until(lambda: widget.current_view.equals(expected_filter_df), page)


def test_tabulator_download(page, df_mixed, df_mixed_as_string):
widget = Tabulator(df_mixed)

Expand Down

0 comments on commit 0169933

Please sign in to comment.