@code {
- ///
- /// SubmitText
- ///
- private string? SubmitText { get; set; }
-
///
/// ModelValidateValue
///
[Required]
public DateTime? Value { get; set; }
-
- ///
- /// OnInitialized 方法
- ///
- protected override void OnInitialized()
- {
- SubmitText ??= Localizer[nameof(SubmitText)];
- }
}
diff --git a/src/BootstrapBlazor.Shared/Locales/en.json b/src/BootstrapBlazor.Shared/Locales/en.json
index be8e09c1ffcd5bcbd011c789eea0ee715f33d6e7..74490a122adc5f48fc1ff6fc5844341ff7d7dc4d 100644
--- a/src/BootstrapBlazor.Shared/Locales/en.json
+++ b/src/BootstrapBlazor.Shared/Locales/en.json
@@ -2559,10 +2559,10 @@
"TimeIntro": "Click the confirm button to select the box value consistent with the text box value",
"ValidateFormTitle": "Client validation",
"ValidateFormIntro": "Check data validity and prompt automatically based on custom validation rules",
- "DateTitle": "Click on the pop-up date box",
- "DateIntro": "Select the control based on the date of the day in 「day」 as the base unit",
- "PlacementTitle": "Data is bound in both directions",
- "PlacementIntro": "The values in the text box change as the date component time changes",
+ "DateTimeOffsetTitle": "Click on the pop-up date box",
+ "DateTimeOffsetIntro": "Select the control based on the date of the day in 「day」 as the base unit",
+ "BindValueTitle": "Data is bound in both directions",
+ "BindValueIntro": "The values in the text box change as the date component time changes",
"ViewModeTitle": "Selector with time",
"ViewModeIntro": "Select the date and time in the same selector, click the confirm button and close the pop-up window",
"ViewModeTip": "Set the value of the viewMode property to The DateTime of DatePickerViewMode.DateTime",
diff --git a/src/BootstrapBlazor.Shared/Locales/zh.json b/src/BootstrapBlazor.Shared/Locales/zh.json
index 05bd406845785cf4f3f44958f0f7773d793d9192..01e15baab7e0665dcdafa28100f49839ac42f211 100644
--- a/src/BootstrapBlazor.Shared/Locales/zh.json
+++ b/src/BootstrapBlazor.Shared/Locales/zh.json
@@ -2566,10 +2566,10 @@
"TimeIntro": "点击确认按钮时间选择框值与文本框值一致",
"ValidateFormTitle": "客户端验证",
"ValidateFormIntro": "根据自定义验证规则进行数据有效性检查并自动提示",
- "DateTitle": "点击弹出日期框",
- "DateIntro": "以「日」为基本单位,基础的日期选择控件",
- "PlacementTitle": "数据双向绑定",
- "PlacementIntro": "日期组件时间改变时文本框内的数值也跟着改变",
+ "DateTimeOffsetTitle": "点击弹出日期框",
+ "DateTimeOffsetIntro": "以「日」为基本单位,基础的日期选择控件,此示例绑定 DateTimeOffset 数据类型",
+ "BindValueTitle": "数据双向绑定",
+ "BindValueIntro": "日期组件时间改变时文本框内的数值也跟着改变",
"ViewModeTitle": "带时间的选择器",
"ViewModeIntro": "在同一个选择器里选择日期和时间,点击确认按钮后关闭弹窗",
"ViewModeTip": "设置 ViewMode 属性值为 DatePickerViewMode.DateTime",
diff --git a/src/BootstrapBlazor.Shared/Samples/DateTimePickers.razor b/src/BootstrapBlazor.Shared/Samples/DateTimePickers.razor
index b9a2f15b589f98f7797893522edbee1bf7fa4243..d61475fd253606e9e0a39e009be8feeeda49e291 100644
--- a/src/BootstrapBlazor.Shared/Samples/DateTimePickers.razor
+++ b/src/BootstrapBlazor.Shared/Samples/DateTimePickers.razor
@@ -12,9 +12,9 @@
-
+
-
+
@((MarkupString)Localizer["ViewModeTip"].Value)
diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj
index 8470706856182e71e25c3e5014fb0ae4beca948e..dfb5556c0d05dd9c04bbc7ba9e7056eba46fda48 100644
--- a/src/BootstrapBlazor/BootstrapBlazor.csproj
+++ b/src/BootstrapBlazor/BootstrapBlazor.csproj
@@ -1,7 +1,7 @@
- 7.1.9-beta04
+ 7.2.0
diff --git a/src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor.cs b/src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor.cs
index cecf5592f4be7cb6f6cf273096282f09fc2acd5f..9db39665db2d98fb086e899872a86c43cff921c8 100644
--- a/src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor.cs
+++ b/src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor.cs
@@ -57,9 +57,7 @@ public partial class DatePickerBody
.AddClass("current", day == Value && Ranger == null && day.Month == CurrentDate.Month && !overflow)
.AddClass("start", Ranger != null && day == Ranger.SelectedValue.Start.Date)
.AddClass("end", Ranger != null && day == Ranger.SelectedValue.End.Date)
- .AddClass("range", Ranger != null && CurrentDate.Month >= Ranger.SelectedValue.Start.Month
- && Ranger.SelectedValue.Start != DateTime.MinValue && Ranger.SelectedValue.End != DateTime.MinValue
- && day >= Ranger.SelectedValue.Start && day <= Ranger.SelectedValue.End)
+ .AddClass("range", Ranger != null && day >= Ranger.SelectedValue.Start && day <= Ranger.SelectedValue.End)
.AddClass("today", day == DateTime.Today)
.AddClass("disabled", IsDisabled(day) || overflow)
.Build();
diff --git a/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs b/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs
index d98700a85a04f072589c5047a2a9405b7a8c8b6a..d934f55555a1163e001c4030767b2d3062929414 100644
--- a/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs
+++ b/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs
@@ -137,6 +137,13 @@ public partial class DateTimePicker
{
base.OnParametersSet();
+ DateTimePlaceHolderText ??= Localizer[nameof(DateTimePlaceHolderText)];
+ DatePlaceHolderText ??= Localizer[nameof(DatePlaceHolderText)];
+ GenericTypeErroMessage ??= Localizer[nameof(GenericTypeErroMessage)];
+ DateTimeFormat ??= Localizer[nameof(DateTimeFormat)];
+ DateFormat ??= Localizer[nameof(DateFormat)];
+ Icon ??= "fa-regular fa-calendar-days";
+
var type = typeof(TValue);
// 判断泛型类型
@@ -145,13 +152,6 @@ public partial class DateTimePicker
throw new InvalidOperationException(GenericTypeErroMessage);
}
- DateTimePlaceHolderText ??= Localizer[nameof(DateTimePlaceHolderText)];
- DatePlaceHolderText ??= Localizer[nameof(DatePlaceHolderText)];
- GenericTypeErroMessage ??= Localizer[nameof(GenericTypeErroMessage)];
- DateTimeFormat ??= Localizer[nameof(DateTimeFormat)];
- DateFormat ??= Localizer[nameof(DateFormat)];
- Icon ??= "fa-regular fa-calendar-days";
-
// 泛型设置为可为空
AllowNull = Nullable.GetUnderlyingType(type) != null;
@@ -167,13 +167,25 @@ public partial class DateTimePicker
}
// Value 为 MinValue 时 设置 Value 默认值
- if (AutoToday)
+ if (AutoToday && (Value == null || Value.ToString() == DateTime.MinValue.ToString()))
{
- if (Value == null || Value.ToString() == DateTime.MinValue.ToString())
+ SelectedValue = DateTime.Today;
+ if (!AllowNull)
{
- SelectedValue = DateTime.Today;
+ CurrentValueAsString = SelectedValue.ToString("yyyy-MM-dd HH:mm:ss");
}
}
+ else if (Value is DateTime dt)
+ {
+ SelectedValue = dt;
+ }
+ else
+ {
+ var offset = (DateTimeOffset?)(object)Value;
+ SelectedValue = offset.HasValue
+ ? offset.Value.DateTime
+ : DateTime.MinValue;
+ }
}
///
diff --git a/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor.cs b/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor.cs
index 7d4efdeed31ae79471c390f667cfc0b169f5ef75..ab5b283f1177f2198d4aeeb6380cfe7dcceecabb 100644
--- a/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor.cs
+++ b/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor.cs
@@ -324,7 +324,7 @@ public partial class DateTimeRange
///
internal void UpdateStart(DateTime d)
{
- StartValue = StartValue.AddYears(d.Year - StartValue.Year).AddMonths(d.Month - StartValue.Month);
+ StartValue = d;
EndValue = StartValue.AddMonths(1);
StateHasChanged();
}
@@ -335,7 +335,7 @@ public partial class DateTimeRange
///
internal void UpdateEnd(DateTime d)
{
- EndValue = EndValue.AddYears(d.Year - EndValue.Year).AddMonths(d.Month - EndValue.Month);
+ EndValue = d;
StartValue = EndValue.AddMonths(-1);
StateHasChanged();
}
@@ -364,11 +364,12 @@ public partial class DateTimeRange
SelectedValue.End = DateTime.MinValue;
}
- if (d.Year < StartValue.Year || d.Month < StartValue.Month)
+ var startDate = StartValue.AddDays(1 - StartValue.Day);
+ if (d < startDate)
{
UpdateStart(d);
}
- else if (d.Month > EndValue.Month)
+ else if (d > startDate.AddMonths(2).AddDays(-1))
{
UpdateEnd(d);
}
diff --git a/test/UnitTest/Components/DateTimePickerTest.cs b/test/UnitTest/Components/DateTimePickerTest.cs
index b9a8da51039fe5ff14c999b2badd1d78276cc1a4..ec9fa74bcabb8e6f97cea24d31b945df5581814c 100644
--- a/test/UnitTest/Components/DateTimePickerTest.cs
+++ b/test/UnitTest/Components/DateTimePickerTest.cs
@@ -17,7 +17,61 @@ public class DateTimePickerTest : BootstrapBlazorTestBase
pb.Add(a => a.Value, DateTime.MinValue);
});
// 设置 Value 为 MinValue 内部更改为 DateTime.Now
- Assert.NotEqual(DateTime.MinValue, cut.Instance.Value);
+ Assert.Equal(DateTime.MinValue, cut.Instance.Value);
+ }
+
+ [Fact]
+ public void AutoToday_Ok()
+ {
+ var cut = Context.RenderComponent>(pb =>
+ {
+ pb.Add(a => a.Value, DateTime.MinValue);
+ });
+ Assert.Equal(DateTime.Today, cut.Instance.Value);
+
+ cut.SetParametersAndRender(pb =>
+ {
+ pb.Add(a => a.AutoToday, false);
+ pb.Add(a => a.Value, DateTime.MinValue);
+ });
+ Assert.Equal(DateTime.MinValue, cut.Instance.Value);
+ }
+
+ [Fact]
+ public void AllowNull_Ok()
+ {
+ var cut = Context.RenderComponent>(pb =>
+ {
+ pb.Add(a => a.Value, DateTime.MinValue);
+ });
+ Assert.Equal(DateTime.MinValue, cut.Instance.Value);
+ }
+
+ [Fact]
+ public void DataTimeOffsetNull_Ok()
+ {
+ var cut = Context.RenderComponent>(pb =>
+ {
+ pb.Add(a => a.Value, DateTimeOffset.MinValue);
+ });
+ Assert.Equal(DateTimeOffset.MinValue, cut.Instance.Value);
+
+ cut.SetParametersAndRender(pb =>
+ {
+ pb.Add(a => a.Value, null);
+ pb.Add(a => a.AutoToday, false);
+ });
+ Assert.Null(cut.Instance.Value);
+ }
+
+ [Fact]
+ public void DataTimeOffset_Ok()
+ {
+ var cut = Context.RenderComponent>(pb =>
+ {
+ pb.Add(a => a.Value, DateTimeOffset.MinValue);
+ });
+ Assert.Equal(DateTimeOffset.MinValue, cut.Instance.Value);
}
[Fact]
@@ -105,6 +159,13 @@ public class DateTimePickerTest : BootstrapBlazorTestBase
cut.InvokeAsync(() => buttons[0].Click());
Assert.Null(cut.Instance.Value);
+
+ cut.SetParametersAndRender(pb =>
+ {
+ pb.Add(a => a.AutoToday, false);
+ });
+ cut.InvokeAsync(() => buttons[0].Click());
+ Assert.Null(cut.Instance.Value);
}
[Fact]
@@ -753,7 +814,6 @@ public class DateTimePickerTest : BootstrapBlazorTestBase
Assert.True(confirm);
}
- [JSModuleNotInherited]
class MockDateTimePicker : DatePickerBody
{
public static bool GetSafeYearDateTime_Ok()
diff --git a/test/UnitTest/Components/DateTimeRangeTest.cs b/test/UnitTest/Components/DateTimeRangeTest.cs
index d5afd323353686820fe6f667d83175b2d63dac9a..9f7ec272fcc66797da947b302b5e46d420e063a4 100644
--- a/test/UnitTest/Components/DateTimeRangeTest.cs
+++ b/test/UnitTest/Components/DateTimeRangeTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/
+using AngleSharp.Dom;
using System.ComponentModel.DataAnnotations;
namespace UnitTest.Components;
@@ -30,6 +31,26 @@ public class DateTimeRangeTest : BootstrapBlazorTestBase
// 内部 StartValue 自动减一个月
}
+ [Fact]
+ public void RangeValue_Ok()
+ {
+ var cut = Context.RenderComponent();
+ var cells = cut.FindAll(".date-table tbody span");
+ var end = cells.First(i => i.TextContent == "7");
+ var first = cells.First(i => i.TextContent == "1");
+ cut.InvokeAsync(() => end.Click());
+ cut.InvokeAsync(() => first.Click());
+
+ // confirm
+ var confirm = cut.FindAll(".is-confirm").Last();
+ cut.InvokeAsync(() => confirm.Click());
+ var value = cut.Instance.Value;
+ var startDate = DateTime.Today.AddDays(1 - DateTime.Today.Day);
+ var endDate = startDate.AddDays(7).AddSeconds(-1);
+ Assert.Equal(startDate, value.Start);
+ Assert.Equal(endDate, value.End);
+ }
+
[Fact]
public void TodayButtonText_Ok()
{