Repository: holoviz/panel

Issue:
Error displaying CheckBoxGroup after modifying it in a callback
Hello,

I am trying to modify the options of a CheckBoxGroup based on an other widget, while keeping the currently selected options if they still make sense. This causes the checked boxes of the CheckBoxGroup to be erroneously displayed.

versions:
panel==0.12.5
param==1.12.0

To reproduce:

```
import panel as pn
pn.extension()
    
sets = {'set_0': ['A', 'B'], 
        'set_1': ['B', 'C']}

set_select = pn.widgets.Select(options=list(sets.keys()))
elements_select = pn.widgets.CheckBoxGroup(value=[], options=sets[set_select.value])

def update_element_options(*events):
    for event in events:
        elements_select.options = sets[event.new]
        elements_select.value = sorted(set(elements_select.value) & set(elements_select.options))
set_select.param.watch(update_element_options, ['value'])

pn.Column(set_select, elements_select)
```

Run this, check 'B' in the CheckBoxGroup, then select 'set_1' in set_select. The options of the CheckBoxGroup change, but it seems that it is the 'C' option that is selected.



Discussion:
I can recreate the problem. As a workaround you can replace the function with this:
``` python
def update_element_options(*events):
    for event in events:
        elements_select.options = sets[event.new]
        old_value = elements_select.value
        elements_select.value = []
        elements_select.value = sorted(set(old_value) & set(elements_select.options))
```

https://user-images.githubusercontent.com/19758978/145277965-1fea33eb-ffad-41fa-bf8b-a1258ae2f923.mp4

Thanks. This works.

FYI, unsurprisingly there is the same issue with CheckButtonGroup.

Resolving patch:
diff --git a/panel/widgets/select.py b/panel/widgets/select.py
--- a/panel/widgets/select.py
+++ b/panel/widgets/select.py
@@ -410,7 +410,7 @@ class _CheckGroupBase(SingleSelectBase):
     __abstract = True
 
     def _process_param_change(self, msg):
-        msg = super(SingleSelectBase, self)._process_param_change(msg)
+        msg = super()._process_param_change(msg)
         values = self.values
         if 'active' in msg:
             msg['active'] = [indexOf(v, values) for v in msg['active']
@@ -419,6 +419,8 @@ def _process_param_change(self, msg):
             msg['labels'] = self.labels
             if any(not isIn(v, values) for v in self.value):
                 self.value = [v for v in self.value if isIn(v, values)]
+            msg["active"] = [indexOf(v, values) for v in self.value
+                             if isIn(v, values)]
         msg.pop('title', None)
         return msg
 


Test patch:
diff --git a/panel/tests/widgets/test_select.py b/panel/tests/widgets/test_select.py
--- a/panel/tests/widgets/test_select.py
+++ b/panel/tests/widgets/test_select.py
@@ -320,6 +320,11 @@ def test_toggle_group_check(document, comm):
         select._process_events({'active': []})
         assert select.value == []
 
+        select.value = ["A", "B"]
+        select.options = ["B", "C"]
+        select.options = ["A", "B"]
+        assert widget.labels[widget.active[0]] == "B"
+
 
 def test_toggle_group_radio(document, comm):