Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

run_method and getElement return inconsistent types of elements #3019

Open
chrschorn opened this issue May 4, 2024 · 1 comment
Open

run_method and getElement return inconsistent types of elements #3019

chrschorn opened this issue May 4, 2024 · 1 comment
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@chrschorn
Copy link
Contributor

chrschorn commented May 4, 2024

Description

Hi, originally I wanted to implement a "scroll to element" functionality in an application I'm working on. You can use scrollIntoView() on the DOM node to achieve that. But: how can I get the DOM node for any NiceGUI element?

The issue I ran into:

  • Sometimes, you can just use element.run_method("scrollIntoView") and it works. This seems to be the case when the NiceGUI element is just a simple dom node to begin with, e.g. ui.label which is a div
  • For Quasar-based elements, that ^ does not work. You have to use $el to get the DOM node of the vue component.
  • For some elements, even that does not work.

Here are some examples that work with run_method, then a custom scroll_to I wrote and then ui.input which I couldn't get to work at all:

from nicegui import ui


def scroll_to(element: ui.element):
    ui.run_javascript(f"""
        var el = getElement({element.id});
        console.log(el);
        if (el.$el)
            el = el.$el;
        el.scrollIntoView();
    """)


ui.button("Scroll to label", on_click=lambda: label.run_method("scrollIntoView"))
ui.button("Scroll to button (not working)", on_click=lambda: button.run_method("scrollIntoView"))
ui.button("Scroll to button (works)", on_click=lambda: scroll_to(button))
ui.button("Scroll to input (not working)", on_click=lambda: input.run_method("scrollIntoView"))
ui.button("Scroll to input (not working #2)", on_click=lambda: scroll_to(input))

ui.element().classes("h-[200vh]")  # space for scroll demo

label = ui.label("Far away label")
button = ui.button("Far away button")
input = ui.input("Far away input")

ui.element().classes("h-[200vh]")  # space to make clear which element was scrolled to

ui.run()

Is there already an easy way to get the root DOM node of the NiceGUI element? According to https://nicegui.io/documentation/run_javascript, it should be getElement, but this either returns a DOM node, vue component where $el refers to the root DOM node or, in cases like ui.input, something where even $el points to a non-DOM object.

It would be good to have a reliable way to get the DOM node for an element. Maybe run_method could have a bool argument dom_element? Providing a javascript function documented on run_javascript could also work.

@falkoschindler
Copy link
Contributor

Hi @chrschorn,

That's a great observation. When implementing and extending getElement, we tried to (almost) always return something "useful", but we introduced an annoying inconsistency. We thought, from the user's perspective, it shouldn't matter if a NiceGUI element is based on a Vue component or a plain HTML element. But of course, if you want to do something with it, the difference matters. One could argue that, if you know that an element is based on Vue, you can step into the HTML element using $el, as you did. But this isn't very intuitive, let alone documented.

To support explicit access to Vue components or HTML elements - without breaking the existing API -, we might want to introduce new functions like getHtmlElement and getVueComponent, and deprecate or at least discourage using getElement.

But besides that, what can we do about ui.input? Quasar takes the q-input tag and replaces it with a whole tree of HTML with a <label> as root, but without setting the "id" attribute. I'm not sure what we could do about it, but it would be great to get some kind of consistency with other UI elements.

@falkoschindler falkoschindler added enhancement New feature or request help wanted Extra attention is needed labels May 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants