Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Add disabled_days prop to datepickers #948

Merged
merged 7 commits into from
Apr 23, 2021

Conversation

tcbegley
Copy link
Contributor

@tcbegley tcbegley commented Apr 8, 2021

Hi,

I've seen a few people requesting on the community forum and elsewhere (e.g. here) that they have the option to make certain days unselectable in the day picker components beyond specifying a range with {min,max}_date_allowed.

As it happens I previously implemented this for a colleague who had the same problem, so thought I would submit it here in case it's of interest. I'm not deeply invested in any aspect of this so if you don't like the interface / implementation / idea that's totally fine 😅 .

I think the main problem with this implementation is that if you wanted to for example disable all weekends over the span of several years you end up passing a pretty long list which could start to affect performance. I suspect for most applications it would be pretty hard to hit this limit but I haven't really investigated this much.

Here's a simple example you can use to test it. It makes only weekdays in April selectable.

from datetime import datetime, timedelta

import dash
import dash_core_components as dcc
import dash_html_components as html

APRIL = [datetime(2021, 4, 1) + timedelta(days=i) for i in range(30)]

app = dash.Dash()

app.layout = html.Div(
    [
        dcc.DatePickerSingle(
            disabled_days=[date for date in APRIL if date.weekday() >= 5],
            min_date_allowed=APRIL[0],
            max_date_allowed=APRIL[-1],
        )
    ],
    style={"padding": "30px"},
)

if __name__ == "__main__":
    app.run_server(debug=True)

which looks something like this

image

@tcbegley tcbegley marked this pull request as ready for review April 15, 2021 08:06
@alexcjohnson
Copy link
Collaborator

@tcbegley this looks like a really nice feature! Before looking at the code, the only thing I'd like to see is a plan for how we would extend this to support patterns of dates to disable, so that you don't have to enumerate them all:

  • January 1 every year
  • The first of every month
  • Every Tuesday

We don't need to implement such patterns in this PR, I just want to make sure we have a consensus on how we would do that in the future, to ensure it wouldn't be a breaking change to the feature as implemented here. Do they fit into the same array with different values? A separate prop?

@tcbegley
Copy link
Contributor Author

I just want to make sure we have a consensus on how we would do that in the future

That sounds like a good idea!

Here's some initial thoughts, but note that I haven't really thought about implementation yet. Since the prop accepts date strings of the form YYYY-MM-DD, would allowing wildcards potentially be one way forward here? It could address your first two examples by allowing the user to pass something like this:

  • disabled_days=["****-01-01"]
  • disabled_days=["****-**-01"]

Days of the week seems harder and would maybe need a different prop. Perhaps it's as simple as disabled_weekdays=[5, 6] or disabled_weekdays=["saturday", "sunday"]? The former is consistent with datetime.date.weekday, the latter is a lot more readable but I guess would require some extra parsing within the component.

Anyway, certainly interested to hear alternative suggestions.

@alexcjohnson
Copy link
Collaborator

OK, having looked at the implementation (which is great, nice and clean! 🎉 ), I think it'll be fine to include arbitrary patterns within the same disabled_days array - whether they're date strings with wildcards, the name of a weekday (I'd rather that than weekday numbers, as that's less readable but also there are differing numbering conventions - that said names are language-dependent so nothing's perfect 🤷 )

So I think all we really need is a test or two - perhaps one test for each component that a disabled date can't be chosen, plus a percy snapshot showing the open datepicker so we can see that the correct dates are visibly disabled.

@alexcjohnson
Copy link
Collaborator

also there are differing numbering conventions

Actually we already build in Sunday=0 via first_day_of_week - so I stand corrected, we should keep using that (if and when we get to this extension 😁 )

@tcbegley
Copy link
Contributor Author

Great! I'll add some tests in the next few days.

@tcbegley
Copy link
Contributor Author

Added some tests. From what I can tell by looking at the logs they are failing because CircleCI is installing dash-core-components 1.16.0, but when I build from this branch it builds version 1.15.0. Not sure the best way to fix that?

@alexcjohnson
Copy link
Collaborator

Added some tests. From what I can tell by looking at the logs they are failing because CircleCI is installing dash-core-components 1.16.0, but when I build from this branch it builds version 1.15.0. Not sure the best way to fix that?

Right, this is a quirk of our CI setup - we've released a new dash version since you created this PR, if you merge in the latest dev this problem will go away.

@tcbegley
Copy link
Contributor Author

This is ready for review now, Percy is failing because I added new snapshots, but all seems to be working.

Copy link
Collaborator

@alexcjohnson alexcjohnson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent - nice tests! 💃

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants