Skip to content

Commit a7c3c85

Browse files
committed
add event handlers docs
1 parent e84b9d6 commit a7c3c85

7 files changed

+157
-1
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import json
2+
3+
import idom
4+
5+
6+
@idom.component
7+
def PlayDinosaurSound():
8+
event, set_event = idom.hooks.use_state(None)
9+
return idom.html.div(
10+
idom.html.audio(
11+
{
12+
"controls": True,
13+
"onTimeUpdate": lambda e: set_event(e),
14+
"src": "https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3",
15+
}
16+
),
17+
idom.html.pre(json.dumps(event, indent=2)),
18+
)
19+
20+
21+
idom.run(PlayDinosaurSound)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import idom
2+
3+
4+
@idom.component
5+
def DoNotChangePages():
6+
return idom.html.div(
7+
idom.html.p("Normally clicking this link would take you to a new page"),
8+
idom.html.a(
9+
{
10+
"onClick": idom.event(lambda e: None, prevent_default=True),
11+
"href": "https://google.com",
12+
},
13+
"https://google.com",
14+
),
15+
)
16+
17+
18+
idom.run(DoNotChangePages)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import json
2+
3+
import idom
4+
5+
6+
@idom.component
7+
def BasicButton():
8+
event, set_event = idom.hooks.use_state(None)
9+
return idom.html.div(
10+
idom.html.button({"onClick": lambda e: set_event(e)}, "click to see event"),
11+
idom.html.pre(json.dumps(event, indent=2)),
12+
)
13+
14+
15+
idom.run(BasicButton)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import idom
2+
3+
4+
@idom.component
5+
def DivInDiv():
6+
stop_propagatation, set_stop_propagatation = idom.hooks.use_state(True)
7+
inner_count, set_inner_count = idom.hooks.use_state(0)
8+
outer_count, set_outer_count = idom.hooks.use_state(0)
9+
10+
div_in_div = idom.html.div(
11+
{
12+
"onClick": idom.event(lambda e: set_outer_count(outer_count + 1)),
13+
"style": {"height": "100px", "width": "100px", "backgroundColor": "red"},
14+
},
15+
idom.html.div(
16+
{
17+
"onClick": idom.event(
18+
lambda e: set_inner_count(inner_count + 1),
19+
stop_propagation=stop_propagatation,
20+
),
21+
"style": {"height": "50px", "width": "50px", "backgroundColor": "blue"},
22+
},
23+
),
24+
)
25+
26+
return idom.html.div(
27+
idom.html.button(
28+
{"onClick": lambda e: set_stop_propagatation(not stop_propagatation)},
29+
f"Toggle Propogation",
30+
),
31+
idom.html.pre(f"Will stop propagation: {stop_propagatation}"),
32+
idom.html.pre(f"Inner click count: {inner_count}"),
33+
idom.html.pre(f"Outer click count: {outer_count}"),
34+
div_in_div,
35+
)
36+
37+
38+
idom.run(DivInDiv)

docs/source/faq.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ favorite Python packages with IDOM.
1616
Does IDOM transpile Python to Javascript?
1717
-----------------------------------------
1818

19-
No. As in the answer to :ref:`Do UI components run server-side?`, IDOM runs almost
19+
No. As in the answer to :ref:`Do UI components run client-side?`, IDOM runs almost
2020
everything server-side and in Python. This was an explicit design choice to keep things
2121
simple and one which allows you to do everything you normally would in Python.
2222

docs/source/handling-events.rst

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
Handling Events
2+
===============
3+
4+
When :ref:`Getting Started`, we saw how IDOM makes it possible to write server-side code
5+
that defines basic views and can react to client-side events. The simplest way to listen
6+
and respond to events is by assigning a callable object to a :ref:`VDOM <VDOM Mimetype>`
7+
an attribute where event signals are sent. This is relatively similar to
8+
`handling events in React`_:
9+
10+
.. _handling events in React: https://reactjs.org/docs/handling-events.html
11+
12+
.. example:: show_click_event
13+
14+
15+
Differences With React Events
16+
-----------------------------
17+
18+
Because IDOM operates server-side, there are inevitable limitations that prevent it from
19+
achieving perfect parity with all the behaviors of React. With that said, any feature
20+
that cannot be achieved in Python with IDOM, can be done by creating
21+
:ref:`Custom Javascript Components`.
22+
23+
24+
Preventing Default Event Actions
25+
................................
26+
27+
Instead of calling an ``event.preventDefault()`` method as you would do in React, you
28+
must declare whether to prevent default behavior ahead of time. This can be accomplished
29+
using the :func:`~idom.core.events.event` decorator and setting ``prevent_default``. For
30+
example, we can stop a link from going to the specified URL:
31+
32+
.. example:: prevent_default_event_actions
33+
34+
Unfortunately this means you cannot conditionally prevent default behavior in response
35+
to event data without writing :ref:`Custom Javascript Components`.
36+
37+
38+
Stop Event Propogation
39+
......................
40+
41+
Similarly to :ref:`preventing default behavior <Preventing Default Event Actions>`, you
42+
can use the :func:`~idom.core.events.event` decorator to forward declare whether or not
43+
you want events from a child element propogate up through the document to parent
44+
elements by setting ``stop_propagation``. In the example below we place a red ``div``
45+
inside a parent blue ``div``. When propogation is turned on, clicking the red element
46+
will cause the handler for the outer blue one to fire. Conversely, when it's off, only
47+
the handler for the red element will fire.
48+
49+
.. example:: stop_event_propagation
50+
51+
52+
Event Data Serialization
53+
........................
54+
55+
Not all event data is serialized. The most notable example of this is the lack of a
56+
``target`` key in the dictionary sent back to the handler. Instead, data which is not
57+
inherhently JSON serializable must be treated on a case-by-case basis. A simple case
58+
to demonstrate this is the ``currentTime`` attribute of ``audio`` and ``video``
59+
elements. Normally this would be accessible via ``event.target.currenTime``, but here
60+
it's simply passed in under the key ``currentTime``:
61+
62+
.. example:: play_audio_sound

docs/source/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ IDOM
33

44
.. toctree::
55
:hidden:
6+
:caption: User Guide
67

78
installation
89
getting-started
10+
handling-events
911
life-cycle-hooks
1012
auto/api-reference
1113
examples

0 commit comments

Comments
 (0)