Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
holoviz
GitHub Repository: holoviz/panel
Path: blob/main/doc/how_to/links/jslinks.md
2011 views

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.

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.

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)

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)