-
Hi, I'm working through the examples and managed to get table pagination working from the example (Table / Pagination / Minimal). However, when I try to insert that table feature into a multipage app the feature fails to work and I'm unable to work out why. I've added the table on #page1 h2o-wave==0.26.0 from h2o_wave import main, app, Q, ui, on, handle_on, data
from typing import Optional, List
# Remove all the cards related to navigation.
def clear_cards(q, ignore: Optional[List[str]] = []) -> None:
if not q.client.cards:
return
for name in q.client.cards.copy():
if name not in ignore:
del q.page[name]
q.client.cards.remove(name)
rows = [str(i + 1) for i in range(100)]
rows_per_page = 10
@on('#page1')
async def page1(q: Q):
clear_cards(q) # When routing, drop all the cards except of the main ones (header, sidebar, meta).
q.client.cards.add('table')
q.page['table'] = ui.form_card(box='vertical', items=[
ui.table(
name='table',
columns=[ui.table_column(name='text', label='Text', link=False)],
rows=[ui.table_row(name=r, cells=[r]) for r in rows[0:rows_per_page]],
pagination=ui.table_pagination(total_rows=len(rows), rows_per_page=rows_per_page),
height='580px',
events=['page_change']
)
])
if q.events.table and q.events.table.page_change:
offset = q.events.table.page_change.get('offset', 0)
new_rows = rows[offset:offset + rows_per_page]
q.page['table'].table.rows = [ui.table_row(name=r, cells=[r]) for r in new_rows]
async def init(q: Q) -> None:
q.page['meta'] = ui.meta_card(box='', layouts=[ui.layout(breakpoint='xs', min_height='100vh', zones=[
ui.zone('header'),
ui.zone('content', zones=[
# Specify various zones and use the one that is currently needed. Empty zones are ignored.
ui.zone('horizontal', direction=ui.ZoneDirection.ROW),
ui.zone('vertical'),
ui.zone('grid', direction=ui.ZoneDirection.ROW, wrap='stretch', justify='center')
]),
])])
q.page['header'] = ui.header_card(
box='header', title='My app', subtitle="Let's conquer the world",
image='https://wave.h2o.ai/img/h2o-logo.svg',
secondary_items=[
ui.tabs(name='tabs', value=f'#{q.args["#"]}' if q.args['#'] else '#page1', link=True, items=[
ui.tab(name='#page1', label='Home'),
]),
],
items=[
ui.persona(title='John Doe', subtitle='Developer', size='xs',
image='https://images.pexels.com/photos/220453/pexels-photo-220453.jpeg?auto=compress&h=750&w=1260'),
]
)
# If no active hash present, render page1.
if q.args['#'] is None:
await page1(q)
@app('/')
async def serve(q: Q):
# Run only once per client connection.
if not q.client.initialized:
q.client.cards = set()
await init(q)
q.client.initialized = True
# Handle routing.
await handle_on(q)
await q.page.save() Any help would be greatly appreciated |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi @htailor, good question! TLDRIf using Working codefrom h2o_wave import main, app, Q, ui, on, handle_on, data
from typing import Optional, List
# Remove all the cards related to navigation.
def clear_cards(q, ignore: Optional[List[str]] = []) -> None:
if not q.client.cards:
return
for name in q.client.cards.copy():
if name not in ignore:
del q.page[name]
q.client.cards.remove(name)
rows = [str(i + 1) for i in range(100)]
rows_per_page = 10
@on('#page1')
async def page1(q: Q):
clear_cards(q) # When routing, drop all the cards except of the main ones (header, sidebar, meta).
q.client.cards.add('table')
q.page['table'] = ui.form_card(box='vertical', items=[
ui.table(
name='table',
columns=[ui.table_column(name='text', label='Text', link=False)],
rows=[ui.table_row(name=r, cells=[r]) for r in rows[0:rows_per_page]],
pagination=ui.table_pagination(total_rows=len(rows), rows_per_page=rows_per_page),
height='580px',
events=['page_change']
)
])
# -------------------------------------------------------
# Separate handler
@on('table.page_change')
async def handle_page_change(q: Q):
offset = q.events.table.page_change.get('offset', 0)
new_rows = rows[offset:offset + rows_per_page]
q.page['table'].table.rows = [ui.table_row(name=r, cells=[r]) for r in new_rows]
# -------------------------------------------------------
async def init(q: Q) -> None:
q.page['meta'] = ui.meta_card(box='', layouts=[ui.layout(breakpoint='xs', min_height='100vh', zones=[
ui.zone('header'),
ui.zone('content', zones=[
# Specify various zones and use the one that is currently needed. Empty zones are ignored.
ui.zone('horizontal', direction=ui.ZoneDirection.ROW),
ui.zone('vertical'),
ui.zone('grid', direction=ui.ZoneDirection.ROW, wrap='stretch', justify='center')
]),
])])
q.page['header'] = ui.header_card(
box='header', title='My app', subtitle="Let's conquer the world",
image='https://wave.h2o.ai/img/h2o-logo.svg',
secondary_items=[
ui.tabs(name='tabs', value=f'#{q.args["#"]}' if q.args['#'] else '#page1', link=True, items=[
ui.tab(name='#page1', label='Home'),
]),
],
items=[
ui.persona(title='John Doe', subtitle='Developer', size='xs',
image='https://images.pexels.com/photos/220453/pexels-photo-220453.jpeg?auto=compress&h=750&w=1260'),
]
)
# If no active hash present, render page1.
if q.args['#'] is None:
await page1(q)
@app('/')
async def serve(q: Q):
# Run only once per client connection.
if not q.client.initialized:
q.client.cards = set()
await init(q)
q.client.initialized = True
# Handle routing.
await handle_on(q)
# -------------------------------------------------------
# Or if you do not want to register new handler.
# Handle events.
# if q.events.table and q.events.table.page_change:
# offset = q.events.table.page_change.get('offset', 0)
# new_rows = rows[offset:offset + rows_per_page]
# q.page['table'].table.rows = [ui.table_row(name=r, cells=[r]) for r in new_rows]
# -------------------------------------------------------
await q.page.save() More detailsThe reason the table does not work for you is because you mix 2 ways of event handling:
The on handler works by registering handler functions and calling them on match. Your app loads with There are 2 ways to fix this. Either move the event handling logic to a separate |
Beta Was this translation helpful? Give feedback.
Hi @htailor, good question!
TLDR
If using
@on
mechanism, you need to use it for everything.Working code