Updating selected value in widget after changing param.Selector objects

Hi,
if I update/change the objects of a param.Selector wich is already rendered with panel as a DropDownList, it perfectly updates the objects/values in the DropDownList.

But how can I change the then (new) selected value, to be not the first item?

Complete, minimal, self-contained example code that reproduces the issue/use case

import param
import panel as pn

class Test(param.Parameterized):
    value = param.Selector(default=1, objects=[1,2,3])
    
    @pn.depends("value", watch=True)
    def update_param(self):
        # add one more number to objects
        o = self.param.value.objects
        new_objects = o + [o[-1]+1]
        self.param.value.objects = new_objects
        
        # how can I change the value in a way, it is also updated in the panel widget?
        # obviously not like this
        self.param.value.default = 2
        
        # and also not by simply setting the value (commented out to not run this function twice due to watch=True):
        # self.value = 2
        
test = Test()
pn.Param(test.param["value"], widgets={'value':pn.widgets.Select}) # maybe this is the wrong usage of a widget in this specific update case?

Thank you dear HoloViz Team for your amazing work with all your libraries.

I guess I didn’t describe the minimal example code clear enough:

When choosing a different option from the DropDownList, it adds one additional option to it.
It shows, that after updating the options, in the DropDownList the selected/displayed value jumps back to the first element. Which still makes sense after an options/objects update of the param.

Then setting a value (and default value) programmatically doesn’t change that, which is unexpected for me. But I guess I am simply overlooking something.

There really is no great pattern for this right now, so there are two alternatives.

  1. Use param.discard_events to literally discard any events arising from the value setting (this is likely not what you want though):
with param.discard_events(self):
    self.value = 2
  1. Add some sentinel to the class which aborts the recursive callback:
@pn.depends("value", watch=True)
def update_param(self):
    if self._updating:
        return
    # add one more number to objects
    o = self.param.value.objects
    new_objects = o + [o[-1]+1]
    self.param.value.objects = new_objects
    self._updating = True
    self.value = 2
    self._updating = False

Then setting a value (and default value) programmatically doesn’t change that, which is unexpected for me. But I guess I am simply overlooking something.

Setting the default will have no effect, setting the value should though.

Thank you for your response.

Should your suggested alternatives be a workaround and produce the expected result?
If yes I can’t reproduce. Both doesn’t update the panel.widget.Select rendering (in a Jupyter Notebook) as expected, so the widget would have selected “2” in the third image above.

If not, I am not sure how to benefit from aborting further recursive callback events to change the widgets “rendered selected value” (as the real value attribute is changed correctly).

I think only my latter suggestion will correctly update the rendered value. Could you tell me the version of Panel you are using?

It’s version 0.9.5

Could you update to 0.10.3?

I tried now with panel 0.10.3 but same behaviour as before.
Here is the self-contained code example again, to prevent talking past each other (:

import param
import panel as pn
pn.extension()

class Test(param.Parameterized):
    value = param.Selector(default=1, objects=[1,2,3])
    _updating = False
    
    @pn.depends("value", watch=True)
    def update_param(self):
        # add one more number to objects
        if self._updating:
            return
        o = self.param.value.objects
        new_objects = o + [o[-1]+1]
        self.param.value.objects = new_objects
        
        self._updating = True
        self.value = 2
        self._updating = False
     

test = Test()
pn.Param(test.param["value"], widgets={'value':pn.widgets.Select}) # maybe this is the wrong usage wor a widget in this case?

Another unclear behaviour to me is, that when changing the widget value back to 2 (= the set self.value value) it doesn’t update the list.

Sorry, I don’t know what I was doing before but I can indeed reproduce your issue. Will keep looking into it.

1 Like

Should I open an issue on github and link it to here and vice versa to help you save time?

Yes, please do open an issue. Thank you!

One more info I need, sorry :smiley:
Do you connect that issue more with param or panel? Just to post it in the right repo.

Let’s go with Panel.

1 Like

This issue is now on github: https://github.com/holoviz/panel/issues/1963

2 Likes