Bladeren bron

introduce emitEvent and ui.on

Falko Schindler 1 jaar geleden
bovenliggende
commit
f4432a4836

+ 1 - 2
nicegui/events.py

@@ -392,8 +392,7 @@ def handle_event(handler: Optional[Callable[..., Any]], arguments: EventArgument
         if isinstance(arguments, UiEventArguments):
         if isinstance(arguments, UiEventArguments):
             if arguments.sender.is_ignoring_events:
             if arguments.sender.is_ignoring_events:
                 return
                 return
-            assert arguments.sender.parent_slot is not None
-            parent_slot = arguments.sender.parent_slot
+            parent_slot = arguments.sender.parent_slot or arguments.sender.client.layout.default_slot
         else:
         else:
             parent_slot = nullcontext()
             parent_slot = nullcontext()
 
 

+ 23 - 0
nicegui/functions/on.py

@@ -0,0 +1,23 @@
+from typing import Any, Callable, Optional, Sequence, Union
+
+from .. import context
+
+
+def on(type: str,  # pylint: disable=redefined-builtin
+       handler: Optional[Callable[..., Any]] = None,
+       args: Union[None, Sequence[str], Sequence[Optional[Sequence[str]]]] = None, *,
+       throttle: float = 0.0,
+       leading_events: bool = True,
+       trailing_events: bool = True,
+       ):
+    """Subscribe to a global event.
+
+    :param type: name of the event
+    :param handler: callback that is called upon occurrence of the event
+    :param args: arguments included in the event message sent to the event handler (default: `None` meaning all)
+    :param throttle: minimum time (in seconds) between event occurrences (default: 0.0)
+    :param leading_events: whether to trigger the event handler immediately upon the first event occurrence (default: `True`)
+    :param trailing_events: whether to trigger the event handler after the last event occurrence (default: `True`)
+    """
+    context.get_client().layout.on(type, handler, args,
+                                   throttle=throttle, leading_events=leading_events, trailing_events=trailing_events)

+ 3 - 0
nicegui/templates/index.html

@@ -54,6 +54,9 @@
           return element.$refs.qRef[method_name](...args);
           return element.$refs.qRef[method_name](...args);
         }
         }
       }
       }
+      function emitEvent(event_name, ...args) {
+        getElement(0).$emit(event_name, ...args);
+      }
     </script>
     </script>
     <script type="module">
     <script type="module">
       const True = true;
       const True = true;

+ 2 - 0
nicegui/ui.py

@@ -97,6 +97,7 @@ __all__ = [
     'footer',
     'footer',
     'header',
     'header',
     'left_drawer',
     'left_drawer',
+    'on',
     'page_sticky',
     'page_sticky',
     'right_drawer',
     'right_drawer',
     'run',
     'run',
@@ -190,6 +191,7 @@ from .functions.download import download
 from .functions.html import add_body_html, add_head_html
 from .functions.html import add_body_html, add_head_html
 from .functions.javascript import run_javascript
 from .functions.javascript import run_javascript
 from .functions.notify import notify
 from .functions.notify import notify
+from .functions.on import on
 from .functions.open import open  # pylint: disable=redefined-builtin
 from .functions.open import open  # pylint: disable=redefined-builtin
 from .functions.page_title import page_title
 from .functions.page_title import page_title
 from .functions.refreshable import refreshable, state
 from .functions.refreshable import refreshable, state

+ 18 - 16
website/documentation/content/generic_events_documentation.py

@@ -99,26 +99,28 @@ def modifiers() -> None:
 
 
 
 
 @doc.demo('Custom events', '''
 @doc.demo('Custom events', '''
-    It is fairly easy to emit custom events from JavaScript which can be listened to with `element.on(...)`.
+    It is fairly easy to emit custom events from JavaScript with `emitEvent(...)` which can be listened to with `ui.on(...)`.
     This can be useful if you want to call Python code when something happens in JavaScript.
     This can be useful if you want to call Python code when something happens in JavaScript.
     In this example we are listening to the `visibilitychange` event of the browser tab.
     In this example we are listening to the `visibilitychange` event of the browser tab.
 ''')
 ''')
 async def custom_events() -> None:
 async def custom_events() -> None:
-    tabwatch = ui.checkbox('Watch browser tab re-entering') \
-        .on('tabvisible', lambda: ui.notify('Welcome back!') if tabwatch.value else None, args=[])
-    ui.add_head_html(f'''
-        <script>
-        document.addEventListener('visibilitychange', () => {{
-            if (document.visibilityState === 'visible')
-                getElement({tabwatch.id}).$emit('tabvisible');
-        }});
-        </script>
-    ''')
+    tabwatch = ui.checkbox('Watch browser tab re-entering')
+    ui.on('tabvisible', lambda: ui.notify('Welcome back!') if tabwatch.value else None)
+    # ui.add_head_html('''
+    #     <script>
+    #     document.addEventListener('visibilitychange', () => {
+    #         if (document.visibilityState === 'visible') {
+    #             emitEvent('tabvisible');
+    #         }
+    #     });
+    #     </script>
+    # ''')
     # END OF DEMO
     # END OF DEMO
     await context.get_client().connected()
     await context.get_client().connected()
-    ui.run_javascript(f'''
-        document.addEventListener('visibilitychange', () => {{
-            if (document.visibilityState === 'visible')
-                getElement({tabwatch.id}).$emit('tabvisible');
-        }});
+    ui.run_javascript('''
+        document.addEventListener('visibilitychange', () => {
+            if (document.visibilityState === 'visible') {
+                emitEvent('tabvisible');
+            }
+        });
     ''')
     ''')