diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 1b4c26eae94..7185b9c967b 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@ - 9.3.1-beta25 + 9.3.1-beta26 diff --git a/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor b/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor index 04317f29135..cc5ed32815c 100644 --- a/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor +++ b/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor @@ -1,7 +1,7 @@ @namespace BootstrapBlazor.Components @typeparam TValue @inherits PopoverDropdownBase -@attribute [BootstrapModuleAutoLoader("DateTimePicker/DateTimePicker.razor.js")] +@attribute [BootstrapModuleAutoLoader("DateTimePicker/DateTimePicker.razor.js", JSObjectReference = true)] @if (IsShowLabel) { diff --git a/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs b/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs index caf7cf7d335..d02cec3c5ab 100644 --- a/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs +++ b/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs @@ -372,6 +372,15 @@ protected override string FormatValueAsString(TValue? value) return ret; } + /// + /// + /// + /// + protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, new + { + TriggerHideCallback = nameof(TriggerHideCallback) + }); + private bool MinValueToEmpty(DateTime val) => val == DateTime.MinValue && AllowNull && DisplayMinValueAsEmpty; private bool MinValueToToday(DateTime val) => val == DateTime.MinValue && !AllowNull && AutoToday; @@ -454,4 +463,15 @@ protected virtual async Task OnBlur() await OnBlurAsync(Value); } } + + /// + /// 客户端弹窗关闭后由 Javascript 调用此方法 + /// + /// + [JSInvokable] + public Task TriggerHideCallback() + { + StateHasChanged(); + return Task.CompletedTask; + } } diff --git a/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.js b/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.js index d45c4fd26ad..f98b7dc7712 100644 --- a/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.js +++ b/src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.js @@ -2,7 +2,7 @@ import EventHandler from "../../modules/event-handler.js" import Popover from "../../modules/base-popover.js" -export function init(id) { +export function init(id, invoke, options) { const el = document.getElementById(id) if (el == null) { return @@ -13,6 +13,9 @@ export function init(id) { dropdownSelector: el.getAttribute('data-bb-dropdown'), isDisabled: () => { return el.classList.contains('disabled'); + }, + hideCallback: () => { + invoke?.invokeMethodAsync(options.triggerHideCallback); } }); const dateTimePicker = { diff --git a/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor b/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor index d62025a0b20..6446d8b82c5 100644 --- a/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor +++ b/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor @@ -1,6 +1,6 @@ @namespace BootstrapBlazor.Components @inherits PopoverDropdownBase -@attribute [BootstrapModuleAutoLoader("DateTimePicker/DateTimePicker.razor.js")] +@attribute [BootstrapModuleAutoLoader("DateTimePicker/DateTimePicker.razor.js", JSObjectReference = true)] @if (IsShowLabel) { diff --git a/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor.cs b/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor.cs index eb66001c8c4..f8ebec6eca0 100644 --- a/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor.cs +++ b/src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor.cs @@ -311,24 +311,7 @@ protected override void OnParametersSet() new() { Text = Localizer["LastMonth"], StartDateTime = DateTime.Today.AddDays(1- DateTime.Today.Day).AddMonths(-1), EndDateTime = DateTime.Today.AddDays(1- DateTime.Today.Day).AddSeconds(-1) }, ]; - Value ??= new DateTimeRangeValue(); - EndValue = Value.End == DateTime.MinValue ? GetEndDateTime(DateTime.Today) : Value.End; - - if (ViewMode == DatePickerViewMode.Year) - { - var d = DateTime.Today.AddYears(-1); - StartValue = Value.Start == DateTime.MinValue ? new DateTime(d.Year, 1, 1) : Value.Start; - } - else if (ViewMode == DatePickerViewMode.Month) - { - var d = DateTime.Today.AddMonths(-1); - StartValue = Value.Start == DateTime.MinValue ? new DateTime(d.Year, d.Month, 1) : Value.Start; - } - else - { - StartValue = EndValue.AddMonths(-1).Date; - } - + ResetBodyValue(); SelectedValue.Start = Value.Start; SelectedValue.End = Value.End; @@ -342,6 +325,15 @@ void CheckValid() } } + /// + /// + /// + /// + protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, new + { + TriggerHideCallback = nameof(TriggerHideCallback) + }); + private async Task OnClickSidebarItem(DateTimeRangeSidebarItem item) { SelectedValue.Start = item.StartDateTime; @@ -505,4 +497,37 @@ private void UpdateValue(DateTime d) public override bool IsComplexValue(object? propertyValue) => false; private static DateTime GetEndDateTime(DateTime dt) => dt.Date.AddHours(23).AddMinutes(59).AddSeconds(59); + + private void ResetBodyValue() + { + Value ??= new DateTimeRangeValue(); + EndValue = Value.End == DateTime.MinValue ? GetEndDateTime(DateTime.Today) : Value.End; + + if (ViewMode == DatePickerViewMode.Year) + { + var d = DateTime.Today.AddYears(-1); + StartValue = Value.Start == DateTime.MinValue ? new DateTime(d.Year, 1, 1) : Value.Start; + } + else if (ViewMode == DatePickerViewMode.Month) + { + var d = DateTime.Today.AddMonths(-1); + StartValue = Value.Start == DateTime.MinValue ? new DateTime(d.Year, d.Month, 1) : Value.Start; + } + else + { + StartValue = EndValue.AddMonths(-1).Date; + } + } + + /// + /// 客户端弹窗关闭后由 Javascript 调用此方法 + /// + /// + [JSInvokable] + public Task TriggerHideCallback() + { + ResetBodyValue(); + StateHasChanged(); + return Task.CompletedTask; + } } diff --git a/src/BootstrapBlazor/wwwroot/modules/base-popover.js b/src/BootstrapBlazor/wwwroot/modules/base-popover.js index ab56632a90b..a2b7b47c532 100644 --- a/src/BootstrapBlazor/wwwroot/modules/base-popover.js +++ b/src/BootstrapBlazor/wwwroot/modules/base-popover.js @@ -14,9 +14,10 @@ const Popover = { isDisabled: () => { return isDisabled(el) || isDisabled(el.parentNode) || isDisabled(el.querySelector('.form-control')) }, - initCallback: null + initCallback: null, + hideCallback: null }, - ...config || {} + ...(config ?? {}) } const createPopover = () => { if (!popover.isDisabled()) { @@ -69,6 +70,12 @@ const Popover = { } } + popover.triggerHideCallback = () => { + if (popover.hideCallback) { + popover.hideCallback(); + }; + } + if (popover.isPopover) { popover.hasDisplayNone = false; @@ -112,6 +119,8 @@ const Popover = { popover.popover.tip.classList.remove('show'); el.classList.remove('show'); el.append(popover.toggleMenu); + + popover.triggerHideCallback(); } const active = e => { @@ -176,6 +185,7 @@ const Popover = { } EventHandler.on(el, 'show.bs.dropdown', show) + EventHandler.on(el, 'hide.bs.dropdown', popover.triggerHideCallback) popover.popover = bootstrap.Dropdown.getOrCreateInstance(popover.toggleElement); } @@ -200,6 +210,7 @@ const Popover = { } else { EventHandler.off(popover.el, 'show.bs.dropdown') + EventHandler.off(popover.el, 'hide.bs.dropdown') } } } diff --git a/test/UnitTest/Components/DateTimePickerTest.cs b/test/UnitTest/Components/DateTimePickerTest.cs index 1612c17c0c9..0ddc9069033 100644 --- a/test/UnitTest/Components/DateTimePickerTest.cs +++ b/test/UnitTest/Components/DateTimePickerTest.cs @@ -482,6 +482,19 @@ class MockCalendarHolidayService : ICalendarHolidays public bool IsWorkday(DateTime dt) => dt == new DateTime(2024, 4, 7); } + [Fact] + public async Task TriggerHideCallback_Ok() + { + var cut = Context.RenderComponent>(pb => + { + pb.Add(a => a.DayTemplate, dt => builder => + { + builder.AddContent(0, "day-template"); + }); + }); + await cut.InvokeAsync(() => cut.Instance.TriggerHideCallback()); + } + [Fact] public void DayTemplate_Ok() { diff --git a/test/UnitTest/Components/DateTimeRangeTest.cs b/test/UnitTest/Components/DateTimeRangeTest.cs index 88a93dcd680..e02bfa8988c 100644 --- a/test/UnitTest/Components/DateTimeRangeTest.cs +++ b/test/UnitTest/Components/DateTimeRangeTest.cs @@ -666,4 +666,14 @@ public async Task ViewMode_Month() await cut.InvokeAsync(() => cells[0].Click()); await cut.InvokeAsync(() => cells[1].Click()); } + + [Fact] + public async Task TriggerHideCallback_Ok() + { + var cut = Context.RenderComponent(pb => + { + pb.Add(a => a.Value, new DateTimeRangeValue()); + }); + await cut.InvokeAsync(() => cut.Instance.TriggerHideCallback()); + } }