DateField#
A date input field with locale-aware display formatting and an optional calendar picker button. Supports single-date and date-range selection modes.
Usage#
Basic usage#
bs.DateField(label="Select a date")
Display formats#
The value_format= parameter controls how dates are displayed in the field.
Any ICU date format pattern or named preset is accepted.
bs.DateField(value=today, value_format="longDate") # January 15, 2025
bs.DateField(value=today, value_format="shortDate") # 1/15/25
bs.DateField(value=today, value_format="monthAndYear") # January 2025
bs.DateField(value=today, value_format="yyyy-MM-dd") # 2025-01-15
Range mode#
Set selection_mode='range' to let the user pick a start and end date.
The entry becomes read-only in this mode — dates must be chosen via the picker.
value returns a (start, end) tuple of date objects.
df = bs.DateField(
selection_mode="range",
range_start=date(2025, 1, 1),
range_end=date(2025, 1, 31),
label="Date range",
)
start, end = df.value # tuple[date, date]
Date constraints#
Use min_date=, max_date=, or disabled_dates= to restrict which
dates the picker shows as selectable.
from datetime import date, timedelta
today = date.today()
bs.DateField(
label="Booking date",
min_date=today,
max_date=today + timedelta(days=30),
disabled_dates=[today + timedelta(days=7)],
)
min_date, max_date, and disabled_dates are also live properties —
assign to them to update the constraints (the change takes effect the next time
the picker opens):
df.min_date = date.today() # no past dates
df.disabled_dates = booked_dates
Reactive binding#
Pass a Signal[str] via textsignal= to keep the field text in sync with
application state.
date_sig = bs.Signal("")
bs.DateField(label="Pick a date", textsignal=date_sig)
bs.Label(textsignal=date_sig, accent="secondary")
Handling changes#
on_change() fires whenever the selected date changes — whether by keyboard
input, picker selection, or value= assignment.
df = bs.DateField(label="Appointment")
df.on_change(lambda e: print("Selected:", df.value))
States#
bs.DateField(value=today, label="Normal")
bs.DateField(value=today, label="Read only", read_only=True)
bs.DateField(value=today, label="Disabled", disabled=True)
Widget sizing#
All widgets accept self-placement kwargs via **kwargs. The parent
container determines which options apply — stack-based parents use stack
kwargs, grid-based parents use grid kwargs. Unrecognised keys are
silently ignored.
Stack#
Used inside VStack, HStack, App, and other stack containers.
|
Fill direction: |
|
Grow to consume extra space in the parent. |
|
Alignment when the widget does not fill the available slot:
|
|
External spacing in pixels. Accepts an integer (equal on all
sides), a 2-tuple |
|
Horizontal external spacing (left and right). Accepts an integer
or a 2-tuple |
|
Vertical external spacing (top and bottom). Accepts an integer
or a 2-tuple |
Grid#
Used inside a Grid container.
|
Zero-based row and column indices. |
|
Number of rows or columns to span. |
|
Alignment and fill within the grid cell. Any combination of
|
|
External spacing in pixels. Accepts an integer, a 2-tuple
|
|
Horizontal external spacing. Accepts an integer or |
|
Vertical external spacing. Accepts an integer or |
See also#
API#
The complete reference for DateField lives on the
Widgets API page. At a glance:
A date input field with an optional calendar picker button. |
Full Example#
1
2with bs.App(title="DateField Demo", padding=20, gap=16) as app:
3
4 # Basic usage
5 bs.Label("Basic", font="heading-sm")
6 bs.DateField(label="Select a date")
7
8 # Date format presets
9 bs.Label("Display Formats", font="heading-sm")
10 today = date.today()
11 bs.DateField(value=today, label="Long date (default)", value_format="longDate")
12 bs.DateField(value=today, label="Short date", value_format="shortDate")
13 bs.DateField(value=today, label="Month and year", value_format="monthAndYear")
14
15 # Range mode
16 bs.Label("Range Mode", font="heading-sm")
17 bs.DateField(
18 selection_mode="range",
19 range_start=date(today.year, today.month, 1),
20 range_end=today,
21 label="Date range",
22 message="Select a start and end date.",
23 )
24
25 # Min / max date constraints
26 bs.Label("Constrained Dates", font="heading-sm")
27 from datetime import timedelta
28 bs.DateField(
29 label="Booking date",
30 message="Must be within the next 30 days.",
31 min_date=today,
32 max_date=today + timedelta(days=30),
33 )
34
35 # Reactive binding
36 bs.Label("Reactive Binding", font="heading-sm")
37 date_sig = bs.Signal("")
38 df = bs.DateField(label="Pick a date", textsignal=date_sig)
39 bs.Label(textsignal=date_sig, accent="secondary")
40
41 # States
42 bs.Label("States", font="heading-sm")
43 bs.DateField(value=today, label="Normal")
44 bs.DateField(value=today, label="Read only", read_only=True)
45 bs.DateField(value=today, label="Disabled", disabled=True)
46
47 # Handling changes
48 bs.Label("Handling Changes", font="heading-sm")
49 last = bs.Signal("(none)")
50 picker = bs.DateField(label="Choose a date")
51 picker.on_change(lambda e: last.set(str(picker.value)))
52 bs.Label(textsignal=last, accent="secondary")
53
54 # Validation
55 bs.Label("Validation", font="heading-sm")
56 validated = bs.DateField(label="Required date", required=True)
57 with bs.HStack(gap=8):
58 bs.Button("Validate", on_click=lambda: validated.validate())
59
60app.run()