Search code examples
pythonvuetify.jsipywidgets

Is it possible to get the current position of an ipywidget?


I'm using the ipyvuetfy lib that create nice dashboarding element based ont he vuetify.js lib and ipyvwidgets.

I need to place a dialog in a specific position (on top of another element) like this menu placed on top of a select folder btn.

enter image description here

How can I access the the current position of a widget relative to the window ?


Solution

  • It is possible with Javascript code, by identifying the widget with a custom class and using the jQuery offset() method, and then setting the DOM Style top and left properties of the child (here a Card) of the ipyvuetify Dialog, with the style position set as fixed. I haven't found how to execute the JS code via the Dialog activator slot, so the Dialog widget is triggered via the click.stop event:

    import ipyvuetify as v
    import ipywidgets as w
    
    from IPython.display import Javascript
    
    out = w.Output(layout={'display': 'none'})
    
    js = '''
    var x = $(".myparentwidget").offset();
    var d = document.getElementsByClassName("mydialog")[0]; 
    d.style.top = x.top+"px"; 
    d.style.left= x.left+"px";'''
    
    def on_click(widget, event, data):
        dialog.v_model=True
        with out:
            display(Javascript(js, lib="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"))
    
    btn = v.Btn(
        children=["Open dialog"],
        class_='myparentwidget'
    )
    btn.on_event("click.stop", on_click)
    
    dialog = v.Dialog(
        v_model=False,
        children=[
            v.Card(
                class_='mydialog',
                style_="position: fixed; width: 300px",
                children=[
                    v.CardTitle(children=["Dialog window"]),
                    v.CardText(children=['Dialog text']),
                ]
            )
        ],
    )
    
    v.Layout(children=[btn,dialog,out])