Write responsive web apps in full python
—
Event system for handling user interactions including clicks, form changes, focus events, and custom events. Lona's event system enables real-time interactivity by allowing views to wait for and respond to user actions asynchronously.
Predefined event types for common user interactions.
# Event type constants
CLICK: int # Click events on interactive elements
CHANGE: int # Change events on form inputs
FOCUS: int # Focus events when elements gain focus
BLUR: int # Blur events when elements lose focusClasses for representing and handling user input events.
class InputEvent:
def __init__(self, event_type: int, node: 'Node', data: dict = None):
"""
Represents a user input event with complete context information.
Args:
event_type (int): Type of event (CLICK, CHANGE, etc.)
node (Node): HTML node that triggered the event
data (dict): Additional event data
"""
# Properties
event_type: int # Event type constant
node: 'Node' # Source HTML node
data: dict # Event-specific data
timestamp: float # Event timestamp
request: 'Request' # Associated request object
payload: dict # Raw event payload from client
document: 'Document' # Document containing the node
connection: object # Client connection object
window_id: str # Browser window identifier
nodes: list # List of involved nodes
target_node: 'Node' # Primary target node
tag_name: str # HTML tag name of target
id_list: list # CSS IDs of target node
class_list: list # CSS classes of target node
event_id: int # Unique event identifier
type: int # Alias for event_type
name: str # Event name string
node_info: dict # Additional node information
target_node_info: dict # Target node metadata
class EventType:
def __init__(self, name: str, code: int):
"""
Base event type definition.
Args:
name (str): Event type name
code (int): Numeric event code
"""
class ChangeEventType(EventType):
def __init__(self, input_delay: float = 0.0):
"""
Change event with optional input delay.
Args:
input_delay (float): Delay in seconds before firing change events
"""Methods available in View classes for waiting for and handling user events.
# Event waiting methods (available in View class)
def await_input_event(self, *nodes, html=None, timeout=None) -> 'InputEvent':
"""
Wait for any input event on specified nodes.
Args:
*nodes: HTML nodes to monitor for events
html: Optional HTML to show before waiting
timeout: Optional timeout in seconds
Returns:
InputEvent: Event details when triggered
"""
def await_click(self, *nodes, html=None, timeout=None) -> 'InputEvent':
"""
Wait for click events on specified nodes.
Args:
*nodes: HTML nodes to monitor for clicks
html: Optional HTML to show before waiting
timeout: Optional timeout in seconds
Returns:
InputEvent: Click event details
"""
def await_change(self, *nodes, html=None, timeout=None) -> 'InputEvent':
"""
Wait for change events on specified nodes.
Args:
*nodes: HTML nodes to monitor for changes
html: Optional HTML to show before waiting
timeout: Optional timeout in seconds
Returns:
InputEvent: Change event details
"""
def await_focus(self, *nodes, html=None, timeout=None) -> 'InputEvent':
"""
Wait for focus events on specified nodes.
Args:
*nodes: HTML nodes to monitor for focus
html: Optional HTML to show before waiting
timeout: Optional timeout in seconds
Returns:
InputEvent: Focus event details
"""
def await_blur(self, *nodes, html=None, timeout=None) -> 'InputEvent':
"""
Wait for blur events on specified nodes.
Args:
*nodes: HTML nodes to monitor for blur
html: Optional HTML to show before waiting
timeout: Optional timeout in seconds
Returns:
InputEvent: Blur event details
"""
def fire_view_event(self, name: str, data=None):
"""
Fire a custom view event.
Args:
name (str): Event name
data: Event data payload
"""from lona import App, View
from lona.html import HTML, H1, Button, TextInput, P
from lona.events import CLICK, CHANGE
app = App(__file__)
@app.route('/interactive')
class InteractiveView(View):
def handle_request(self, request):
# Create interactive elements
name_input = TextInput(placeholder='Enter your name')
greet_button = Button('Greet')
result_text = P('')
html = HTML(
H1('Interactive Example'),
name_input,
greet_button,
result_text
)
self.show(html)
while True:
# Wait for either button click or input change
event = self.await_input_event(name_input, greet_button)
if event.node == greet_button:
# Button was clicked
name = name_input.value or 'World'
result_text.set_text(f'Hello, {name}!')
elif event.node == name_input:
# Input was changed
if name_input.value:
result_text.set_text(f'Hi {name_input.value}...')
else:
result_text.set_text('')from typing import Union, Optional, Dict, Any, Callable
from lona.html import Node
# Event types
EventCode = int
EventData = Dict[str, Any]
EventHandler = Callable[['InputEvent'], None]
EventTimeout = Optional[float]
# Node collections for event monitoring
EventNodes = Union[Node, tuple, list]
HTMLNodes = Union[Node, tuple, list]
# Custom event types
CustomEventName = str
CustomEventData = AnyInstall with Tessl CLI
npx tessl i tessl/pypi-lona