Replies: 5 comments 3 replies
-
Just a guess - I get anomalous behavior like this when DOM content isn't fully loaded yet. Try a short pause before ui.timer (0.1, lambda : scroller.scroll_to (percent=0.5), once = true) But note that pausing in nicegui server doesn't guarantee a pause in client browser. You can either increase the pause time, or issue the scroll behavior directly in client with Or my guess is wrong and cause is something else entirely... |
Beta Was this translation helpful? Give feedback.
-
Thanks for the suggestion, I figured it was a timing thing between the server and client. Using the client.connected() method from nicegui's chat example was necessary. Along with that I found a reliable solution, but it is UGLY, using an invented class as a marker and hard-coded element traversal based on my observations of the internal div structure created by nicegui for a ScrollArea. The getElementsByClassName()[0] finds the "q-scrollarea" element thanks to my hopefully-forever-unique class naming convention, but scrolling that does nothing. It's firstElementChild is a "q-scrollarea__container", but that's obviously an internal detail that I'd rather not rely on if possible. FWIW I'm def nowhere near a css/javascript expert, so looking for any suggestions that would improve and maybe future-proof this. (And I'm still wondering if there isn't some way to get ScrollArea's scroll_to() function to work reliably, otherwise what use is it?) import builtins
from nicegui import ui
numbers = list(range(0, 10))
def setup(path: str):
@ui.refreshable
async def show_numbers(scroller_class: str) -> None:
for i in numbers:
ui.label(f'scrolling:{i} ')
# make sure client is connected before doing javascript
try:
await ui.context.client.connected(timeout=5.0)
await ui.run_javascript(code=f"const sdiv = document.getElementsByClassName('{scroller_class}')[0].firstElementChild;"
f"sdiv.scrollTop = sdiv.scrollHeight;")
# scroller.scroll_to(percent=1.0) # this is unpredictable, usually scrolls to penultimate item
except builtins.TimeoutError:
pass
def add():
numbers.append(len(numbers))
show_numbers.refresh()
@ui.page(path)
async def index():
ui.button(text='add', on_click=lambda: add())
with ui.row():
with ui.card().classes('w-32 h-48'):
sclass = 'kfname-scroll-area-scroller1'
with ui.scroll_area().classes(add=sclass):
await show_numbers(sclass)
if __name__ in {'__main__', '__mp_main__'}:
setup('/')
ui.run(host='localhost', port=8000, show=False, reload=False) |
Beta Was this translation helpful? Give feedback.
-
For any that are still following this, I found a much cleaner and simpler solution by dropping the @ui.refreshable, and instead explicitly clearing then refilling ScrollArea PLUS setting the scroll_to() percent to 1.1 (or 2.0 or 100.0) solved the problem of scrolling to the penultimate element in the list (maybe a rounding error when translating % to pixels?): from nicegui import ui
from nicegui.elements.scroll_area import ScrollArea
numbers = list(range(0, 10))
def setup(path: str):
async def show_numbers(scroller: ScrollArea) -> None:
for i in numbers:
ui.label(f'scrolling:{i} ')
scroller.scroll_to(percent=1.1)
async def add(scroller: ScrollArea) -> None:
numbers.append(len(numbers))
scroller.clear()
with scroller:
await show_numbers(scroller)
@ui.page(path)
async def index():
ui.button(text='add', on_click=lambda: add(scroller))
with ui.row():
with ui.card().classes('w-40 h-48'):
with ui.scroll_area().classes() as scroller:
await show_numbers(scroller)
if __name__ in {'__main__', '__mp_main__'}:
setup('/')
ui.run(host='localhost', port=8000, show=False, reload=False) |
Beta Was this translation helpful? Give feedback.
-
@8forty Your solution with Anyway, this made me realize that the |
Beta Was this translation helpful? Give feedback.
-
Oh cool, I took out refreshable first while debugging this, then discovered the percent value. I agree that "percent" parameter is confusing, but its type being float is a clue. I don't think there's an agreed-on term in English to specify "35%" vs. ".35", e.g.: math.stackexchange. percent_in_its_decimal_form is probably too long :) |
Beta Was this translation helpful? Give feedback.
-
Question
I'm trying to make a ScrollArea auto-scroll vertically to show the bottom line every time it's refreshed. Clicking my "ADD" button always adds another line but the scroll_to() has unpredictable results: sometimes scrolls to the bottom, sometimes to the line before the bottom, sometimes does nothing.
Anybody know what I'm doing wrong?
Beta Was this translation helpful? Give feedback.
All reactions