Skip to content

Fix Inconsistent behavior occurs when using @bind and @bind-value in input date type#67310

Open
NanthiniMahalingam wants to merge 3 commits into
dotnet:mainfrom
NanthiniMahalingam:fix-40660
Open

Fix Inconsistent behavior occurs when using @bind and @bind-value in input date type#67310
NanthiniMahalingam wants to merge 3 commits into
dotnet:mainfrom
NanthiniMahalingam:fix-40660

Conversation

@NanthiniMahalingam

Copy link
Copy Markdown

Bug Description

Inconsistent behavior occurs when using @Bind and @bind-value in input date type

Description of code changes

  • Set to default for string empty values if T is nullable or string. For format-based non-nullable types like DateTime, don't update (keep previous value) to avoid resetting to invalid defaults like DateTime.MinValue.
  • Return an empty string (rather than null) so a null nullable date formats the same way an empty date input reports its value to the server. This keeps the rendered 'value' attribute in sync with what the browser already shows, preventing the diff from re-writing it and resetting the caret/segments while the user is typing (e.g. ).

Output

Before changes

Beforefix40660.mp4

After changes

Afterfix40660_1.mp4

Fixes #40660

@NanthiniMahalingam NanthiniMahalingam marked this pull request as ready for review June 23, 2026 11:12
@NanthiniMahalingam NanthiniMahalingam requested a review from a team as a code owner June 23, 2026 11:12
Copilot AI review requested due to automatic review settings June 23, 2026 11:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes inconsistent <input type="date"> editing behavior in Blazor when using @bind/@bind-value with date/time types by avoiding disruptive re-renders during segmented date entry and aligning formatted null output with what browsers report for empty date inputs.

Changes:

  • Adjusts binder empty-string handling to avoid resetting date/time values to invalid defaults while users are editing.
  • Updates BindConverter formatting for nullable date/time types to return "" (instead of null) so rendered value stays in sync with the browser’s empty value.
  • Adds regression tests covering non-nullable DateTime empty-string scenarios (and should be extended to cover async setter overloads).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs Updates binder behavior when the browser reports an empty string during change events.
src/Components/Components/src/BindConverter.cs Formats nullable date/time values as empty string to keep rendered value aligned with browser state.
src/Components/Components/test/EventCallbackFactoryBinderExtensionsTest.cs Adds regression tests for non-nullable DateTime empty string binder scenarios.

Comment on lines +482 to +500
[Fact]
public async Task CreateBinder_NonNullableDateTime_EmptyValue_PreservesEachBoundValue()
{
var value = new DateTime(2022, 2, 10);
var component = new EventCountingComponent();
Action<DateTime> setter = (_) => value = _;

EventCallback<ChangeEventArgs> binder = EventCallback.Factory.CreateBinder(component, setter, value, "yyyy-MM-dd", CultureInfo.InvariantCulture);
await binder.InvokeAsync(new ChangeEventArgs() { Value = string.Empty, });
Assert.Equal(1, component.Count);
var value1 = new DateTime(2023, 02, 09);
Action<DateTime> setter1 = (_) => value1 = _;

var binder1 = EventCallback.Factory.CreateBinder(component, setter1, value1, "yyyy-MM-dd", CultureInfo.InvariantCulture);
await binder1.InvokeAsync(new ChangeEventArgs() { Value = string.Empty, });
// The setter must not have been called, so the previous valid value is preserved.
Assert.Equal(new DateTime(2023, 02, 9), value1);
Assert.Equal(2, component.Count);
}
Comment on lines 1374 to +1378
else if (string.Empty.Equals(e.Value))
{
setter(default!);
var typeInfo = typeof(T);
var isNullable = typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>);
if (typeInfo == typeof(string) || isNullable)
Comment on lines 1466 to +1470
else if (string.Empty.Equals(e.Value))
{
setter(default!);
var typeInfo = typeof(T);
var isNullable = typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>);
if (typeInfo == typeof(string) || isNullable)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@bind and @bind-Value and @bind-Value for extra model behave different for datetime

2 participants