| 
1 | 1 | from starlette.requests import Request  | 
2 | 2 | 
 
  | 
3 |  | -from shiny import App, Inputs, Outputs, Session, module, ui  | 
 | 3 | +from shiny import App, Inputs, Outputs, Session, module, reactive, render, ui  | 
4 | 4 | from shiny.bookmark import BookmarkState, RestoreState  | 
5 | 5 | 
 
  | 
6 | 6 | 
 
  | 
7 | 7 | @module.ui  | 
8 |  | -def mod_ui(label: str):  | 
 | 8 | +def mod_ui():  | 
9 | 9 |     return ui.div(  | 
10 |  | -        ui.input_text("text", f"{label} Text", "Initial Module Text"),  | 
11 |  | -        ui.input_numeric("num", f"{label} Numeric", 1),  | 
12 |  | -        ui.input_text("excluded", f"{label} Excluded", "Module Excluded"),  | 
 | 10 | +        ui.input_text("text_in", "Initial Module Text"),  | 
 | 11 | +        ui.output_text("included_module_text"),  | 
 | 12 | +        ui.input_numeric("num_in", "Enter number", 1),  | 
 | 13 | +        ui.output_text("included_module_num"),  | 
 | 14 | +        ui.input_text("text_excl", "Module Excluded"),  | 
 | 15 | +        ui.output_text("excluded_module_text"),  | 
13 | 16 |     )  | 
14 | 17 | 
 
  | 
15 | 18 | 
 
  | 
16 | 19 | @module.server  | 
17 | 20 | def mod_server(input: Inputs, output: Outputs, session: Session):  | 
18 |  | -    session.bookmark.exclude.append("excluded")  | 
 | 21 | +    # 1. Fix: Correct input ID for exclusion  | 
 | 22 | +    session.bookmark.exclude.append("text_excl")  # Changed from "excluded"  | 
 | 23 | + | 
 | 24 | +    @render.text  | 
 | 25 | +    def included_module_text():  | 
 | 26 | +        return f"Included text: {input.text_in()}"  | 
 | 27 | + | 
 | 28 | +    @render.text  | 
 | 29 | +    def included_module_num():  | 
 | 30 | +        return f"Included num: {input.num_in()}"  | 
 | 31 | + | 
 | 32 | +    @render.text  | 
 | 33 | +    def excluded_module_text():  | 
 | 34 | +        return f"Excluded text: {input.text_excl()}"  | 
 | 35 | + | 
 | 36 | +    # 2. Add: Trigger bookmarking when inputs change  | 
 | 37 | +    @reactive.effect  | 
 | 38 | +    @reactive.event(input.text_in, input.num_in, ignore_init=True)  | 
 | 39 | +    async def _():  | 
 | 40 | +        await session.bookmark()  | 
19 | 41 | 
 
  | 
20 | 42 |     @session.bookmark.on_bookmark  | 
21 | 43 |     async def _(state: BookmarkState):  | 
22 |  | -        state.values["module_num"] = input.num()  | 
 | 44 | +        # 3. Store the value directly  | 
 | 45 | +        state.values["module_num"] = input.num_in()  | 
23 | 46 | 
 
  | 
24 | 47 |     @session.bookmark.on_restore  | 
25 | 48 |     def _(state: RestoreState):  | 
 | 49 | +        # 4. Fix: Correct key name and input access  | 
26 | 50 |         if "module_num" in state.values:  | 
27 |  | -            ui.update_numeric("num", value=state.values["module_num"])  | 
28 |  | -        if "text" in state.input:  | 
29 |  | -            print(f"module on_restore: text: {state.input['text']}")  | 
 | 51 | +            ui.update_numeric("num_in", value=state.values["module_num"])  | 
 | 52 | + | 
 | 53 | +        # 5. Fix: Correct input access for module  | 
 | 54 | +        if "text_in" in state.input:  | 
 | 55 | +            print(f"module on_restore: text: {state.input['text_in']}")  | 
30 | 56 | 
 
  | 
31 | 57 | 
 
  | 
32 | 58 | def app_ui(request: Request):  | 
33 | 59 |     return ui.page_fluid(  | 
34 |  | -        mod_ui("mod1", "Module 1"),  | 
35 |  | -        mod_ui("mod2", "Module 2"),  | 
 | 60 | +        mod_ui("mod1"),  | 
36 | 61 |         ui.input_bookmark_button(),  | 
37 | 62 |     )  | 
38 | 63 | 
 
  | 
39 | 64 | 
 
  | 
40 | 65 | def server(input: Inputs, output: Outputs, session: Session):  | 
41 | 66 |     mod_server("mod1")  | 
42 |  | -    mod_server("mod2")  | 
43 | 67 | 
 
  | 
44 | 68 |     @session.bookmark.on_bookmarked  | 
45 | 69 |     async def _(url: str):  | 
 | 
0 commit comments