WDM
WDM

Reputation: 13

Call Javascript from a button click event function in Jupyter Lab or Jupyter notebook

In jupyter cell, I have the following code, and I can see the it works with "hello world!" printed out in Chrome console.

from IPython.display import Javascript
my_js = """
console.log('hello world!');
"""
Javascript(my_js)

Now, I create a button in jupyter and move that function to button click event. Now, when I click button, the event is executed, but the javascript doesn't work and no output in chrome console:

button = widgets.Button(
   description='Button',
   disabled=False,
   button_style='', 
   tooltip='Button',
   icon='check' 
)

def on_button_clicked(b):
   print("on_button_clicked called")
   my_js = """
   console.log('Hello world2!');
   """
   Javascript(my_js)
   print("on_button_clicked call ended")
   
button.on_click(on_button_clicked)

display(button)

enter image description here

Any idea? Thanks.

Upvotes: 1

Views: 1604

Answers (2)

Mahmut ARIKAN
Mahmut ARIKAN

Reputation: 625

I used Krassowski's solution with small tuning in 2023. Run it in a cell. I need to use a display call for out and button. And don't forget to open your browser's console.

`

from ipywidgets import widgets
from IPython.display import Javascript, Markdown

out = widgets.Output(layout={'border': '1px solid black'})

def on_button_clicked(b):
    my_js = """
    console.log('Hello world2!');
    alert("hi");
    """
    with out:
        #print(my_js)
        display(Javascript(my_js))
        display(Markdown("on_button_clicked called"))
        print("on_button_clicked call ended")

button = widgets.Button(
    description='Button',
    disabled=False,
    button_style='',
    tooltip='Button',
    icon='check'
)

button.on_click(on_button_clicked)
display(button, out)

`

Upvotes: 0

krassowski
krassowski

Reputation: 15379

You are creating an object of Javascript class, but then discarding it (as you are not assigning it to any variable, nor displaying it). This works with your first use of Javascript because when the last result of an IPython cell is not assigned to a variable it will be automatically displayed; this also means that you can skip display() call when displaying a button (if it is the last line in the cell):

button = widgets.Button(
    description='Button',
    disabled=False,
    button_style='',
    tooltip='Button',
    icon='check'
)
button.on_click(on_button_clicked)
# notice lack of `display()` call:
button

but it does not work if the object to be displayed is inside the function callback, because IPython does not know which expressions to display and which to ignore. Javascript objects need to be displayed in order for the JavaScript code to be executed by your browser. To make it work:

  • use display explicitly on Javascript object, and
  • define an output area in which the object should be displayed in

For example, cell 1:

out = widgets.Output(layout={'border': '1px solid black'})
out

And then:

def on_button_clicked(b):
    my_js = """
    console.log('Hello world2!');
    """
    with out:
        display(Javascript(my_js))
        display(Markdown("on_button_clicked called"))

enter image description here

Upvotes: 2

Related Questions