jdtcn / BlazorDateRangePicker

A Blazor component for choosing date ranges and dates
MIT License
186 stars 34 forks source link

Tab out does not close selection box #51

Closed bradirby closed 3 years ago

bradirby commented 3 years ago

I'm building an app where data entry is done primarily with the keyboard, not the mouse. I like how fast your date picker is for this purpose. When I tab into the field the selection box opens, but when I tab out the box does not close up. I need to click the mouse to close the box. It will close if I add a complete date, but leaving the date blank, not changing an existing date, or adding an invalid partial date, all leave the dialog visible when tabbing out.

This is how I am specifying the picker, though the problem occurs with all sets of parameters. <DateRangePicker SingleDatePicker="true" ShowDropdowns="false"/>

jdtcn commented 3 years ago

Hi,

I'll fix this problem in the next release, I just haven't decided yet how exactly to do it.

But you can solve the problem like that:


<DateRangePicker @ref="Picker" SingleDatePicker="true" ShowDropdowns="false" @onblur="OnBlur" />

@code {
    DateRangePicker Picker;

    private Task OnBlur(FocusEventArgs e)
    {
        return Picker.Close();
    }
}
bradirby commented 3 years ago

Nice! thanks. that's an easy workaround to implement.

I have a question that's not a bug - I want to use the SingleDatePicker but for the end date, not the start date. It's for a scheduling app and the start date is when the order was placed (so cannot be changed), but the user needs to set the delivery date. I like how your UI shows the days between the two dates, but I don't want them editing the start date. Is there a way to do that?

Thanks for contributing this component. If there's no way to do this now, i can give it a try and send you a PR.

jdtcn commented 3 years ago

Anything is possible with custom click handlers (see this demo).

Example for fixed start date:

<DateRangePicker @ref="Picker" StartDate="FixedStartDate" OnMonthChanged="MonthChanged" />

@code {
    DateRangePicker Picker { get; set; }

    DateTimeOffset FixedStartDate { get; } = DateTime.Now.AddDays(-10);

    private void MonthChanged()
    {
        UpdateClickHandlers();
    }

    private void UpdateClickHandlers()
    {
        var days = Enumerable
            .Concat(Picker.LeftCalendar.Calendar, Picker.RightCalendar.Calendar)
            .SelectMany(d => d);

        foreach (var day in days)
        {
            var dayClick = day.Click;
            day.Click = () =>
            {
                if (day.Day > FixedStartDate && Picker.TStartDate.HasValue && Picker.TEndDate.HasValue)
                {
                    Picker.TStartDate = FixedStartDate;
                    Picker.TEndDate = null;
                    dayClick.Invoke();
                }
                else if (day.Day > FixedStartDate)
                {
                    dayClick.Invoke();
                }
            };
        }
    }
}