diff --git a/src/BootstrapBlazor.Server/Components/Samples/Dialogs.razor b/src/BootstrapBlazor.Server/Components/Samples/Dialogs.razor
index d2786cccd..77ad3f424 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/Dialogs.razor
+++ b/src/BootstrapBlazor.Server/Components/Samples/Dialogs.razor
@@ -124,7 +124,8 @@ private async Task OnClick()
@Localizer["ModalDialogTip5"]
- @Localizer["ModalDialogButton"]
+
+
diff --git a/src/BootstrapBlazor.Server/Components/Samples/Dialogs.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Dialogs.razor.cs
index 674056262..b6f5e7044 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/Dialogs.razor.cs
+++ b/src/BootstrapBlazor.Server/Components/Samples/Dialogs.razor.cs
@@ -163,6 +163,13 @@ public sealed partial class Dialogs
ModalDialogLogger.Log($"The return value of the popup window is: {result} The return value of the component is: {DemoValue1}");
}
+ private async Task OnConfirmModalClick()
+ {
+ var result = await DialogService.ShowModal(Localizer["ConfirmDialogModalContent"], Localizer["ConfirmDialogModalTitle"]);
+
+ ModalDialogLogger.Log($"The return value of the popup window is: {result} no component provider");
+ }
+
private async Task OnEditDialogClick()
{
var option = new EditDialogOption()
diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json
index e331fc1f7..58fdb1914 100644
--- a/src/BootstrapBlazor.Server/Locales/en-US.json
+++ b/src/BootstrapBlazor.Server/Locales/en-US.json
@@ -902,7 +902,10 @@
"ExportPdfDialogTitle": "Pop up window with export Pdf function",
"ExportPdfDialogIntro": "Set ShowExportPdfButtonInHeader
to display an export PDF button on the Header
",
"ExportPdfDialogTip": "More parameters can be set by setting ExportPdfButtonOptions
",
- "ExportPdfButton": "Export Pdf"
+ "ExportPdfButton": "Export Pdf",
+ "ConfirmDialogButton": "Popup Modal",
+ "ConfirmDialogModalTitle": "Literal Confirmation Modal",
+ "ConfirmDialogModalContent": "this is the prompt message.
this is a danger info
"
},
"BootstrapBlazor.Server.Components.Samples.Dispatches": {
"Title": "Dispatch message distribution",
diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json
index 7abd68fc1..b9cbfe11d 100644
--- a/src/BootstrapBlazor.Server/Locales/zh-CN.json
+++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json
@@ -902,7 +902,10 @@
"ExportPdfDialogTitle": "带导出 Pdf 功能的弹窗",
"ExportPdfDialogIntro": "通过设置 ShowExportPdfButtonInHeader
使 Header
上显示一个导出 pdf 按钮",
"ExportPdfDialogTip": "可通过设置 ExportPdfButtonOptions
对更多参数进行设置",
- "ExportPdfButton": "导出 Pdf 弹窗"
+ "ExportPdfButton": "导出 Pdf 弹窗",
+ "ConfirmDialogButton": "弹出模态框",
+ "ConfirmDialogModalTitle": "文字确认模态框",
+ "ConfirmDialogModalContent": "这是一个文字确认模态框
这是警告信息
"
},
"BootstrapBlazor.Server.Components.Samples.Dispatches": {
"Title": "Dispatch 消息分发",
diff --git a/src/BootstrapBlazor/Extensions/DialogServiceExtensions.cs b/src/BootstrapBlazor/Extensions/DialogServiceExtensions.cs
index fdf05f4e3..fc3f611e0 100644
--- a/src/BootstrapBlazor/Extensions/DialogServiceExtensions.cs
+++ b/src/BootstrapBlazor/Extensions/DialogServiceExtensions.cs
@@ -3,6 +3,8 @@
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
+using Microsoft.AspNetCore.Components.Rendering;
+
namespace BootstrapBlazor.Components;
///
@@ -71,21 +73,23 @@ public static class DialogServiceExtensions
public static async Task ShowModal(this DialogService service, ResultDialogOption option, Dialog? dialog = null)
where TDialog : IComponent, IResultDialog
{
- IResultDialog? resultDialog = null;
- option.GetDialog = () => resultDialog;
- option.BodyTemplate = builder =>
+ if (option.BodyTemplate == null)
{
- var index = 0;
- builder.OpenComponent(index++, typeof(TDialog));
- if (option.ComponentParameters != null)
+ IResultDialog? resultDialog = null;
+ option.GetDialog = () => resultDialog;
+ option.BodyTemplate = builder =>
{
- builder.AddMultipleAttributes(1, option.ComponentParameters);
- }
- builder.AddComponentReferenceCapture(index++, com => resultDialog = (IResultDialog)com);
- builder.CloseComponent();
- };
+ builder.OpenComponent(0, typeof(TDialog));
+ if (option.ComponentParameters != null)
+ {
+ builder.AddMultipleAttributes(10, option.ComponentParameters);
+ }
+ builder.AddComponentReferenceCapture(30, com => resultDialog = (IResultDialog)com);
+ builder.CloseComponent();
+ };
+ }
- option.FooterTemplate = BootstrapDynamicComponent.CreateComponent(new Dictionary
+ option.FooterTemplate ??= BootstrapDynamicComponent.CreateComponent(new Dictionary
{
[nameof(ResultDialogFooter.ButtonNoText)] = option.ButtonNoText,
[nameof(ResultDialogFooter.ButtonYesText)] = option.ButtonYesText,
@@ -105,6 +109,52 @@ public static class DialogServiceExtensions
return await option.ResultTask.Task;
}
+ ///
+ /// 弹出带结果的对话框
+ ///
+ /// DialogService 服务实例
+ /// 对话框标题,优先级高于
+ /// 对话框 文本参数
+ /// 对话框参数实例
+ /// 指定弹窗组件 默认为 null 使用 组件内置弹窗组件
+ public static Task ShowModal(this DialogService service, string title, string content, ResultDialogOption? option = null, Dialog? dialog = null)
+ {
+ option ??= new();
+ if (!string.IsNullOrEmpty(title))
+ {
+ option.Title = title;
+ }
+ if (!string.IsNullOrEmpty(content))
+ {
+ IResultDialog? resultDialog = null;
+ option.GetDialog = () => resultDialog;
+ option.BodyTemplate = builder =>
+ {
+ builder.OpenComponent(0, typeof(ResultDialog));
+ builder.AddAttribute(20, nameof(ResultDialog.Content), content);
+ builder.AddComponentReferenceCapture(30, com => resultDialog = (IResultDialog)com);
+ builder.CloseComponent();
+ };
+ }
+ return ShowModal(service, option, dialog);
+ }
+
+ private class ResultDialog : ComponentBase, IResultDialog
+ {
+ [Parameter]
+ public string? Content { get; set; }
+
+ protected override void BuildRenderTree(RenderTreeBuilder builder)
+ {
+ builder.AddMarkupContent(0, Content);
+ }
+
+ public Task OnClose(DialogResult result)
+ {
+ return Task.CompletedTask;
+ }
+ }
+
///
/// 弹出带保存按钮对话窗方法
///
diff --git a/test/UnitTest/Components/DialogTest.cs b/test/UnitTest/Components/DialogTest.cs
index 70b0b4542..0de95b36a 100644
--- a/test/UnitTest/Components/DialogTest.cs
+++ b/test/UnitTest/Components/DialogTest.cs
@@ -7,6 +7,24 @@ namespace UnitTest.Components;
public class DialogTest : BootstrapBlazorTestBase
{
+ [Fact]
+ public async Task ShowModal_Ok()
+ {
+ var cut = Context.RenderComponent(pb =>
+ {
+ pb.Add(a => a.EnableErrorLogger, false);
+ pb.AddChildContent();
+ });
+ var modal = cut.FindComponent();
+ var dialog = cut.FindComponent().Instance.DialogService;
+ _ = cut.InvokeAsync(() => dialog.ShowModal("title", "test-content "));
+ cut.WaitForState(() => cut.Markup.Contains("btn-primary"));
+
+ var closeButton = cut.Find(".btn-primary");
+ await cut.InvokeAsync(() => closeButton.Click());
+ await cut.InvokeAsync(() => modal.Instance.CloseCallback());
+ }
+
[Fact]
public async Task Show_Ok()
{
@@ -304,6 +322,7 @@ public class DialogTest : BootstrapBlazorTestBase
// 点击的是 No 按钮
result = true;
+ resultOption.BodyTemplate = null;
_ = cut.InvokeAsync(() => dialog.ShowModal(resultOption));
cut.WaitForState(() => cut.Markup.Contains("btn-danger"));
@@ -314,6 +333,7 @@ public class DialogTest : BootstrapBlazorTestBase
// 点击的是 Close 按钮
result = true;
+ resultOption.BodyTemplate = null;
_ = cut.InvokeAsync(() => dialog.ShowModal(resultOption));
cut.WaitForState(() => cut.Markup.Contains("btn-secondary"));
@@ -341,6 +361,7 @@ public class DialogTest : BootstrapBlazorTestBase
await cut.InvokeAsync(() => modal.Instance.CloseCallback());
// 点击右上角关闭按钮
+ resultOption.BodyTemplate = null;
_ = cut.InvokeAsync(() => dialog.ShowModal(resultOption));
cut.WaitForState(() => cut.Markup.Contains("btn-close"));
@@ -349,12 +370,21 @@ public class DialogTest : BootstrapBlazorTestBase
await cut.InvokeAsync(() => modal.Instance.CloseCallback());
// 点击 FooterTemplate 中的 关闭 按钮
+ resultOption.BodyTemplate = null;
_ = cut.InvokeAsync(() => dialog.ShowModal(resultOption));
cut.WaitForState(() => cut.Markup.Contains("btn-secondary"));
closeButton = cut.Find(".btn-secondary");
await cut.InvokeAsync(() => closeButton.Click());
await cut.InvokeAsync(() => modal.Instance.CloseCallback());
+
+ // 测试 Markup 扩展模式弹窗
+ _ = cut.InvokeAsync(() => dialog.ShowModal("title", "test-content "));
+ cut.WaitForState(() => cut.Markup.Contains("btn-primary"));
+
+ closeButton = cut.Find(".btn-primary");
+ await cut.InvokeAsync(() => closeButton.Click());
+ await cut.InvokeAsync(() => modal.Instance.CloseCallback());
#endregion
#region 弹窗中的弹窗测试
diff --git a/test/UnitTest/Services/ClipboardServiceTest.cs b/test/UnitTest/Services/ClipboardServiceTest.cs
index d98a0bd19..6fa2abb8e 100644
--- a/test/UnitTest/Services/ClipboardServiceTest.cs
+++ b/test/UnitTest/Services/ClipboardServiceTest.cs
@@ -48,5 +48,9 @@ public class ClipboardServiceTest : BootstrapBlazorTestBase
items = await service.Get();
item = items[0];
Assert.Empty(item.Text);
+
+ Context.JSInterop.Setup?>("getAllClipboardContents").SetResult(null);
+ items = await service.Get();
+ Assert.Empty(items);
}
}