Skip to content

Latest commit

 

History

History
144 lines (100 loc) · 5.37 KB

File metadata and controls

144 lines (100 loc) · 5.37 KB

Responding to Events

IDOM lets you add event handlers to your parts of the interface. These events handlers are functions which can be assigned to a part of a UI such that, when a user iteracts with the interface, those functions get triggered. Examples of interaction include clicking, hovering, of focusing on form inputs, and more.

Adding Event Handlers

To start out we'll just display a button that, for the moment, doesn't do anything:

.. idom:: _examples/button_does_nothing

To add an event handler to this button we'll do three things:

  1. Declare a function called handle_event(event) inside the body of our Button component
  2. Add logic to handle_event that will print the event it receives to the console.
  3. Add an "onClick": handle_event attribute to the <button> element.
.. idom:: _examples/button_prints_event

Note

Normally print statements will only be displayed in the terminal where you launched IDOM.

It may feel weird to define a function within a function like this, but doing so allows the handle_event function to access information from within the scope of the component. That's important if you want to use any arguments that may have beend passed your component in the handler:

.. idom:: _examples/button_prints_message

With all that said, since our handle_event function isn't doing that much work, if we wanted to streamline our component definition, we could pass in our event handler as a lambda:

html.button({"onClick": lambda event: print(message_text)}, "Click me!")

Supported Event Types

Since IDOM's event information comes from React, most the the information (:ref:`with some exceptions <event data Serialization>`) about how React handles events translates directly to IDOM. Follow the links below to learn about each category of event:

Passing Handlers to Components

A common pattern when factoring out common logic is to pass event handlers into a more generic component definition. This allows the component to focus on the things which are common while still giving its usages customizablity. Consider the case below where we want to create a generic Button component that can be used for a variety of purpose:

.. idom:: _examples/button_handler_as_arg


Async Event Handlers

Sometimes event handlers need to execute asynchronous tasks when they are triggered. Behind the scenes, IDOM is running an :mod:`asyncio` event loop for just this purpose. By defining your event handler as an asynchronous function instead of a normal synchronous one. In the layout below we sleep for several seconds before printing out a message in the first button. However, because the event handler is asynchronous, the handler for the second button is still able to respond:

.. idom:: _examples/button_async_handlers


Event Data Serialization

Not all event data is serialized. The most notable example of this is the lack of a target key in the dictionary sent back to the handler. Instead, data which is not inherently JSON serializable must be treated on a case-by-case basis. A simple case to demonstrate this is the currentTime attribute of audio and video elements. Normally this would be accessible via event.target.currentTime, but here it's simply passed in under the key currentTime:

.. idom:: _examples/audio_player


Client-side Event Behavior

Because IDOM operates server-side, there are inevitable limitations that prevent it from achieving perfect parity with all the behaviors of React. With that said, any feature that cannot be achieved in Python with IDOM, can be done by creating :ref:`Custom Javascript Components`.

Preventing Default Event Actions

Instead of calling an event.preventDefault() method as you would do in React, you must declare whether to prevent default behavior ahead of time. This can be accomplished using the :func:`~idom.core.events.event` decorator and setting prevent_default. For example, we can stop a link from going to the specified URL:

.. idom:: _examples/prevent_default_event_actions

Unfortunately this means you cannot conditionally prevent default behavior in response to event data without writing :ref:`Custom Javascript Components`.

Stop Event Propogation

Similarly to :ref:`preventing default behavior <Preventing Default Event Actions>`, you can use the :func:`~idom.core.events.event` decorator to prevent events originating in a child element from propagating to parent elements by setting stop_propagation. In the example below we place a red div inside a parent blue div. When propogation is turned on, clicking the red element will cause the handler for the outer blue one to trigger. Conversely, when it's off, only the handler for the red element will trigger.

.. idom:: _examples/stop_event_propagation