From 372d9385d7ffa7145ad1e5030b634ec00fc4da8d Mon Sep 17 00:00:00 2001 From: Robert Haken Date: Mon, 6 May 2024 13:36:19 +0200 Subject: [PATCH] #800 [HxDropdownToggleButton] allow DropdownReference changes --- .../HxDropdown_UpdateReference_Test.razor | 47 +++++++++++++--- .../Dropdowns/HxDropdownToggleButton.cs | 56 ++++++++++++++++--- 2 files changed, 86 insertions(+), 17 deletions(-) diff --git a/BlazorAppTest/Pages/HxDropdown_UpdateReference_Test.razor b/BlazorAppTest/Pages/HxDropdown_UpdateReference_Test.razor index 677e1aec..e95a2e3c 100644 --- a/BlazorAppTest/Pages/HxDropdown_UpdateReference_Test.razor +++ b/BlazorAppTest/Pages/HxDropdown_UpdateReference_Test.razor @@ -3,7 +3,7 @@

HxDropdown

- +
@@ -15,24 +15,55 @@ -Show 1 -Show 2 +Show 1 +Show 2 + +
+ + + + +
+
+
+ +
+
+
+
+
+ +Show 3 +Show 4 @code { - private HxDropdownToggleElement dropdownToggleComponent; + private HxDropdownToggleElement dropdownToggleElementComponent; + private HxDropdownToggleButton dropdownToggleButtonComponent; private bool IsBold { get; set; } = false; private string _dropdownReference = "#button1"; - private async Task HandleShow1() + private async Task HandleShowElement1() { _dropdownReference = "#button1"; - await dropdownToggleComponent.ShowAsync(); + await dropdownToggleElementComponent.ShowAsync(); } - private async Task HandleShow2() + private async Task HandleShowElement2() { _dropdownReference = "#button2"; - await dropdownToggleComponent.ShowAsync(); + await dropdownToggleElementComponent.ShowAsync(); + } + + private async Task HandleShowButton3() + { + _dropdownReference = "#button3"; + await dropdownToggleButtonComponent.ShowAsync(); + } + + private async Task HandleShowButton4() + { + _dropdownReference = "#button4"; + await dropdownToggleButtonComponent.ShowAsync(); } } \ No newline at end of file diff --git a/Havit.Blazor.Components.Web.Bootstrap/Dropdowns/HxDropdownToggleButton.cs b/Havit.Blazor.Components.Web.Bootstrap/Dropdowns/HxDropdownToggleButton.cs index 58b2d4c5..49a86cd0 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Dropdowns/HxDropdownToggleButton.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Dropdowns/HxDropdownToggleButton.cs @@ -1,4 +1,5 @@ -using Microsoft.JSInterop; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; namespace Havit.Blazor.Components.Web.Bootstrap; @@ -71,6 +72,8 @@ static HxDropdownToggleButton() private DotNetObjectReference _dotnetObjectReference; private IJSObjectReference _jsModule; + private string _currentDropdownJsOptionsReference; + private Queue> _onAfterRenderTasksQueue = new(); private bool _disposed; public HxDropdownToggleButton() @@ -129,7 +132,10 @@ protected override void OnParametersSet() /// protected override async Task OnAfterRenderAsync(bool firstRender) { - await base.OnAfterRenderAsync(firstRender); + await base.OnAfterRenderAsync(firstRender); // allows HxButton.OnAfterRenderAsync + + var dropdownJsOptionsReference = DropdownToggleExtensions.GetDropdownJsOptionsReference(this); + if (firstRender) { await EnsureJsModuleAsync(); @@ -137,26 +143,58 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { return; } - await _jsModule.InvokeVoidAsync("create", buttonElementReference, _dotnetObjectReference, DropdownToggleExtensions.GetDropdownJsOptionsReference(this)); + _currentDropdownJsOptionsReference = dropdownJsOptionsReference; + await _jsModule.InvokeVoidAsync("create", buttonElementReference, _dotnetObjectReference, _currentDropdownJsOptionsReference); + } + else + { + if (dropdownJsOptionsReference != _currentDropdownJsOptionsReference) + { + _currentDropdownJsOptionsReference = dropdownJsOptionsReference; + if (_jsModule is not null) + { + await _jsModule.InvokeVoidAsync("update", buttonElementReference, dropdownJsOptionsReference); + } + } + } + + // for show/hide/... the dropdown has to be created/updated first + while (_onAfterRenderTasksQueue.TryDequeue(out var task)) + { + await task(); } } /// /// Shows the dropdown. /// - public async Task ShowAsync() + public Task ShowAsync() { - await EnsureJsModuleAsync(); - await _jsModule.InvokeVoidAsync("show", buttonElementReference); + _onAfterRenderTasksQueue.Enqueue(async () => + { + await EnsureJsModuleAsync(); + await _jsModule.InvokeVoidAsync("show", buttonElementReference); + }); + + StateHasChanged(); // ensure re-rendering + + return Task.CompletedTask; } /// /// Hides the dropdown. /// - public async Task HideAsync() + public Task HideAsync() { - await EnsureJsModuleAsync(); - await _jsModule.InvokeVoidAsync("hide", buttonElementReference); + _onAfterRenderTasksQueue.Enqueue(async () => + { + await EnsureJsModuleAsync(); + await _jsModule.InvokeVoidAsync("hide", buttonElementReference); + }); + + StateHasChanged(); // ensure re-rendering + + return Task.CompletedTask; } ///