Using JSLINK to synchronize Tabs and pn.Column contents to avoid requiring Python to be running

The sample code couples an active Tab component with a (in)visible markdown component. The idea is to present a multi-segment panel where all of the segments are pre-rendered because the drawing times are sometimes too long for high-priced non-tech professionals to wait for. The multiple segments allow me to focus the plots so they can be expanded to full-screen without the text when needed.

Setting RUNPYTHON to True allows me to do quick exploring with the python syncing working great. My desire is setting it to False will use the jslink code instead, but that code is not producing similar results. I do not know if it is my lack of javascript experience, understanding the identifiers to use between the python bindings and the js/Bokeh bindings, or that a list of pn.Column items is just not accessible via jslink.

Any ideas/pointers?

import panel as pn
import holoviews as hv
hv.extension('bokeh', logo=False)
pn.extension()
pn.param.ParamMethod.loading_indicator = True

RUNPYTHON = False

tabs = pn.Tabs(
    ('first tab', 'first tab content'),
    ('second tab', 'second tab content'),
    ('third tab', 'third tab content'),
    )

texts = pn.Column(
    'first page comments', 
    'second page comments', 
    'third page comments',
    )

def set_cur_text(texts, tabs): 
    for i in range(len(texts)):
        texts[i].visible = (i == tabs.active)

set_cur_text(texts, tabs)
def match_text(*events):
    for event in events:
        if event.name == 'active':
            texts[event.old].visible = False
            texts[event.new].visible = True

if RUNPYTHON:
    watchtabs = tabs.param.watch(match_text, ['active'], onlychanged=True)
    tabs.param.trigger('active')
else:
    # jscode = '''
    #     for (i = 0; i < target.length; i++) {
    #         target[i].visible = (i == source.active);
    #     }
    # '''
    jscode = '''
        target[source.old].visible = false;
        target[source.new].visible = true
        target.change.emit()
    '''
    link = tabs.jslink(texts, code={'active': jscode})

app = pn.template.FastGridTemplate()
app.main[:8, :3] = texts
app.main[:8, 3:] = tabs
app.show()

The code below demonstrates my current solution for this capability. Set RUNPYTHON to select either python (True) or JS (False) linking. Not only does this provide component syncing with no python server, it supports separating different types of data from each other for full screen viewing of individual components.

import numpy as np
import panel as pn
import holoviews as hv
hv.extension('bokeh', logo=False)
pn.extension(sizing_mode='stretch_both')
pn.param.ParamMethod.loading_indicator = True

# RUNPYTHON = True
RUNPYTHON = False

XS = np.linspace(0, np.pi)
a = hv.Curve((XS, np.sin(XS * 4 + 0))).opts(responsive=True, title="Sine")
b = hv.Curve((XS, np.cos(XS * 4 + 0))).opts(responsive=True, title="Cosine")
c = a * b

tabs = pn.Tabs(
    ('Sine/Cosine Layout', (a + b + c).cols(1)),
    ('Cosine Curve', b),
    ('Sine/Cosine Overlay', c),
    )

titles = pn.Column(
    '# Sine/Cosine Layout Comments',
    '# Cosine Curve Comments', 
    '# Sine/Cosine Overlay Comments',
    )

texts = pn.Column(
    'Comments about the sine and cosine layout to the right',
    'Comments about the Cosine Curve to the right', 
    'Comments about the  Sine/Cosine Overlay to the right',
    )

def set_current(col, tabs): 
    for i in range(len(col)):
        col[i].visible = (i == tabs.active)

set_current(titles, tabs)
set_current(texts, tabs)

if RUNPYTHON:
    def match_text(*events):
        for event in events:
            if event.name == 'active':
                for i in range(len(texts)):
                    titles[i].visible = (i == event.new)
                    texts[i].visible = (i == event.new)

    watchtabs = tabs.param.watch(match_text, ['active'], onlychanged=True)
    tabs.param.trigger('active')
else:
    watchtitles = []
    watchtexts = []
    for i in range(len(texts)):
        watchtitles.append(tabs.jslink(titles[i], code={'active': f'target.visible = (source.active == {i})'}))
        watchtexts.append(tabs.jslink(texts[i], code={'active': f'target.visible = (source.active == {i})'}))

app = pn.template.FastGridTemplate()
app.main[:1, :] = titles
app.main[1:6, :3] = texts
app.main[1:6, 3:] = tabs
app.save('jstest.html')
app.show()