Link Two Objects in Javascript#
This guide addresses how to link parameters of two objects in Javascript.
Linking objects in Python is often very convenient because it allows writing code entirely in Python. However, it also requires a live Python kernel. If instead we want a static example (e.g. on a simple website or in an email) to have custom interactivity, or we simply want to avoid the overhead of having to call back into Python, we can define links in JavaScript.
Link model properties#
Let us start by linking the value
of the TextInput
widget to the object
property of a Markdown
pane:
import panel as pn
pn.extension()
markdown = pn.pane.Markdown('Markdown display')
text_input = pn.widgets.TextInput(value=markdown.object)
link = text_input.jslink(markdown, value='object')
pn.Row(text_input, markdown)
As you can see, Panel translates the specification into a JS code snippet which syncs the properties on the underlying Bokeh properties. But now if you edit the widget and press Return, the Markdown display will automatically update even in a static HTML web page.
Link bi-directionally#
When you want the source and target to be linked bi-directionally, i.e. a change in one will automatically trigger a change in the other you can simply set the bidirectional
argument:
t1 = pn.widgets.TextInput()
t2 = pn.widgets.TextInput()
t1.jslink(t2, value='value', bidirectional=True)
pn.Row(t1, t2)
Link using custom JS code#
Since everything happens in JS for a jslink
, we can’t provide a Python callback. Instead, we can define a JS code snippet, which is executed when a property changes. E.g. we can define a little code snippet which adds HTML bold tags (<b>
) around the text before setting it on the target. The code argument should map from the parameter/property on the source object to the JS code snippet to execute:
markdown = pn.pane.Markdown("<b>Markdown display</b>", width=400)
text_input = pn.widgets.TextInput(value="Markdown display")
code = '''
target.text = '<b>' + source.value + '</b>'
'''
link = text_input.jslink(markdown, code={'value': code})
pn.Row(text_input, markdown)
Here source
and target
are made available in the JavaScript namespace, allowing us to arbitrarily modify the models in response to property change events. Note however that the underlying Bokeh model property names may differ slightly from the naming of the parameters on Panel objects, e.g. the ‘object’ parameter on the Markdown pane translates to the ‘text’ property on the Bokeh model used to render the Markdown
.
Of course, you can still update the value from Python, and it will automatically update the linked markdown:
text_input.value = "Markdown display"
Responding to click events#
To respond to click events, we’ll demonstrate an example of using js_on_click
. This example will open a URL from the TextInput
widget value in a new browser tab:
button = pn.widgets.Button(name='Open URL', button_type = 'primary')
url = pn.widgets.TextInput(name='URL', value = 'https://holoviz.org/')
button.js_on_click(args={'target': url}, code='window.open(target.value)')
pn.Row(url, button)