Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

[BUG] dcc.DatePickerRange doesn't update on blur

Đang mở
#3,678 0 bình luận 0 reaction 1 người được giao Xem trên GitHub

@KoolADE85 đang làm issue này rồi.

Từ ngày 20/3/2026.

Đánh giá

Issue này chưa được đánh giá.

Mô tả

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

  1. Run sample code (available at the end of the issue).
  2. Click into the start (or end) input and type a valid date.
  3. 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

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.
Ngôn ngữ chính
Python
Star
24.4k
Fork
2.3k
Merge trung bình
1 ngày 19 giờ
Pull request đã merge (30 ngày)
19

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của plotly/dash

Tất cả issue của plotly/dash

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.