Bind dynamic list of widgets

Here’s the functional way. I think param can group your parameters more effectively, and potentially scale (it’s how panel / holoviews is built internally).

Initially pn.bind is easier to pick up and use, but after it could potentially get messy with watch=True is my understanding.

import panel as pn
import param

pn.extension(template="material")
BASE_COLOR = "#0072b5"


def update_colors_select(event):
    colors = [color_picker.value for color_picker in color_pickers]
    colors_select.param.update(
        options=colors,
        value=colors,
    )

def create_color_pickers(colors):
    color_picker_list = []
    for color in colors:
        color_picker = pn.widgets.ColorPicker(name="Color", value=color)
        color_picker.param.watch(update_colors_select, "value")
        color_picker_list.append(color_picker)
    color_pickers[:] = color_picker_list

def create_color_palette(colors):
    return pn.pane.HTML(f"{colors}")


colors_select = pn.widgets.MultiSelect(name="Colors", visible=False)
color_pickers = pn.Column()
pn.bind(create_color_pickers, colors=colors_select.param.value, watch=True)
color_palette = pn.bind(create_color_palette, colors=colors_select.param.value)
colors_select.param.update(
    value=[BASE_COLOR],
    options=[BASE_COLOR],
)  # initialize
pn.Column(colors_select, color_pickers, color_palette)

There’s some discussion here:

1 Like