Files
NiceGUIEx/example_async_dialog.py
2025-09-23 05:26:18 +02:00

146 lines
5.3 KiB
Python

#!/usr/bin/env python3
"""Example demonstrating the AsyncElement.as_dialog() method"""
from nicegui import ui
from src.niceguiex.async_elements import AsyncColumn
class ConfirmDialog(AsyncColumn):
"""A confirmation dialog that can be awaited for a result"""
async def build(self, message: str, title: str = "Confirm"):
"""Build the dialog content"""
# Set dialog size using the property
self.dialog_size = 'w-96'
ui.label(title).classes('text-h6')
ui.label(message)
ui.space()
with ui.row().classes('full-width justify-end'):
ui.button('Cancel', on_click=lambda: self._dialog.submit(False))
ui.button('OK', on_click=lambda: self._dialog.submit(True)).props('color=primary')
class FormDialog(AsyncColumn):
"""A form dialog that collects user input"""
async def build(self, title: str = "Enter Information"):
"""Build the form dialog"""
# Set a wider dialog size for the form
if hasattr(self, '_dialog'):
self.dialog_size = 'w-1/2'
ui.label(title).classes('text-h6')
# Create input fields
name_input = ui.input('Name', placeholder='Enter your name')
email_input = ui.input('Email', placeholder='Enter your email')
ui.space()
with ui.row().classes('full-width justify-end'):
# Check if we're in dialog mode (self._dialog exists)
if hasattr(self, '_dialog'):
ui.button('Cancel', on_click=lambda: self._dialog.submit(None))
ui.button('Submit', on_click=lambda: self._dialog.submit({
'name': name_input.value,
'email': email_input.value
})).props('color=primary')
else:
# Normal mode - just show submit button that displays the values
ui.button('Submit', on_click=lambda: ui.notify(f"Name: {name_input.value}, Email: {email_input.value}")).props('color=primary')
@ui.page('/')
async def main():
ui.label('AsyncElement Dialog Examples').classes('text-h4')
ui.separator()
# Example: Same component used both normally and as dialog
with ui.row():
with ui.column():
ui.label('Normal usage (inline):').classes('text-subtitle1')
# Use FormDialog normally inline on the page
await FormDialog.create(title="Inline Form")
with ui.column():
ui.label('Dialog usage:').classes('text-subtitle1')
async def show_form_dialog():
result = await FormDialog.as_dialog(title="Dialog Form")
if result:
ui.notify(f'Form submitted: {result}', type='positive')
else:
ui.notify('Form cancelled', type='warning')
ui.button('Open as Dialog', on_click=show_form_dialog)
ui.separator()
async def show_confirm():
result = await ConfirmDialog.as_dialog(
message="Are you sure you want to proceed?",
title="Confirmation Required"
)
ui.notify(f'Confirmation result: {result}', type='positive' if result else 'negative')
async def show_form():
result = await FormDialog.as_dialog(title="User Registration")
if result:
ui.notify(f'Form submitted: {result}', type='positive')
else:
ui.notify('Form cancelled', type='warning')
with ui.row():
ui.button('Show Confirmation Dialog', on_click=show_confirm)
ui.button('Show Form Dialog', on_click=show_form)
# Example with inline async element using AsyncColumn
async def show_inline_dialog():
class QuickDialog(AsyncColumn):
async def build(self):
# Smaller dialog size for simple questions
self.dialog_size = 'w-72'
ui.label('Quick Question').classes('text-h6')
ui.label('Do you like this feature?')
with ui.row():
ui.button('Yes!', on_click=lambda: self._dialog.submit('yes'))
ui.button('No', on_click=lambda: self._dialog.submit('no'))
ui.button('Maybe', on_click=lambda: self._dialog.submit('maybe'))
result = await QuickDialog.as_dialog()
ui.notify(f'Your answer: {result}')
ui.button('Show Quick Dialog', on_click=show_inline_dialog)
# Example with dynamic sizing based on content
async def show_dynamic_dialog():
class DynamicDialog(AsyncColumn):
async def build(self, items_count: int = 3):
# Adjust size based on content
if items_count <= 3:
self.dialog_size = 'w-96'
else:
self.dialog_size = 'w-1/2'
ui.label(f'Dynamic Dialog with {items_count} items').classes('text-h6')
for i in range(items_count):
ui.label(f'Item {i + 1}: This is some content for item {i + 1}')
ui.space()
ui.button('Close', on_click=lambda: self._dialog.submit(f'Closed with {items_count} items'))
for count in [2, 5]:
result = await DynamicDialog.as_dialog(items_count=count)
ui.notify(f'Result: {result}')
ui.button('Show Dynamic Dialogs', on_click=show_dynamic_dialog)
if __name__ in {"__main__", "__mp_main__"}:
ui.run(title='Async Dialog Example', port=8085)