How can I return two widgets using depends and a function

mcw1 = pn.widgets.Multichoice(name, options, value)
mcw2 = pn.widgets.Multichoice(name, options, value)
mcw3 = pn.widgets.Multichoice(name, options, value)

@pn.depends(mcw2)
def update_mcw(*N):
    mcw1.value = myfunc1(mcw2.value)
    mcw3.value = myfunc2(mvc2.value)
    return mcw1, mcw3

pn.Row(mcw2, update_mcw).show()

when I run above code, the output only shows mcw2 correctly but for mcw1 and mcw3 are not rendered as widgets in the browser. Any ideas why? How can I return two widgets which depend on another widgets. Thanks

1 Like

Found a working solution by returning a panel row. i.e. return pn.Row(mcw1, mcw2)

1 Like

Something like

import panel as pn

pn.extension(template="fast")

mcw1 = pn.widgets.TextInput(value="Hello", name="1")
mcw2 = pn.widgets.TextInput(value="Hello", name="2")
mcw3 = pn.widgets.TextInput(value="Hello", name="3")

def myfunc1(value):
    return value + " 1"

def myfunc3(value):
    return value + " 3"

@pn.depends(mcw2)
def update_mcw(*N):
    mcw1.value = myfunc1(mcw2.value)
    mcw3.value = myfunc3(mcw2.value)
    return pn.Row(mcw1, mcw2, mcw3)

pn.panel(update_mcw).servable()

Might also be what you are looking for.

1 Like

Or this

import panel as pn

pn.extension(template="fast")

mcw1 = pn.widgets.TextInput(name="1")
mcw2 = pn.widgets.TextInput(name="2")
mcw3 = pn.widgets.TextInput(name="3")

def myfunc1(value):
    return value + " 1"

def myfunc3(value):
    return value + " 3"

@pn.depends(value=mcw2, watch=True)
def update_mcw(value):
    mcw1.value = myfunc1(value)
    mcw3.value = myfunc3(value)
update_mcw("Hello")

pn.Row(mcw1, mcw2, mcw3).servable()

The pn.Row and pn.Column could be clear() and append(),
so you could try this,

import panel as pn
import datetime as dt
pn.extension()


selector  = pn.widgets.Select(name = 'widget_selector',options = ['IntSlider','DateSlider'])

date_slider1 = pn.widgets.DateSlider(name='Date Slider', start=dt.datetime(2019, 1, 1), end=dt.datetime(2019, 6, 1), value=dt.datetime(2019, 2, 8))
date_slider2 = pn.widgets.DateSlider(name='Date Slider', start=dt.datetime(2022, 1, 1), end=dt.datetime(2022, 12, 30), value=dt.datetime(2022, 8, 8))
int_slider1 = pn.widgets.IntSlider(name='Integer Slider', start=0, end=8, step=2, value=4)
int_slider2 = pn.widgets.IntSlider(name='Integer Slider', start=0, end=8, step=2, value=8)

select_dir = {'IntSlider':[date_slider1,date_slider2],
              'DateSlider':[int_slider1,int_slider2]}


app = pn.Column(pn.pane.Str('init stuff'))

@pn.depends(selector,watch = True)
def change_widgets(widget_name):
    app.clear()
    for widget in select_dir[widget_name]:
        app.append(widget)

pn.Column(
    selector,
    app
).show()
1 Like

I believe you version @CongTang will be the slowest because it will update the screen many times. First when you .clear then each time you .append. In this example it is probably not an issue. But when I started using Panel I did things like this which made my apps slow. And it took a while before I figured out the cause.

1 Like

Hi Marc

Thanks for letting me know this, I do have some performance issues when using I using clear and append ways to replace widgets.

If I change the code like this, is that will would be better? or do you have some recommended way to replace the widgets?

import panel as pn
import datetime as dt
pn.extension()


selector  = pn.widgets.Select(name = 'widget_selector',options = ['IntSlider','DateSlider'])

date_slider1 = pn.widgets.DateSlider(name='Date Slider', start=dt.datetime(2019, 1, 1), end=dt.datetime(2019, 6, 1), value=dt.datetime(2019, 2, 8))
date_slider2 = pn.widgets.DateSlider(name='Date Slider', start=dt.datetime(2022, 1, 1), end=dt.datetime(2022, 12, 30), value=dt.datetime(2022, 8, 8))
int_slider1 = pn.widgets.IntSlider(name='Integer Slider', start=0, end=8, step=2, value=4)
int_slider2 = pn.widgets.IntSlider(name='Integer Slider', start=0, end=8, step=2, value=8)

select_dir = {'IntSlider':pn.Column(date_slider1,date_slider2),
              'DateSlider':pn.Column(int_slider1,int_slider2)}


app = pn.Column(pn.pane.Str('init stuff'))

@pn.depends(selector,watch = True)
def change_widgets(widget_name):
    app[0]=select_dir[widget_name]

pn.Column(
    selector,
    app
).show()

And thank for point out the issue :+1:

Kind regards
Victor

1 Like

This looks much better to me.

1 Like