Update `bounds` of `param.CalendarDateRange` dynamically if `bounds` are not initially instantiated

Hello!

Whenever I try to update the bounds of a param.calendarDateRange widget that wasn’t instantiated with bounds using a button and its on_click callback, I get the following:

Note that here the widget is not interactive. However, when I instantiate with bounds, the widget updates properly and is interactive.

See below for the code that was used to generate the screenshots and example in question:

import os
import param
import pandas as pd
import holoviews as hv
import panel as pn

pn.extension()

OLD_DATE_BOUNDS = (datetime.datetime(2019, 1, 1), datetime.datetime(2020, 10, 31))
NEW_DATE_BOUNDS = (datetime.datetime(2020, 1, 1), datetime.datetime(2020, 10, 31))
DATA = [
 {'CRNCY': 'NOK', 'DATE': '2019-10-09'},
 {'CRNCY': 'NOK', 'DATE': '2020-04-30'},
 {'CRNCY': 'NOK', 'DATE': '2020-02-24'},
 {'CRNCY': 'AUD', 'DATE': '2020-10-06'},
 {'CRNCY': 'AUD', 'DATE': '2020-06-16'},
 {'CRNCY': 'NOK', 'DATE': '2020-04-23'},
 {'CRNCY': 'SEK', 'DATE': '2020-04-15'},
 {'CRNCY': 'NOK', 'DATE': '2020-07-06'},
 {'CRNCY': 'SEK', 'DATE': '2019-11-05'},
 {'CRNCY': 'SEK', 'DATE': '2020-09-22'},
 {'CRNCY': 'SEK', 'DATE': '2019-10-18'},
 {'CRNCY': 'AUD', 'DATE': '2019-10-16'},
 {'CRNCY': 'NOK', 'DATE': '2020-04-08'},
 {'CRNCY': 'AUD', 'DATE': '2020-07-29'},
 {'CRNCY': 'AUD', 'DATE': '2020-10-20'}
]

class Table(param.Parameterized):
    CRNCY = param.ListSelector(objects=["NOK", "AUD", "SEK"])
#     TODO: Uncomomment to instantiate param with bounds or without bounds
    DATE = param.CalendarDateRange(bounds=OLD_DATE_BOUNDS)
#     DATE = param.CalendarDateRange()

    @pn.depends("DATE", "CRNCY", watch=True)
    def view(self):
        df = pd.DataFrame(DATA)
        df.DATE = pd.to_datetime(df.DATE)
        if self.CRNCY and len(self.CRNCY):
            df = df.loc[df['CRNCY'].isin(self.CRNCY)]
        if self.DATE:
            _min, _max = self.DATE
            mask = (df['DATE'] >= _min) & (df['DATE'] <= _max)
            df = df.loc[mask]
        return hv.Table(df)

    def handle_click(self, event):
        if self.params()['DATE'].bounds:
            self.DATE = NEW_DATE_BOUNDS
        else:
#             TODO: Update the calendar date range widget with new bounds.
            self.DATE = NEW_DATE_BOUNDS
            print('I cannot interact with widget.')

temp = pn.template.BootstrapTemplate()
table = Table()
button = pn.widgets.Button(name='Update Calendar Date Range Widget', button_type='primary')
button.on_click(table.handle_click)
main_layout = pn.Row(table, table.view, button)
temp.main.append(main_layout)
temp.show()

Is there something incorrect about how I’m dynamically setting bounds in handle_click? Or is this expected behavior?

So this is a combination of a bug and a usage issue. The problem is that a slider cannot be instantiated without setting the bounds so what happens is that it falls back to an LiteralInput widget. The bug is that setting bounds on the parameter will then update the bounds of the LiteralInput widget (even though it doesn’t have any). I’ve filed this bug to fix this: https://github.com/holoviz/panel/issues/1951

Now to your usage error here. There is a difference between the bounds of date range (which sets the limits, and the current value. To set the bounds you would do self.param.DATE.bounds = bounds. That doesn’t currently work due to the bug mentioned above.

1 Like

Thanks @philippjfr! I agree that setting value is more applicable for our use case rather than bounds.

1 Like