From 19d777401031c9597ae47693e21942772c749480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Sun, 22 Sep 2024 12:13:04 +0200 Subject: [PATCH] #321 - Close modal when navigation occurs. --- .../Components/Modal.razor.cs | 29 ++++++++++++- .../Components/ModalInterop.cs | 6 +++ .../wwwroot/js/site.js | 41 +++++++++++-------- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/Recollections.Blazor.Components/Components/Modal.razor.cs b/src/Recollections.Blazor.Components/Components/Modal.razor.cs index 8d106b1..a85f3d3 100644 --- a/src/Recollections.Blazor.Components/Components/Modal.razor.cs +++ b/src/Recollections.Blazor.Components/Components/Modal.razor.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Routing; using Neptuo.Logging; using System; using System.Collections.Generic; @@ -9,11 +10,16 @@ namespace Neptuo.Recollections.Components { - public partial class Modal + public partial class Modal : IDisposable { + private IDisposable locationChangingToken; + [Inject] internal ModalInterop Interop { get; set; } + [Inject] + internal NavigationManager NavigationManager { get; set; } + [Inject] internal ILog Log { get; set; } @@ -48,6 +54,27 @@ public partial class Modal protected ElementReference Container { get; set; } + protected override void OnInitialized() + { + base.OnInitialized(); + locationChangingToken = NavigationManager.RegisterLocationChangingHandler(OnLocationChanging); + } + + public void Dispose() + { + Hide(); + locationChangingToken.Dispose(); + } + + private async ValueTask OnLocationChanging(LocationChangingContext context) + { + if (await Interop.IsOpenAsync(Container)) + { + context.PreventNavigation(); + Hide(); + } + } + protected override void OnParametersSet() { base.OnParametersSet(); diff --git a/src/Recollections.Blazor.Components/Components/ModalInterop.cs b/src/Recollections.Blazor.Components/Components/ModalInterop.cs index 4403ce9..fc83337 100644 --- a/src/Recollections.Blazor.Components/Components/ModalInterop.cs +++ b/src/Recollections.Blazor.Components/Components/ModalInterop.cs @@ -24,5 +24,11 @@ internal void Show(ElementReference element) internal void Hide(ElementReference element) => jsRuntime.InvokeVoidAsync("Bootstrap.Modal.Hide", element); + + internal void Dispose(ElementReference element) + => jsRuntime.InvokeVoidAsync("Bootstrap.Modal.Dispose", element); + + internal ValueTask IsOpenAsync(ElementReference element) + => jsRuntime.InvokeAsync("Bootstrap.Modal.IsOpen", element); } } diff --git a/src/Recollections.Blazor.UI/wwwroot/js/site.js b/src/Recollections.Blazor.UI/wwwroot/js/site.js index a8f4f28..290ce3e 100644 --- a/src/Recollections.Blazor.UI/wwwroot/js/site.js +++ b/src/Recollections.Blazor.UI/wwwroot/js/site.js @@ -1,31 +1,36 @@ window.Bootstrap = { Modal: { Show: function (container) { - var modal = bootstrap.Modal.getInstance(container); - if (modal == null) { - modal = new bootstrap.Modal(container, { - "show": true, - "focus": true - }); - - container.addEventListener('shown.bs.modal', function () { - $(container).find("input").first().trigger('focus'); + var $container = $(container); + if (!$container.data("modal-initialized")) { + var modal = new bootstrap.Modal(container, {}); + $container.data("modal", modal); + + $container.data("modal-initialized", true).on('shown.bs.modal', function () { + var $select = $container.find("[data-select]"); + if ($select.length > 0) { + $select[0].setSelectionRange(0, $select[0].value.length) + } + + const autofocus = $container.find('[data-autofocus]'); + if (autofocus.length > 0) { + autofocus.first().trigger('focus'); + } else { + $container.find("input").first().trigger('focus'); + } }); } - modal.show(); + $container.data("modal").show(); }, Hide: function (container) { - var modal = bootstrap.Modal.getInstance(container); - if (modal != null) { - modal.hide(); - } + $(container).data("modal").hide(); + }, + IsOpen: function (container) { + return $(container).hasClass("show"); }, Dispose: function (container) { - var modal = bootstrap.Modal.getInstance(container); - if (modal != null) { - modal.dispose(); - } + $(container).data("modal").dispose(); } }, Offcanvas: {