Open
Description
Description
I have a modal that opens when a user clicks on a row from render.DataGrid
. This works great! However, when the "upstream" data changes and the resulting data in render.DataGrid
changes, the modal opens again.
The expected behaviour would be that the modal should not re-open, as no value is selected.
I could be missing something about the correct way to implement this. But I cannot figure it out!
Recording
The unexpected behaviour happens at the 9 second mark.
Screenshot.2024-05-09.at.15.41.30.mp4
Reprex
shiny==0.9.0
anyio==4.3.0
appdirs==1.4.4
asgiref==3.8.1
click==8.1.7
h11==0.14.0
htmltools==0.5.1
idna==3.7
linkify-it-py==2.0.3
markdown-it-py==3.0.0
mdit-py-plugins==0.4.0
mdurl==0.1.2
numpy==1.26.4
packaging==24.0
pandas==2.2.2
prompt-toolkit==3.0.36
python-dateutil==2.9.0.post0
python-multipart==0.0.9
pytz==2024.1
questionary==2.0.1
shiny==0.9.0
six==1.16.0
sniffio==1.3.1
starlette==0.37.2
typing-extensions==4.11.0
tzdata==2024.1
uc-micro-py==1.0.3
uvicorn==0.29.0
watchfiles==0.21.0
wcwidth==0.2.13
websockets==12.0
import pandas as pd
import numpy as np
from shiny import App, reactive, render, req, ui
categories = ["Category1", "Category2", "Category3", "Category4", "Category5"]
df = pd.DataFrame({
"category": pd.Categorical(categories * 4),
"number": np.random.rand(20),
})
app_ui = ui.page_fillable(
ui.input_select("category", "Select a category", categories),
ui.card(ui.output_data_frame("data")),
)
def server(input, output, session):
@render.data_frame
def data():
selected_category = input.category()
return render.DataGrid(
df.loc[df["category"] == selected_category, :],
selection_mode="row"
)
@reactive.effect
def show_modal():
data_selected = data.data_view(selected=True)
req(not data_selected.empty)
print(data_selected)
modal = ui.modal(
ui.tags.code(data_selected.to_json(orient="records"))
)
ui.modal_show(modal)
app = App(app_ui, server)
Possible solutions
Use .update_cell_selection(None)
This still results in the same behaviour.
Also, it is correct that data_table.update_cell_selection(None)
needs to be run in an async function?
import pandas as pd
import numpy as np
from shiny import App, reactive, render, req, ui
categories = ["Category1", "Category2", "Category3", "Category4", "Category5"]
df = pd.DataFrame({
"category": pd.Categorical(categories * 4),
"number": np.random.rand(20),
})
app_ui = ui.page_fillable(
ui.input_select("category", "Select a category", categories),
ui.card(ui.output_data_frame("data_table")),
)
def server(input, output, session):
@reactive.calc
def filter_data() -> pd.DataFrame:
print("Data updating ------------------------------------------")
selected_category = input.category()
return df.loc[df["category"] == selected_category, :]
@render.data_frame
def data_table():
print("Updating table output.")
return render.DataGrid(filter_data(), selection_mode="row")
# Why does `data_table.update_cell_selection` need to be async?
@reactive.effect(priority=99)
@reactive.event(filter_data)
async def clear_selection():
print("Clearing selection")
await data_table.update_cell_selection(None)
@reactive.effect
@reactive.event(data_table.input_cell_selection, ignore_init=True, ignore_none=True)
def show_modal():
print("Deciding to show modal...")
data_selected = data_table.data_view(selected=True)
print(data_selected.to_json(orient="records"))
req(not data_selected.empty)
print("Showing modal")
modal = ui.modal(ui.tags.code(data_selected.to_json(orient="records")))
ui.modal_show(modal)
app = App(app_ui, server)