[BUG] dcc.DatePickerRange doesn't update on blur
@KoolADE85 がすでに取り組んでいます。
2026年3月20日 から。
評価
この issue はまだ評価されていません。
説明
Description of the issue
When a user types a date directly into dcc.DatePickerRange’s start/end text inputs, Dash doesn’t update start_date / end_date (and callbacks don’t fire) unless the user presses Enter (or arrow up, arrow down or tab). If the user types a valid date and then clicks elsewhere (input loses focus), the typed value is not committed.
Steps to reproduce
- Run sample code (available at the end of the issue).
- Click into the start (or end) input and type a valid date.
- Click outside the component (blur) without pressing Enter.
Current behavior
No update occurs until Enter (or Tab) is pressed.
https://github.com/user-attachments/assets/2a1602d4-61ad-45af-ac9a-af7122676edc
Expected behavior
The typed date is parsed/committed on blur and start_date / end_date update, triggering callbacks:
https://github.com/user-attachments/assets/28724130-74b1-4818-9662-baa62a63538b
Suggested fix
https://github.com/plotly/dash/blob/v4.0.0/components/dash-core-components/src/fragments/DatePickerRange.tsx#L345-L351
Add onBlur handlers to both AutosizeInput fields to call the existing commit functions:
onBlur={() => sendStartInputAsDate()}onBlur={() => sendEndInputAsDate()}
This would commit typed values on unfocus, which then flows to setProps via the existing useEffect that emits updates when internalStartDate / internalEndDate change.
Code to reproduce and workaround
Code to reproduce
- dash==4.0.0
- From: https://dash.plotly.com/dash-core-components/datepickerrange#simple-datepickerrange-example
from datetime import date
from dash import Dash, dcc, html, Input, Output, State, callback, clientside_callback
import dash
app = Dash()
app.layout = html.Div([
html.Div(f"dash version: {dash.__version__}"),
html.Div(id='output-container-date-picker-range'),
dcc.DatePickerRange(
id='my-date-picker-range',
initial_visible_month=date(2017, 8, 5),
),
])
@callback(
Output('output-container-date-picker-range', 'children'),
Input('my-date-picker-range', 'start_date'),
Input('my-date-picker-range', 'end_date'))
def update_output(start_date, end_date):
string_prefix = 'You have selected: '
if start_date is not None:
start_date_object = date.fromisoformat(start_date)
start_date_string = start_date_object.strftime('%B %d, %Y')
string_prefix = string_prefix + 'Start Date: ' + start_date_string + ' | '
if end_date is not None:
end_date_object = date.fromisoformat(end_date)
end_date_string = end_date_object.strftime('%B %d, %Y')
string_prefix = string_prefix + 'End Date: ' + end_date_string
if len(string_prefix) == len('You have selected: '):
return 'Select a date to see it displayed here'
else:
return string_prefix
if __name__ == '__main__':
app.run(debug=True, use_reloader=False, dev_tools_hot_reload=False)
Workaround
Add this clientside callback:
from dash import clientside_callback
clientside_callback(
"""
function(component_id) {
// Use a small timeout to allow React to finish rendering the DOM nodes
setTimeout(() => {
const start_date = document.getElementById(`${component_id}`);
const end_date = document.getElementById(`${component_id}-end-date`);
if (start_date) {
start_date.onblur = () => {
start_date.dispatchEvent(new KeyboardEvent('keydown', {
key: 'Tab',
bubbles: true
}));
};
}
if (end_date) {
end_date.onblur = () => {
end_date.dispatchEvent(new KeyboardEvent('keydown', {
key: 'Tab',
bubbles: true
}));
};
}
}, 500); // 500ms is usually enough for the DOM to settle
return component_id;
}
""",
Output('my-date-picker-range', 'id'),
Input('my-date-picker-range', 'id')
)
- This code adds an event listener for both the start and end date text boxes. This event listener simulates a "Tab" key press when the focus is taken from those text boxes (i.e. when the blur event happens).
- The code regarding the timeout is to make sure that the clientside callback runs once the DatePickerRange textboxes are renderer on the page. Otherwise, we'll get errors like:
can't access property "onblur", start_date is null. - Since the input is the DatePickerRange id, this clientside_callback will only run once.
- 主要言語
- Python
- スター
- 24.4k
- フォーク
- 2.3k
- 平均マージ
- 1日 19時間
- マージ済み PR(30日)
- 19
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
plotly/dash のほかの issue
-
good first issue P3 size: 1 task
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
enhancement P2 size: 5
難易度 5/5 1週間以上 初心者へのやさしさ 45/100
-
enhancement P3 size: 10+
-
P2 size: 1 task
-
enhancement P3 size: 1
難易度 3/5 1〜2日 初心者へのやさしさ 72/100
似ている issue
-
essnmx good first issue
難易度 1/5 1時間未満 初心者へのやさしさ 95/100
-
[Feature] 奇物选择添加优先级 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
syfoud/Simulated_Scepter#174 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
Giskard-AI/giskard-oss#2840 · コメント 1 件 ·
-
A claim comment carrying the issue number is silently declined while the workflow reports success オープンarea: repo bug perceived difficulty: 2
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
yeti-platform/yeti#1380 ·